Representation catalogue accepts only one prior format spec; PRE_FLEET_OWNER stores are refused
Summary
Opening a directory principal-store activates the direct representation catalogue with a compatibility list of exactly one prior format specification, while the format-amendment path beside it recognises thirteen. Any store whose active direct profile was frozen under a prior spec other than PRE_DENSE_RADIX is refused, and the daemon cannot boot:
Error: Failed to boot Kernel: Failed to open principal store: connection error: activate direct representation catalogue: invalid representation state: active direct profile names a different frozen specificationMy store was frozen under PRE_FLEET_OWNER_FORMAT_SPEC_ID — a spec the same crate already knows about and explicitly special-cases elsewhere.
Mechanism
open_runtime_principal_store_with_options (crates/astrid-storage/src/principal_state.rs:745) passes a single-element slice:
engine
.ensure_direct_representation_catalogue_compatible_with(
format_spec_id,
&[PRE_DENSE_RADIX_FORMAT_SPEC_ID],
&bootstrap_objects,
)repair_direct_coverage (crates/astrid-storage/src/engine/durable/representation_engine.rs:141) rejects anything not named there:
if active_specification != frozen_specification
&& !compatible_frozen_specifications.contains(&active_specification)
{
return Err(DurableError::InvalidRepresentationState(
"active direct profile names a different frozen specification",
));
}But crates/astrid-storage/src/principal_state/format_amendment.rs:80 enumerates thirteen prior specs, with PRE_FLEET_OWNER_FORMAT_SPEC_ID sitting immediately after PRE_DENSE_RADIX_FORMAT_SPEC_ID in the list:
const PRIOR_V1_FORMAT_SPEC_IDS: [ObjectId; 13] = [
...
PRE_DENSE_RADIX_FORMAT_SPEC_ID, // line 91
PRE_FLEET_OWNER_FORMAT_SPEC_ID, // line 92
PRE_WORKSPACE_BRANCH_FORMAT_SPEC_ID,
];The same file already special-cases PRE_FLEET_OWNER_FORMAT_SPEC_ID at format_amendment.rs:324, so the store's format is understood — only the representation-catalogue call site was not updated when PRE_FLEET_OWNER and PRE_WORKSPACE_BRANCH were added. The compatibility list looks like it was written once for the dense-radix amendment and never revisited.
Identity confirmation
PRE_FLEET_OWNER_FORMAT_SPEC_ID (format_amendment.rs:64) is:
157, 112, 29, 200, 115, 96, 230, 52, 178, 91, 123, 127, 93, 94, 121, 49,
95, 159, 39, 188, 244, 213, 14, 9, 194, 24, 30, 67, 155, 12, 125, 117which is hex 9d701dc87360e634b25b7b7f5d5e79315f9f27bcf4d50e09c2181e439b0c7d75, an exact match for format-spec-object in my var/principal-store/store.meta:
format=astrid-principal-store-v1
identity=blake3-object-identity-v1
identity-wire=tagged-identity-v1
format-spec-object=1:1:32:9d701dc87360e634b25b7b7f5d5e79315f9f27bcf4d50e09c2181e439b0c7d75
content-catalog-spec-object=1:1:32:8f3999b066b666396259c4a92f9de7c5b8e67df9d38a69fb4fb824968b56ecdb
representations=authoritative-direct-v1
principal-codec=principal-uid-v1
projection=kv-transition-bplus-v4So the store is exactly one generation newer than the only value the call site accepts.
Reproduction Steps
- Create a
~/.astridwith a release whose store format spec isPRE_FLEET_OWNER(mine: store created 2026-08-27,store.metaformat-spec-object9d701dc8…). - Upgrade to 2026.9.2 via
astrid update. - Run
astrid start. - Boot aborts in
open_runtime_principal_store_with_optionsbefore any migration runs.
Workaround that confirms the diagnosis: move var/principal-store/representations/ out of the store. ensure_direct_representation_catalogue_compatible_with takes the inner.representations.is_none() branch (representation_engine.rs:137) and rebuilds the catalogue from objects.arena + objects.index under the current spec. Boot then proceeds past this point. That the catalogue is cheaply rebuildable derived data is a good argument for not hard-failing here at all.
Expected Behavior
- Pass the full set of prior specifications whose direct-canonical recipe is still valid —
PRIOR_V1_FORMAT_SPEC_IDS, or an explicit subset fromPRE_PHYSICAL_CATALOGUEonward — rather than a hardcoded single element. - Add a test that fails when a new
PRE_*spec is added toPRIOR_V1_FORMAT_SPEC_IDSwithout being reflected at this call site, so the two lists cannot drift again. - Consider rebuilding the derived catalogue when the active profile is a recognised prior spec, since the no-catalogue path already does exactly that.
Environment
- OS: macOS 15.6 (Darwin 24.6.0), arm64
- Astrid: 2026.9.2, installed via
astrid update - Source: astrid-runtime/astrid @
73661c9b(Cargo version 0.10.4) - Principal store created 2026-08-27;
migration.completerecordssurrealkv-to-principal-store,flat-content-catalog-to-radix-tree,principal-kv-avl-to-transition-checkpoints - Store format spec on disk:
PRE_FLEET_OWNER(9d701dc8…)
Logs / Backtrace
i Starting Astrid daemon (persistent mode)...
2026-09-15T06:27:55.164699Z INFO astrid_config::loader: loaded user config path=/Users/jamie/.astrid/config.toml
✗ error: Daemon exited prematurely (exit status: 1). Check logs: /Users/jamie/.astrid/log
# ~/.astrid/log/daemon-boot.log
Error: Failed to boot Kernel: Failed to open principal store: connection error: activate direct representation catalogue: invalid representation state: active direct profile names a different frozen specificationSource: astrid-runtime/astrid