Slice 2: boot build-parity assertion + smoke-gated hub swaps - #298
Draft
aarontrowbridge wants to merge 3 commits into
Draft
Slice 2: boot build-parity assertion + smoke-gated hub swaps#298aarontrowbridge wants to merge 3 commits into
aarontrowbridge wants to merge 3 commits into
Conversation
…ail-open (amicode#295 AC1 unit + AC2) D3 (spec-20260905-045114): every client and the hub assert their build (channel + version + sha) against the release channel's dist-tags at boot and record exactly one of parity-ok | parity-drift | channel-unreachable in the log. An unreachable / erroring / hung / malformed channel fails OPEN but is recorded as its own outcome — never as parity-ok. A local build has no release channel and records channel-unreachable without probing. The boot sha is baked at build time (OPENCODE_SHA define).
…icode#295 AC1) serve (hub), run (client), and attach (client) each assert the build at boot via Parity.assertBoot — bounded (5s hub, 2s clients), fail-open, one record per boot in opencode.log. Subprocess tests spawn the real CLI and assert the log file carries exactly one record; a local channel reads channel-unreachable, never parity-ok.
…ename-only proceed (amicode#295 AC3+AC4) The DB-snapshot boot smoke is the only road to a hub swap: a passing ops/hub-upgrade-smoke.sh run records <staged>.smoke.json (outcome=pass + sha256 of the smoked binary), and the gate refuses any swap without a passing, sha-matching record — the refusal NAMES the missing gate (hub-upgrade-smoke). On pass, swap is rename-only (mv) with a sha sidecar refresh; no process stop, so a running hub is never left down. Tested against the real script with real files and a real long-running process holding the live binary open across the rename. The swap/restart driver itself lives in the ops surface (outside this repo); adopting the gate there is a one-line call in hub-restart.sh's swap mode.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks 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 |
Member
Author
|
HELD — do not merge. Same fork-retirement disposition as #296: parity assertion + smoke gate are harness-side boot behavior; re-homes as a Harness Contract field + upstream reference PR. Reference implementation preserved here. |
4 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 #295 (D3 of spec-20260905-045114 — session & device lifecycle). Sibling of #296 (slice 1); no file collisions.
What landed
Boot build-parity assertion (base, hub + clients)
packages/opencode/src/installation/parity.ts—Parity.assertcompares the running build (channel + version + sha) against the release channel's npm dist-tags and records exactly one ofparity-ok | parity-drift | channel-unreachableinopencode.log. Fail-open: unreachable channel, error status, malformed JSON, hung channel (bounded at 5s), and local builds (no release channel) all recordchannel-unreachable— neverparity-ok. The assertion never fails boot.serve, asserted before listen so even a crashed boot carries its record), client (run), client (attach).OPENCODE_SHAdefine fromgit rev-parse HEADinscript/build.ts;unknownoutside release builds). Comparison is tag-based — dist-tags carry versions.Smoke gate (base ops tooling, in-tree)
packages/opencode/script/hub-smoke-gate.sh— a passingops/hub-upgrade-smoke.shrun (which lives in the ops surface, outside this repo) records<staged>.smoke.json(outcome=pass+ sha256 of the smoked binary); the gate is the reader every swap goes through.check/swapmodes; any missing, non-pass, or sha-mismatched record is refused and the refusal names the missing gate (hub-upgrade-smoke). On pass, swap is rename-only (mv+ sha sidecar refresh) — no process stop, so a running hub is never left down.Green (with the tests that pin them)
serveandrun) and assert the log file under the isolated XDG dir carries exactly one record. ✅channel-unreachable, neverparity-ok: unit tests for connection failure, HTTP error status, malformed body, missing dist-tag, hung channel (bounded), and local builds (no probe at all). ✅All green locally: 22 installation tests, 7 smoke-gate tests, 2 subprocess boot tests,
servesuite,runsuite (200 pass),tsgo --noEmitclean inopencode+core, oxlint adds zero findings.Not green / out of repo (deliberate)
ops/hub-restart.sh) and the smoke harness (ops/hub-upgrade-smoke.sh) live OUTSIDE this repo. In-tree this slice ships the gate + the record contract; adopting it is a one-line call inhub-restart.sh'sswapmode and a record-write in the harness's PASS path. AC3/AC4 are enforced and tested in-tree at the gate; the live ops scripts are not edited from here.Verification matrix note
H2-family per the spec: the release channel is exercised up / drifted / down via service-injected HTTP (no
globalThismocks) and via real subprocess boots; the gate is exercised against the real script with real files and processes.