Skip to content

fix(fleet): complete the enroll port/auth layout + pin real version + sign the build (#1354) - #1357

Merged
jeonghun-jj-lee merged 1 commit into
feature/free-tier-fleetfrom
fix/1354-followup-ports-pin-codesign
Sep 21, 2026
Merged

jeonghun-jj-lee merged 1 commit into
feature/free-tier-fleetfrom
fix/1354-followup-ports-pin-codesign

Conversation

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor

Follow-up to #1355 — the rest of the fleet-enroll story

Bringing a real Mac Studio server up (and enrolling a MacBook Pro against it end-to-end) surfaced that #1355 fixed the right class of bugs but the port picture was incomplete, plus two more enrollment blockers and a build-time footgun.

The corrected server port layout (no collisions)

Port Service
FLEET_PORT-3 hub's embedded engine (AMICODE_ENGINE_PORT)
FLEET_PORT-2 extension's opencode engine (amicode.opencodePort)
FLEET_PORT-1 extension's app shelf (configuredPort + 1)
FLEET_PORT hub service — fleet API (roster/health/enroll)

What was wrong

  • App-shelf collision. fix(fleet): fleet enroll verify-attach — port collision + auth gap + tunnel race (#1354) #1355's -1 offset put the extension's app shelf (configuredPort + 1) right back on FLEET_PORT, colliding with the hub service. Fixed with a -2 offset so the app shelf lands on FLEET_PORT-1.
  • Hub-engine collision. The hub's own embedded engine defaulted to the same port as the extension engine. Pinned to FLEET_PORT-3 via AMICODE_ENGINE_PORT.
  • Engine-proxy auth. AMICODE_SERVICE_AUTH=open only bypasses the service's auth; /global/health proxies to the engine, which 401s if it holds a password — and verify-attach reads that 401 as auth-rejected. The hub engine now runs AMICODE_ENGINE_UNARMED=1, open-auth's matched pair. The SSH tunnel is the boundary.
  • Pin version. enroll --as-server defaulted pin_version to "dev", which fails the enroll-time pin-check against the server's own 1.18.x engine before verify-attach runs. It now probes the just-provisioned local hub's /global/health and pins the real version; AMICO_CLIENT_VERSION / an injected clientVersion still override; "dev" survives only as the unreachable-at-mint fallback.
  • Codesign. build_binary.mjs (the CLI build path) never signed the compiled binary. On macOS, Gatekeeper silently kills an unsigned/modified Mach-O on spawn (exit, no output), so every build:binary produced a binary that couldn't run until hand-signed. It now ad-hoc-signs on darwin (codesign --sign - --force) and hashes the on-disk file post-sign so .sha256 matches what ships. Verified: codesign -v reports a valid signature and the binary runs standalone.

Consistency note

The TS hub-service renderer (fleet_hub_service.ts) isn't wired to production, but #1355 had already set AMICODE_SERVICE_AUTH=open there — a broken posture without the unarmed engine + non-colliding port. Kept it consistent so it isn't a latent landmine if anyone wires it in.

Verification

  • E2E: MacBook Pro enrolled against the fixed Mac Studio hub — verify_attach: {ok: true}, roster shows the laptop reachable, /global/health 200 through the tunnel.
  • Tests: +3 pin-version cases (probe / fallback / env-override), +3 hub-service env cases (engine-port / unarmed / corrected port convention); projection test updated to the -2 offset and now asserts the shell-rendered unit carries AMICODE_ENGINE_PORT + AMICODE_ENGINE_UNARMED. Full amico-run suite 1740 green; fleet extension suites green; both install.sh copies byte-identical; extension typecheck clean.

Not in this PR (filed separately)

  • Installer-path gap: defaultRunInstaller only resolves AMICO_FLEET_INSTALLER or the dev-checkout path — nothing sets the env, so released (non-dev) enrollment's installer step likely can't find install.sh.
  • Orphaned engines on VS Code reload: stale opencode serve processes survive reloads and squat on ports (possibly related to the session-restore regression).

Closes the enrollment path opened by #1354.

… sign the build (#1354)

Follow-up to #1355. Bringing a real server up surfaced that the port picture
was incomplete, plus two more enrollment blockers.

Ports — the -1 offset from #1355 put the extension's app shelf (configuredPort
+ 1) right back on FLEET_PORT, colliding with the hub service; and the hub's
own embedded engine defaulted to the same port as the extension engine. Final
server layout, no overlap:
  FLEET_PORT-3 hub-engine · FLEET_PORT-2 ext-engine · FLEET_PORT-1 app-shelf · FLEET_PORT hub-service
- install.sh: server want_port = FLEET_PORT-2; hub plist/unit set
  AMICODE_ENGINE_PORT=FLEET_PORT-3.

Auth — AMICODE_SERVICE_AUTH=open only bypasses the SERVICE's auth; /global/health
proxies to the engine, which 401s if it holds a password (verify-attach reads
that 401 as auth-rejected). The hub engine now runs AMICODE_ENGINE_UNARMED=1 —
open-auth's matched pair. The SSH tunnel is the boundary.

Pin version — enroll --as-server defaulted pin_version to "dev", which fails the
enroll-time pin-check against the server's own 1.18.x engine before verify-attach
runs. It now probes the just-provisioned local hub's /global/health and pins the
REAL version; AMICO_CLIENT_VERSION / an injected clientVersion still override;
"dev" survives only as the unreachable-at-mint fallback.

Codesign — build_binary.mjs (the CLI build path) never signed the compiled
binary; on macOS Gatekeeper silently kills an unsigned/modified Mach-O on spawn
(exit, no output), so every build:binary produced a binary that could not run
until hand-signed. It now ad-hoc-signs on darwin (codesign --sign - --force) and
hashes the on-disk file post-sign so .sha256 matches what ships.

The TS hub-service renderer (fleet_hub_service.ts) is not wired to production,
but #1355 had already set AMICODE_SERVICE_AUTH=open there — a broken posture
without the unarmed engine + non-colliding port. Kept it consistent so it is not
a latent landmine.

Tests: +3 pin-version cases (probe / fallback / env-override), +3 hub-service
env cases (engine-port / unarmed / corrected port convention), projection test
updated to the -2 offset and asserts the shell-rendered unit carries
AMICODE_ENGINE_PORT + AMICODE_ENGINE_UNARMED. Full amico-run suite (1740) green;
fleet extension suites green; both install.sh copies byte-identical.
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 566c0802-e843-48a1-8b01-bd0e70a6e39e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jeonghun-jj-lee

Copy link
Copy Markdown
Contributor Author

Follow-up findings from this session filed as separate issues (not blockers for this PR):

@jeonghun-jj-lee
jeonghun-jj-lee merged commit ce08c53 into feature/free-tier-fleet Sep 21, 2026
12 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix/1354-followup-ports-pin-codesign branch September 21, 2026 03:47
jeonghun-jj-lee added a commit that referenced this pull request Sep 23, 2026
… sign the build (#1354) (#1357)

Follow-up to #1355. Bringing a real server up surfaced that the port picture
was incomplete, plus two more enrollment blockers.

Ports — the -1 offset from #1355 put the extension's app shelf (configuredPort
+ 1) right back on FLEET_PORT, colliding with the hub service; and the hub's
own embedded engine defaulted to the same port as the extension engine. Final
server layout, no overlap:
  FLEET_PORT-3 hub-engine · FLEET_PORT-2 ext-engine · FLEET_PORT-1 app-shelf · FLEET_PORT hub-service
- install.sh: server want_port = FLEET_PORT-2; hub plist/unit set
  AMICODE_ENGINE_PORT=FLEET_PORT-3.

Auth — AMICODE_SERVICE_AUTH=open only bypasses the SERVICE's auth; /global/health
proxies to the engine, which 401s if it holds a password (verify-attach reads
that 401 as auth-rejected). The hub engine now runs AMICODE_ENGINE_UNARMED=1 —
open-auth's matched pair. The SSH tunnel is the boundary.

Pin version — enroll --as-server defaulted pin_version to "dev", which fails the
enroll-time pin-check against the server's own 1.18.x engine before verify-attach
runs. It now probes the just-provisioned local hub's /global/health and pins the
REAL version; AMICO_CLIENT_VERSION / an injected clientVersion still override;
"dev" survives only as the unreachable-at-mint fallback.

Codesign — build_binary.mjs (the CLI build path) never signed the compiled
binary; on macOS Gatekeeper silently kills an unsigned/modified Mach-O on spawn
(exit, no output), so every build:binary produced a binary that could not run
until hand-signed. It now ad-hoc-signs on darwin (codesign --sign - --force) and
hashes the on-disk file post-sign so .sha256 matches what ships.

The TS hub-service renderer (fleet_hub_service.ts) is not wired to production,
but #1355 had already set AMICODE_SERVICE_AUTH=open there — a broken posture
without the unarmed engine + non-colliding port. Kept it consistent so it is not
a latent landmine.

Tests: +3 pin-version cases (probe / fallback / env-override), +3 hub-service
env cases (engine-port / unarmed / corrected port convention), projection test
updated to the -2 offset and asserts the shell-rendered unit carries
AMICODE_ENGINE_PORT + AMICODE_ENGINE_UNARMED. Full amico-run suite (1740) green;
fleet extension suites green; both install.sh copies byte-identical.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant