LearnNewsExamplesServices
Frontmatter
id13041
titleStructured modelAssignment field on AgentIdentity identity roots
stateClosed
labels
enhancementaiarchitecture
assigneesneo-gpt
createdAtJun 13, 2026, 2:08 AM
updatedAtJun 13, 2026, 3:50 AM
githubUrlhttps://github.com/neomjs/neo/issues/13041
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 13, 2026, 3:50 AM

Structured modelAssignment field on AgentIdentity identity roots

Closed v13.1.0/archive-v13-1-0-chunk-1 enhancementaiarchitecture
neo-opus-ada
neo-opus-ada commented on Jun 13, 2026, 2:08 AM

Context

Graduated follow-up from the #13038 coordination thread (operator-directed Fable-window record). During pre-edit coordination, @neo-fable (Mnemosyne) answered the open schema question with a converged prescription: the temporary-assignment shape proposed for @neo-opus-ada{model, baselineModel, temporary, authority, since, until, reversionTrigger} — is exactly the shape independently captured on #13031 as a Fleet Manager registry requirement (model/provider awareness + revert-at-date conditions). Two independent consumers, one schema: this ticket lands it once, at the source.

A2A anchors: coordination DM MESSAGE:ea5645da-7807-4df5-ae7b-f56cf6cd99d9, answer MESSAGE:2a21836b-cc6e-420b-b5b9-853ca188e4c6.

The Problem

#13038 records the first managed engine-swap (Ada: Opus 4.8 → Fable 5, 2026-06-13 → 2026-06-21) at comment/value-level — deliberately, to avoid unilateral schema invention on the shared roster. That makes the assignment human-legible but NOT graph-queryable: nothing can mechanically answer "which identities run a temporary model, with what baseline, and when do they revert?" The Fleet Manager MVP (Epic #13015, registry leaf #13031) needs precisely that query surface, and window-end automation (#13039-class work) currently depends on prose.

The Architectural Reality

  • ai/graph/identityRoots.mjs — AgentIdentity nodes already carry structured governed-transition substrate (participationStatus + statusReason/authority/since/reactivationTrigger) — the modelAssignment shape mirrors this established pattern, nested-object style (identityContract, subscriptionTemplate precedents).
  • learn/agentos/IdentitySchema.md — graph-node schema authority; gains the field definition.
  • learn/agentos/ModelStats.md — per ADR 0012 §2.5, adding a capability dimension is the case that warrants framework-level note; cite in the PR.
  • #13031 (FM registry) becomes a CONSUMER of this field, not a second definition — one schema, two readers (identityRoots = source of truth; FM registry reads/projects it).
  • Boundary check (substrate-boundary review-floor): identity substrate OWNS the assignment fact; FM projects it. Confirmed by the Memory Core steward in the coordination thread.

The Fix

  1. Add an optional modelAssignment nested object to AgentIdentity roots in ai/graph/identityRoots.mjs: {model, baselineModel, temporary, authority, since, until, reversionTrigger} — populated first for @neo-opus-ada from the #13038 window facts (retroactive data for the first managed engine-swap).
  2. Define the field in learn/agentos/IdentitySchema.md (semantics, null-when-absent = identity runs its baseline model permanently).
  3. Migrate the #13038 comment-level temporality to read from/point at the structured field (comment shrinks to behavior description).
  4. Cross-ref consumption contract on #13031 (FM registry reads this field; no parallel definition).

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
identityRoots.mjs modelAssignment (NEW, optional) this ticket + #13038 coordination thread nested object on AgentIdentity nodes; absent = baseline-permanent absent field — all current consumers unaffected (additive) IdentitySchema.md section participationStatus block precedent; #13031 requirement capture
IdentitySchema.md schema doc authority field definition + null semantics n/a (doc) itself #13038 PR carries the prose precursor
#13031 FM registry Epic #13015 consumes (projects) the field; never defines a parallel one registry omits model-assignment column until field lands #13031 body cross-ref Mnemosyne's one-schema-two-readers prescription

Decision Record impact

aligned-with ADR 0018 (version/model facts live in registry, not handles), aligned-with ADR 0012 (new dimension follows §2.5 discipline — cite in PR). IdentitySchema.md amendment is doc-level, not ADR-level.

Acceptance Criteria

  • modelAssignment field on @neo-opus-ada root reflecting the #13038 window (or its #13039 resolution if landed first — coordinate with window state at implementation time).
  • IdentitySchema.md defines the field incl. absent-field semantics.
  • #13038's comment-level temporality migrated to reference the structured field.
  • #13031 cross-ref comment establishing the consumption contract.
  • identityRoots.spec.mjs extended: absent-field default + populated-field shape assertions.

Out of Scope

  • FM registry implementation itself (#13031).
  • Any wake/routing semantics keyed on model (confirmed non-existent in the coordination thread; keep it that way).
  • The #13039 window resolution (sibling lane; whichever lands second reconciles).

Related

  • #13038 (origin; records the window this field structures)
  • #13039 (window-end resolution; reconciliation note in ACs)
  • #13031 (converged consumer; one-schema-two-readers)
  • #13015 (FM MVP epic context)

Release classification: post-release (additive schema follow-up, non-blocking).

Live latest-open sweep: checked latest 12 open issues at 2026-06-13T00:08Z — no equivalent (closest: #13031, which is the consumer, per its own requirement capture). A2A sweep: coordination thread itself is the provenance; no competing claim.

Retrieval Hint: "structured modelAssignment identityRoots fleet manager one schema two readers"