Context
The peer-onboarding rail's capstone leaf (parent #13015). Its prerequisite pieces are merged: PR #14918 (#14914 — curated per-family launch templates, isolated instance homes, minimal child env, live auth status) and PR #14950 (#14916 — roster generator, including the resident's subscriptionTemplate).
The former Day-0 provisioning-script slice (#14915 / closed PRs #14919 and #14931) is satisfied by composition:
- The merged roster entry is seeded into the graph by
GraphService.initAsync on Memory Core boot.
- The first real peer boot materializes the wake route through
WakeSubscriptionService.bootstrap from the boot envelope.
- Fleet instance linkage remains in the Fleet registry and lifecycle owner, never duplicated into graph identity nodes.
The Fix
ai/scripts/fleet/onboardPeer.mjs is a dry-run-first, two-phase conductor. Every Fleet read/write goes through the one long-lived dev-loopback Fleet owner; separate CLI invocations never create private lifecycle/process maps.
Phase A — before the roster merge
- Define — create the exact curated Fleet definition, or refuse an occupied id whose GitHub login/harness family differs.
- Repo — require coordinates for a new resident; create, reuse, or reconcile
metadata.repo through the owner. Never launch in the Fleet process cwd. Reject credential-bearing/control-character clone inputs, and never render the clone URL.
- Roster ceremony — print the #14950 generator command with the concrete harness family (
gpt / claude).
Operator gate: merge the roster PR, refresh origin/dev, and restart the Memory Core server.
Phase B — after the gate
- Preflight — prove membership from
origin/dev:ai/graph/identityRoots.mjs (not the current worktree) and prove the seeded graph node through a read-only query. Missing or unreachable truth is REFUSE.
- Launch — provision and start through the long-lived Fleet owner; repeat invocations share lifecycle truth and cannot double-spawn.
- Auth handoff — when live status says
authRequired === true, print a shell-safe command using the lifecycle-resolved instance home and actual AiConfig-resolved executable. False/unknown status never guesses a command. No auth contents cross the dev-loopback DTO.
Contract Ledger
| Target Surface |
Source of Authority |
Behavior |
Failure Posture |
Evidence |
| Fleet definition/repo/lifecycle |
long-lived Fleet HTTP owner + FleetControlBridge |
all reads/writes and starts traverse the shared owner |
owner unreachable refuses with the recovery command |
real ephemeral owner + two external Node clients |
| roster gate |
merged origin/dev identityRoots.mjs |
exact resident membership only after merge/ref refresh |
git read failure or missing id refuses |
injected exact git show contract spec |
| graph gate |
Memory Core graph DB |
exact seeded AgentIdentity required |
absent/unreachable both refuse; never launch |
planner matrix |
| auth handoff |
lifecycle/AiConfig resolution |
non-secret home + resolved executable, shell-quoted |
command built only for authRequired === true |
real /bin/sh execution/injection falsifier |
Acceptance Criteria
Post-Merge Validation
Out of Scope
Cockpit Add-Peer UI (#14807) · GitHub account creation and PAT issuance (operator-owned) · naming ritual (post-boot) · engine episode opening (observation-owned).
Related
Parent: #13015 · merged rail: #14914 / PR #14918 and #14916 / PR #14950 · closed-by-composition: #14915 · UI sibling: #14807 · v13.2 cornerstone-1 (#14560 / #13448).
Origin Session ID: b956ba53-01ed-4ea6-a1e5-62969f887bc3
Retrieval Hint: query_raw_memories("turnkey peer onboarding long-lived fleet owner origin/dev graph preflight auth handoff")
Context
The peer-onboarding rail's capstone leaf (parent #13015). Its prerequisite pieces are merged: PR #14918 (#14914 — curated per-family launch templates, isolated instance homes, minimal child env, live auth status) and PR #14950 (#14916 — roster generator, including the resident's
subscriptionTemplate).The former Day-0 provisioning-script slice (#14915 / closed PRs #14919 and #14931) is satisfied by composition:
GraphService.initAsyncon Memory Core boot.WakeSubscriptionService.bootstrapfrom the boot envelope.The Fix
ai/scripts/fleet/onboardPeer.mjsis a dry-run-first, two-phase conductor. Every Fleet read/write goes through the one long-lived dev-loopback Fleet owner; separate CLI invocations never create private lifecycle/process maps.Phase A — before the roster merge
metadata.repothrough the owner. Never launch in the Fleet process cwd. Reject credential-bearing/control-character clone inputs, and never render the clone URL.gpt/claude).Operator gate: merge the roster PR, refresh
origin/dev, and restart the Memory Core server.Phase B — after the gate
origin/dev:ai/graph/identityRoots.mjs(not the current worktree) and prove the seeded graph node through a read-only query. Missing or unreachable truth isREFUSE.authRequired === true, print a shell-safe command using the lifecycle-resolved instance home and actual AiConfig-resolved executable. False/unknown status never guesses a command. No auth contents cross the dev-loopback DTO.Contract Ledger
FleetControlBridgeorigin/devidentityRoots.mjsgit showcontract specauthRequired === true/bin/shexecution/injection falsifierAcceptance Criteria
--commitlaunches through one long-lived owner and returns live auth/home/executable status without a process-local lifecycle split.Post-Merge Validation
OK, then confirm an unavailable graph refuses without spawning.Out of Scope
Cockpit Add-Peer UI (#14807) · GitHub account creation and PAT issuance (operator-owned) · naming ritual (post-boot) · engine episode opening (observation-owned).
Related
Parent: #13015 · merged rail: #14914 / PR #14918 and #14916 / PR #14950 · closed-by-composition: #14915 · UI sibling: #14807 · v13.2 cornerstone-1 (#14560 / #13448).
Origin Session ID: b956ba53-01ed-4ea6-a1e5-62969f887bc3
Retrieval Hint:
query_raw_memories("turnkey peer onboarding long-lived fleet owner origin/dev graph preflight auth handoff")