Context
The retirement half split from #14731 at implementation (consumer-census-driven): the migration module now expresses every live agent resident through the identity schema (seed eras carry the flat facts verbatim; THE PROPERTY proven on production data), but the flat era-owned fields cannot leave ai/graph/identityRoots.mjs until every consumer's read path moves.
The consumer census (V-B-A'd 2026-07-04)
modelFamily/family are load-bearing in: ai/services/memory-core/MailboxService.mjs (A2A AGENT:<family>/<model> alias resolution — ambiguity rejection reads properties.modelFamily), ai/services/memory-core/WakeSubscriptionService.mjs (family-filtered wake routing), ai/services/graph/agentFamilyResolution.mjs (the resolver itself). Zero consumers read contextWindowInput/capability facts outside the schema family. 8+ modules import identityRoots for identity-level operational fields (trust tiers, wake routes, mailbox addresses) — those stay identity-level by design and are NOT part of this retirement.
The Fix
- Each family/model read-path consumes
buildHydrationIndex(...).index.currentEra.family (with isIndexCurrent gating any cached read) instead of the flat property — one consumer per commit, regression per consumer (alias resolution and wake routing must behave identically before/after).
Then delete the era-owned flat fields (modelFamily duplicates, ...) STALE — CORRECTED 2026-07-17 (V-B-A, @neo-opus-vega). DO NOT DELETE modelFamily. This line is dangerous: two live specs pin modelFamily as identity-level, NOT era-owned. identityRootsMigration.spec.mjs:82 asserts the retired set is exactly ['family', 'tier', 'contextWindowInput', 'parallelToolCalls', 'thoughtBudget', 'hosting', 'sunsetTriggers'] — modelFamily is deliberately absent (:81: "modelFamily stays — identity-level"), and identityRoots.mjs:7-8 names only the family duplicate as retired. Deleting modelFamily would null @neo-gpt-emmy's family (the sole flat-fallback resident) and break AGENT:gpt/* A2A alias resolution + family-keyed wake routing. The era-owned deletions this line asks for already shipped — the identity keeps only the anchor, social layer, and identity-level lifecycle/operational fields.
- The graph-seeding path writes IdentityState + EmbodiedEpisode nodes from the migration module's output.
Status (V-B-A 2026-07-17, @neo-opus-vega — live, not inferred)
3 of 4 ACs are already MET; only AC4 remains, and it is blocked. Verified by running the specs (identityRootsMigration + identityHydration + agentFamilyResolution: 16 passed) and by a controlled coverage probe over the live registry:
era-chain covered: 7/11 residents
NOT covered: @system · @tobiu · AGENT:* -> non-agents; migrateResident refuses them BY DESIGN
@neo-gpt-emmy (flat='gpt') -> the ONLY real flat-fallback resident
control: a non-resident resolves to null -> PASS (the probe can see a miss, so 7/11 is real)
- AC1 — MET.
identityRootsMigration.spec.mjs:82 mechanically asserts all seven era-owned fields are gone.
- AC2 — MET. Consumers are already era-chain-first (
agentFamilyResolution.mjs:61-73, harnessRouting.mjs:88, WakeSubscriptionService.mjs:620); agentFamilyResolution.spec.mjs:16 IS the regression AC.
- AC3 — N/A by design. No consumer caches the index, so no gate applies (
agentFamilyResolution.mjs:50-52).
- AC4 — NOT met, BLOCKED. Needs the graph-seeding slice to give post-epoch residents an observation-owned era, plus the bearer-audited backfill (
ERA_BACKFILL_CANDIDATES still lists @neo-opus-vega).
The mechanical witness already exists and I rediscovered it the long way: agentFamilyResolution.spec.mjs:42 pins the fallback population exactly — expect(postEpoch.map(i => i.id)).toEqual(['@neo-gpt-emmy']). Per agentFamilyResolution.mjs:56: "when it reaches zero, the era-owned flat fields can leave." Population is 1. That single resident is this ticket's entire remaining blocker.
Acceptance Criteria
Blocked-by
PR chain #14729 → #14730 → the #14731 migration PR (this consumes all three).
Related
Parent #14677 · #14731 (the migration module + the census) · the backfill candidates exported by identityRootsMigration.mjs.
Claimable — high care (A2A routing is production-critical); the per-consumer-per-commit discipline is the safety rail.
Origin Session ID: b9b95ac6-42f5-47a3-b58f-6071f79657e8
Retrieval Hint: "identityRoots retirement flat facts consumer migration hydration index alias resolution wake routing"
Context
The retirement half split from #14731 at implementation (consumer-census-driven): the migration module now expresses every live agent resident through the identity schema (seed eras carry the flat facts verbatim; THE PROPERTY proven on production data), but the flat era-owned fields cannot leave
ai/graph/identityRoots.mjsuntil every consumer's read path moves.The consumer census (V-B-A'd 2026-07-04)
modelFamily/familyare load-bearing in:ai/services/memory-core/MailboxService.mjs(A2AAGENT:<family>/<model>alias resolution — ambiguity rejection readsproperties.modelFamily),ai/services/memory-core/WakeSubscriptionService.mjs(family-filtered wake routing),ai/services/graph/agentFamilyResolution.mjs(the resolver itself). Zero consumers readcontextWindowInput/capability facts outside the schema family. 8+ modules importidentityRootsfor identity-level operational fields (trust tiers, wake routes, mailbox addresses) — those stay identity-level by design and are NOT part of this retirement.The Fix
buildHydrationIndex(...).index.currentEra.family(withisIndexCurrentgating any cached read) instead of the flat property — one consumer per commit, regression per consumer (alias resolution and wake routing must behave identically before/after).Then delete the era-owned flat fields (STALE — CORRECTED 2026-07-17 (V-B-A, @neo-opus-vega). DO NOT DELETEmodelFamilyduplicates, ...)modelFamily. This line is dangerous: two live specs pinmodelFamilyas identity-level, NOT era-owned.identityRootsMigration.spec.mjs:82asserts the retired set is exactly['family', 'tier', 'contextWindowInput', 'parallelToolCalls', 'thoughtBudget', 'hosting', 'sunsetTriggers']—modelFamilyis deliberately absent (:81: "modelFamily stays — identity-level"), andidentityRoots.mjs:7-8names only thefamilyduplicate as retired. DeletingmodelFamilywould null@neo-gpt-emmy's family (the sole flat-fallback resident) and breakAGENT:gpt/*A2A alias resolution + family-keyed wake routing. The era-owned deletions this line asks for already shipped — the identity keeps only the anchor, social layer, and identity-level lifecycle/operational fields.Status (V-B-A 2026-07-17, @neo-opus-vega — live, not inferred)
3 of 4 ACs are already MET; only AC4 remains, and it is blocked. Verified by running the specs (
identityRootsMigration+identityHydration+agentFamilyResolution: 16 passed) and by a controlled coverage probe over the live registry:era-chain covered: 7/11 residents NOT covered: @system · @tobiu · AGENT:* -> non-agents; migrateResident refuses them BY DESIGN @neo-gpt-emmy (flat='gpt') -> the ONLY real flat-fallback resident control: a non-resident resolves to null -> PASS (the probe can see a miss, so 7/11 is real)identityRootsMigration.spec.mjs:82mechanically asserts all seven era-owned fields are gone.agentFamilyResolution.mjs:61-73,harnessRouting.mjs:88,WakeSubscriptionService.mjs:620);agentFamilyResolution.spec.mjs:16IS the regression AC.agentFamilyResolution.mjs:50-52).ERA_BACKFILL_CANDIDATESstill lists@neo-opus-vega).The mechanical witness already exists and I rediscovered it the long way:
agentFamilyResolution.spec.mjs:42pins the fallback population exactly —expect(postEpoch.map(i => i.id)).toEqual(['@neo-gpt-emmy']). PeragentFamilyResolution.mjs:56: "when it reaches zero, the era-owned flat fields can leave." Population is 1. That single resident is this ticket's entire remaining blocker.Acceptance Criteria
identityRoots.mjsentries.isIndexCurrent.Blocked-by
PR chain #14729 → #14730 → the #14731 migration PR (this consumes all three).
Related
Parent #14677 · #14731 (the migration module + the census) · the backfill candidates exported by
identityRootsMigration.mjs.Claimable — high care (A2A routing is production-critical); the per-consumer-per-commit discipline is the safety rail.
Origin Session ID: b9b95ac6-42f5-47a3-b58f-6071f79657e8 Retrieval Hint: "identityRoots retirement flat facts consumer migration hydration index alias resolution wake routing"