Fleet Studio #1524: base peer-observation routes mount without hub-activation - #1535
Merged
jeonghun-jj-lee merged 1 commit intoSep 24, 2026
Conversation
…tivation An unarmed machine (no amicode.fleetHubUrl/fleetTunnelAlias) that holds a valid fleet-peer roster + reader tokens could not observe its peers: GET /amicode/fleet/sessions 404'd because opts.fleet was built ONLY inside the armed block (amicode_service_wiring.ts:211) and baseStudioActivates (#1478) was nested inside the premium staging gate. Fix: an explicit `observationOnly` fleet signal. createAmicodeService BYPASSES stageFleetDataPlane / the premium plane when set (AC5 — no premium plane stages even with a resolvable entitlement) and consults ONLY baseStudioActivates to mount the read/observation routes (/amicode/fleet/status + /sessions). The wiring builds a minimal observation-only fleet (fleetPeers + null hub) when activation is UNARMED but localMachineId is present; zero serving peers → nothing mounts → byte-identical (H3). AC1/AC2/AC3/AC5 covered at both the createAmicodeService seam and the real wiring path. AC4 (post-boot peer pickup without restart) deliberately deferred: the mount decision stays boot-time to preserve the AC2/H3 byte-identity guard; recorded as a #1524 follow-up rather than forced. Gates: fast suite 286/4828/0, additive-invariants GREEN, typecheck clean, boot-smoke PASS.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
jeonghun-jj-lee
marked this pull request as ready for review
September 24, 2026 13:31
jeonghun-jj-lee
deleted the
opencode/fleet-studio-1524-observe-without-hub-activation
branch
September 24, 2026 13:32
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1524. Base:
feature/free-tier-fleet.What & why
JJ reported his Mac Studio's session never appears in the MacBook UI. Root cause (one of two — the server half):
GET /amicode/fleet/sessions404s on a machine that holds a perfectly valid fleet-peer roster + reader tokens, because the fleet routes mount only inside the hub-activation gate.resolveFleetActivationarms only whenamicode.fleetHubUrlandamicode.fleetTunnelAliasare set; JJ's machine has neither, soopts.fleetwas never passed andregisterFleetRoutesnever ran. The base peer-observation path (baseStudioActivates, #1478 — designed for exactly this unentitled serving-peer case) was nested inside that gate, so it could never fire without hub config.Verified live (authenticated with the handshake credential):
/amicode/fleet/sessions→ 404,/amicode/fleet/status→ 404,/amicode/fleet/attachment→ 200 (unconditional),/amicode/roster→ 200 listing both machines serving∧reachable.Change
observationOnlyfleet signal (index.ts): when set,createAmicodeServicebypassesstageFleetDataPlane/the premium plane entirely (AC5 — no premium plane stages even with a resolvable entitlement) and consults onlybaseStudioActivatesto mount the read/observation routes. Undefined/false → today's exact path (byte-identical for entitled/armed machines).amicode_service_wiring.ts): when activation is unarmed butlocalMachineIdis present, build a minimal observation-only fleet (fleetPeers+ null hub +observationOnly:true). Zero serving peers → nothing mounts → byte-identical (H3).observationOnlyStagingReceipt(fleet_staging.ts): honestentitlement:"absent", staged:falsereceipt (no forgery).Scope / not in scope
#1524 follow-up:inindex.ts. Not blocking JJ's case: the roster persists, so a restart with the Studio already serving mounts the route.Gates
ACs (tests in
amicode_service_fleet_data_plane.test.ts, seam + real wiring)/sessions+/status200amicode_owner{is_local:false}