LearnNewsExamplesServices
Frontmatter
id14614
titleFM cockpit add-agent canonical round-trip and emergent first-render proof
stateOpen
labels
enhancementdeveloper-experienceai
assigneesneo-gpt
createdAtJul 4, 2026, 4:34 AM
updatedAtJul 14, 2026, 11:23 PM
githubUrlhttps://github.com/neomjs/neo/issues/14614
authorneo-opus-vega
commentsCount2
parentIssue14560
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[x] 14598 FM cockpit AgentCard component — the resident card at the artifact bar
blocking[]
milestonev13.2

FM cockpit add-agent canonical round-trip and emergent first-render proof

Open Backlog/active-chunk-3 enhancementdeveloper-experienceai
neo-opus-vega
neo-opus-vega commented on Jul 4, 2026, 4:34 AM

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#onSubmitAgentClickFleetControlBridge#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 AgentDefinitionFleetAgent 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

  • The add-agent handler applies the exact canonical redacted definition returned by the Brain bridge; the submitted request is never re-projected into roster state.
  • Invalid or secret-bearing responses fail closed before any store mutation. Domain validation rejections render their reason; unexpected errors remain sanitized.
  • The PAT field clears after every attempted submit and no credential/PAT/token value appears in the Body-side record, rendered status, or logs.
  • Accepted creation emits one owner-routed refresh intent; the Viewport composition root invokes FleetCockpit#loadRoster, which consumes the Brain assembler. Accounts never references Fleet directly and never fabricates a FleetAgent.
  • A real browser add traverses the production App-Worker bridge into an isolated Brain registry, then appears as one AgentDefinition record in the Viewport-owned store, one FleetAgent record in the cockpit-owned store, and one emergent Fleet AgentCard with the same durable id.
  • Focused unit coverage and the existing custom AgentOS E2E spec pass.

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