LearnNewsExamplesServices
Frontmatter
id17276
titleOne command boots the cockpit against the live containerized plane
stateClosed
labels
enhancementai
assigneesneo-gpt
createdAtAug 17, 2026, 9:41 AM
updatedAtAug 25, 2026, 10:11 AM
githubUrlhttps://github.com/neomjs/neo/issues/17276
authorneo-kimi-iris
commentsCount2
parentIssue17271
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 25, 2026, 10:11 AM

One command boots the cockpit against the live containerized plane

Closed Backlog/active-chunk-17 enhancementai
neo-kimi-iris
neo-kimi-iris commented on Aug 17, 2026, 9:41 AM

One command boots the cockpit against the live containerized plane

Parent: #17271 (slice 1 — the journey). The parent's AC5 (the operator-witnessed L1 beat) stays with the parent; this leaf owns the mechanics the operator's session will run: one documented command that brings the cockpit up against the LIVE containerized plane with the full read set armed.

Context

npm run cockpit (the documented one-command journey) boots the fleet transport in in-process mode unless the operator hand-exports NEO_FLEET_PLANE_BASE + NEO_FLEET_PLANE_BEARER — the hand-assembly #17271 names as the gap. Every piece of plane-mode machinery already exists in ai/services/fleet/devFleetServer.mjs (verified at intake): plane admission with plane-side viewer verification, presence via createPlaneWhoIsOnlineReader, activity/mailbox/compose/catch-up through the proven plane client, honest-degraded wake lanes. What does not exist is the JOURNEY: a single command that resolves the binding and arms it.

The Architectural Reality

  • buildScripts/devCockpit.mjs supervises the two processes (webpack + fleet transport) and owns the launch contract (process bearer, handshake arming, probe/plan/refuse discipline).
  • Plane config is leaf-owned (ai/configBase.mjs: fleet.planeBase, fleet.planeBearer, fleet.planeBearerFile, fleet.planeAdmissionBearer(File)) — consumed at the use site per ADR-0019; no new leaves, no re-derivation.
  • The canonical local plane publishes http://127.0.0.1:3102 (ADR-0019 §10.7 local profile; ai/scripts/lifecycle/local-agent-os/README.md), path-routing authenticated /mc/mcp; its auth guard answers unauthenticated calls 401 invalid_token — the plane's identity signature (verified live).
  • The viewer identity chain (StdioIdentityResolver: env-var → gh CLI) and the plane's provider-PAT authority resolve the SAME subject when the bearer comes from gh auth token — the single-viewer invariant holds by construction.

The Fix

npm run cockpit:livebuildScripts/devCockpit.mjs --live:

  1. Resolve the binding (resolveLivePlaneConfig): base = NEO_FLEET_PLANE_BASE else the canonical local plane; bearer = NEO_FLEET_PLANE_BEARER else the NEO_FLEET_PLANE_BEARER_FILE secret file (materialized into the fleet child's direct env channel — the dev entry reads only the direct leaf) else gh auth token. Fail-closed: pinned-but-unreadable file refuses (never falls through to a different credential); all-three-empty refuses with the remediation. The bearer VALUE never enters any note or log.
  2. Probe the plane (probePlaneIdentity): unauthenticated; the auth guard's 401 IS the identity signature. Unreachable refuses pre-spawn naming the plane-start compose command. Bearer VALIDITY stays with the fleet entry's verified admission — one verification authority.
  3. Never adopt an incumbent: live mode refuses an occupied :8083 — an incumbent's plane binding is not observable through /fleet/probe, so adoption could point the cockpit at the wrong plane.
  4. Custody (buildFleetChildEnv): the resolved binding rides ONLY the fleet child's env — never the webpack child, never process.env mutation.
  5. Docs: learn/agentos/RunningTheFleetCockpit.md gains the live-plane section (command, resolution order, honest-degraded lanes).

Contract Ledger

# Surface (live anchor) Delta Source of authority Fallback / degraded Docs Evidence
1 cockpit:live npm script (package.json) Additive This ticket n/a — new runbook §"The one command against the live plane" composed live run receipt
2 buildScripts/devCockpit.mjs --live branch Additive; the zero-setup journey is byte-identical without the flag devCockpit.mjs launch contract refusals are named + pre-spawn module @summary 9 new unit witnesses, suite 20/20
3 fleet.planeBase / fleet.planeBearer(File) (existing leaves) Consumed, unchanged ADR-0019 (use-site reads) empty base default → canonical local plane (named in notes) runbook resolution witnesses
4 gh auth token fallback New consumption of the viewer-claim identity's own credential the stdio identity chain (env → gh CLI) gh absent/unauthenticated → named refusal runbook gh-fallback witness + live run
5 Plane MCP ingress probe New, unauthenticated, side-effect-free the plane's own auth-guard 401 unreachable → plane-start remediation runbook probe witnesses (401/200/closed)
6 Fleet wire envelopes / handshake payload Unchanged fleetWireMethods.mjs parity lint n/a n/a parity lint untouched in CI
7 learn/agentos/RunningTheFleetCockpit.md New section this ticket n/a the file itself doc diff

Decision Record impact

aligned-with ADR 0038 (FM-as-client topology: the cockpit consumes the plane through the authenticated MCP boundary; this ticket changes no topology, only the dev journey to it). ADR-0019 read per its read-gate; no config-leaf changes.

Acceptance Criteria

  • npm run cockpit:live boots the supervised cockpit with the fleet transport bound to the containerized plane — zero hand-assembled wiring (default base + credential fallback), witnessed in a live run from an agent seat.
  • Resolution is fail-closed and named at every branch: env > secret-file > gh; pinned-dead file refuses (no fall-through); all-empty refuses with remediation; bearer value never in notes/logs.
  • The plane probe fails fast pre-spawn on an unreachable plane (remediation names the compose command); live mode refuses to adopt an incumbent fleet transport (plane binding not probe-observable).
  • Bearer custody: the resolved plane credential reaches the fleet child's env only — never the webpack child (witnessed end-to-end through the real launcher).
  • Presence bands render the live presence surface's real answers on real roster rows — cross-checked against who_is_online at capture time with the deployed plane revision recorded (the honest-surface improvements not yet deployed are named, not silently claimed).
  • The activity stream shows real A2A/PR events in live mode — cross-checked against the mailbox trail; zero seeded rows in live mode.
  • Mailbox/compose/catch-up seams bind plane-side with the viewer verified by the plane (boot witness log line); the wake push lane renders its honest not-armed reason with poll as the truth lane.
  • learn/agentos/RunningTheFleetCockpit.md documents the journey.
  • Unit witnesses cover the resolution seam, the probe, the custody rule, and the composed live boot; the full devCockpit suite stays green.

Out of Scope

The operator-witnessed L1 beat (parent #17271 AC5 — the closing evidence lives with the parent) · app-side rosterSourceMode semantics (intake evidence: the promotion/admission paths already render selected-source truth for populated registries, and the empty-registry case renders the labelled static roster with its retained cause — no masking to fix) · the devFleetServer planeBearerFile-indirection gap observed at intake (adjacent debt: the dev entry reads only the direct leaf; this journey's launcher materializes the file's value, so the journey is unblocked; the entry-level gap is recorded on the parent) · wake-push admission credentials (the deployment declares them; the journey renders the honest not-armed lane).

Avoided Traps

  • A second supervisor process (a devCockpitLive wrapper spawning devCockpit): nested supervisors for zero behavioral gain — the flag branch reuses the entire probe/plan/spawn/supervise machinery.
  • Re-verifying the bearer in the launcher (MCP initialize duplication): the fleet entry's plane-side verified admission is the one verification authority; the launcher fails fast only on reachability.
  • Live-mode incumbent reuse: extending /fleet/probe to report plane bindings was rejected as wire-surface growth for a journey that can simply refuse named.

Related

Parent: #17271 · Epic: #14560 · the honest presence surface this consumes: #17248 / #17225 · ADR 0038 · ai/scripts/lifecycle/local-agent-os/README.md (the plane-start command).

Live latest-open sweep: latest 20 open checked 2026-08-17T07:45Z, no equivalent; A2A herd-window sweep clean (active claims: #17239/#17272 Ada, #17271 mine).

Origin Session ID: 0c5a1cf3-093b-4e9d-a7ba-74137e4d4f23

Retrieval Hint: query_raw_memories("cockpit:live one command live plane journey resolveLivePlaneConfig probePlaneIdentity buildFleetChildEnv")

tobiu referenced in commit bd5c40d - "feat(cockpit): add the live-plane journey (cockpit:live) (#17276) (#17277) on Aug 17, 2026, 10:36 AM
tobiu closed this issue on Aug 17, 2026, 10:36 AM
tobiu referenced in commit 045658c - "test(fleet): serialize cockpit port owners (#17276) (#17751)" on Aug 25, 2026, 10:11 AM
tobiu closed this issue on Aug 25, 2026, 10:11 AM