Intake correction — 2026-07-14
Live ticket intake found that the original leaf bundled two independently shippable contracts and described an add-agent surface that has since partially landed through #14884 / PR #14887, #14807 / PR #14960, and #14964 / PR #14998.
The remote-tenant contract remains owned by #14574 and is explicitly out of scope here. This ticket now tracks the coherent remaining add-agent vertical slice: make the existing UI consume the Brain's canonical creation response, render domain rejection reasons honestly, and prove the new resident emerges through the shared Fleet store and AgentCard.
Problem
AgentOS.view.Accounts already renders the add-agent form and submits {githubUsername, harnessType, credential} through the production Fleet Registry bridge. The success path currently discards defineAgent()'s canonical redacted return and fabricates a second Body-side definition from the submitted request. That creates two competing truths and can render fields the Brain did not persist.
Creation also stops at the Accounts/configuration projection. The Fleet cockpit owns a deliberately separate FleetRoster store of FleetAgent records and refreshes it only through the Brain-side fleetRoster() assembler. Without an owner-routed refresh after accepted creation, the newly registered resident cannot appear as an AgentCard until a page reload.
The current E2E pre-seeds an agent Brain-side before opening Accounts; it proves configuration readback, but not the real add journey. The rejection path also collapses every domain rejection into one generic message.
Current authority
FleetControlBridge#defineAgent is the Body-reachable allowlist and returns FleetRegistryService#defineAgent's canonical public definition.
- The PAT necessarily crosses the Body → Brain request once. It must be cleared from the form after every attempt and must never be retained, logged, stored, or echoed in the Body response/store.
- The Viewport
state.Provider owns the AgentDefinitions data.Store consumed by Accounts/configuration surfaces. FleetCockpit owns a separate provider-scoped FleetRoster store of FleetAgent records.
- A successful definition must send an owner-routed accepted intent to the Viewport composition root. The cockpit then re-polls
FleetControlBridge#fleetRoster; Accounts must not reach into its sibling or locally map an AgentDefinition into a FleetAgent.
- ADR 0032 §2.3.7 governs the first Fleet render: a newly registered resident is emergent, with no inherited identity mold or model-as-identity shortcut.
- #14598 is closed, so AgentCard is available; #14574 remains open and independent.
Contract Ledger
| Surface |
Canonical contract |
Fail-closed fallback |
Documentation |
Evidence |
Accounts#onSubmitAgentClick → FleetControlBridge#defineAgent |
Send the curated creation request once; accept only the returned redacted public definition; mutate the Body store from that response, never from submitted values |
Missing/invalid response or unexpected failure leaves the store unchanged; allowlisted FleetRegistryService.defineAgent: domain reasons render without leaking internals |
Update method @summary and return/readback wording |
Unit behavior specs + real E2E |
Viewport-owned AgentDefinitions store |
Insert/update a real AgentDefinition record from the canonical response; select that durable id |
Missing store, id, username, harness type, or secret-bearing response rejects before mutation |
Update upsert JSDoc with response preconditions |
Real store unit spec + Neural Link inspectStore |
| PAT lifecycle |
Form field clears after every attempted bridge submit; canonical response/store contain no credential material |
Failed bridge or rejected response performs zero roster mutation and still clears the field |
Keep capability-boundary class docs accurate |
Unit secret fixture + E2E store/DOM assertions |
Accepted-definition handoff → FleetCockpit#loadRoster |
Viewport composition routes the accepted intent; Fleet re-polls the Brain fleetRoster() assembler into its own FleetRoster store |
No direct Accounts→Fleet component reference and no local AgentDefinition→FleetAgent mapping; failed creation emits no refresh |
Document the composition-root handoff and separate-store authority |
Unit routing spec + real E2E |
| First Fleet render |
The authoritative assembler row makes the same durable resident appear through one Fleet AgentCard as emergent |
No locally invented lifecycle/identity state |
ADR 0032 §2.3.7 reference in E2E docs |
DOM assertion + Neural Link checks of both stores/components |
Acceptance criteria
Out of scope
- Remote-tenant URL/PAT probe → propose → confirm (#14574)
- Fleet Registry encryption/keychain internals
- Lifecycle start/provisioning after registration
- Identity-template or embodiment-policy changes
Related
Parent #14560 · #14598 (closed AgentCard dependency) · #14574 (independent remote-tenant contract) · PRs #14887, #14960, #14998 · ADR 0032 §2.3.7 · D#14561
Ticket-intake verdict
- Original shape: needs narrowing + contract alignment
- Corrected shape: valid as written after live Neural Link exposed and this body recorded the separate-store projection boundary
- Successor risk: ADR-aligned; the original ticket preceded ADR 0032's merge by minutes, and the accepted first-render authority is now explicit
- ROI: positive — small remaining code surface, direct v13.2 operable-cold value, and a missing real boundary proof
Origin Session ID: a28f1415-37a4-4a5a-a3e4-b56adf6274ec
Retrieval Hint: FM cockpit add agent canonical Brain response provider store emergent AgentCard
Intake correction — 2026-07-14
Live ticket intake found that the original leaf bundled two independently shippable contracts and described an add-agent surface that has since partially landed through #14884 / PR #14887, #14807 / PR #14960, and #14964 / PR #14998.
The remote-tenant contract remains owned by #14574 and is explicitly out of scope here. This ticket now tracks the coherent remaining add-agent vertical slice: make the existing UI consume the Brain's canonical creation response, render domain rejection reasons honestly, and prove the new resident emerges through the shared Fleet store and AgentCard.
Problem
AgentOS.view.Accountsalready renders the add-agent form and submits{githubUsername, harnessType, credential}through the production Fleet Registry bridge. The success path currently discardsdefineAgent()'s canonical redacted return and fabricates a second Body-side definition from the submitted request. That creates two competing truths and can render fields the Brain did not persist.Creation also stops at the Accounts/configuration projection. The Fleet cockpit owns a deliberately separate
FleetRosterstore ofFleetAgentrecords and refreshes it only through the Brain-sidefleetRoster()assembler. Without an owner-routed refresh after accepted creation, the newly registered resident cannot appear as an AgentCard until a page reload.The current E2E pre-seeds an agent Brain-side before opening Accounts; it proves configuration readback, but not the real add journey. The rejection path also collapses every domain rejection into one generic message.
Current authority
FleetControlBridge#defineAgentis the Body-reachable allowlist and returnsFleetRegistryService#defineAgent's canonical public definition.state.Providerowns theAgentDefinitionsdata.Storeconsumed by Accounts/configuration surfaces.FleetCockpitowns a separate provider-scopedFleetRosterstore ofFleetAgentrecords.FleetControlBridge#fleetRoster; Accounts must not reach into its sibling or locally map anAgentDefinitioninto aFleetAgent.Contract Ledger
Accounts#onSubmitAgentClick→FleetControlBridge#defineAgentFleetRegistryService.defineAgent:domain reasons render without leaking internals@summaryand return/readback wordingAgentDefinitionsstoreAgentDefinitionrecord from the canonical response; select that durableidinspectStoreFleetCockpit#loadRosterfleetRoster()assembler into its ownFleetRosterstoreAgentDefinition→FleetAgentmapping; failed creation emits no refreshAcceptance criteria
FleetCockpit#loadRoster, which consumes the Brain assembler. Accounts never references Fleet directly and never fabricates aFleetAgent.AgentDefinitionrecord in the Viewport-owned store, oneFleetAgentrecord in the cockpit-owned store, and one emergent Fleet AgentCard with the same durable id.Out of scope
Related
Parent #14560 · #14598 (closed AgentCard dependency) · #14574 (independent remote-tenant contract) · PRs #14887, #14960, #14998 · ADR 0032 §2.3.7 · D#14561
Ticket-intake verdict
Origin Session ID:
a28f1415-37a4-4a5a-a3e4-b56adf6274ecRetrieval Hint:
FM cockpit add agent canonical Brain response provider store emergent AgentCard