diff --git a/.github/workflows/golden.yml b/.github/workflows/golden.yml index 3c008cd6..d653b907 100644 --- a/.github/workflows/golden.yml +++ b/.github/workflows/golden.yml @@ -1065,15 +1065,17 @@ jobs: # ---- D9-6 two-host rig ladder (M4-PLAN §D9b) ---- # Two-host evidence is default-on for every golden branch. Manual dispatch # preserves that default but exposes an explicit opt-out for isolation runs. - # The two rig hosts ARE the self-hosted runners. `needs: test` is only a - # rendezvous barrier that releases both roles together; `!cancelled()` makes - # two-host evidence independent of the suite result. Without the barrier, one - # role could queue behind its local test leg and starve the pairing window. + # The two rig hosts ARE single-slot self-hosted runners. Both roles must wait + # for BOTH test and n1-gate matrices; otherwise n1-gate can occupy one runner + # while its partner spends the 900s rendezvous budget alone (IR-142). + # This is a scheduling barrier, not a success gate: `!cancelled()` preserves + # two-host evidence after unrelated suite or n1-gate failures. # The harness remains env-gated (SPT_TWO_HOST=1), so the normal full-suite # jobs still skip these tests; only these coordinated jobs activate them. twohost-b: if: ${{ !cancelled() && (github.event_name != 'workflow_dispatch' || inputs.twohost) }} - needs: test + # [impl->REQ-GOLDEN-CI-LANE] + needs: [test, n1-gate] runs-on: [self-hosted, Linux, kitsubito] timeout-minutes: 40 steps: @@ -1251,7 +1253,8 @@ jobs: retention-days: 30 twohost-a: if: ${{ !cancelled() && (github.event_name != 'workflow_dispatch' || inputs.twohost) }} - needs: test + # [impl->REQ-GOLDEN-CI-LANE] + needs: [test, n1-gate] runs-on: [self-hosted, Windows, hfenduleam] timeout-minutes: 40 steps: diff --git a/docs/GOLDEN-CI.md b/docs/GOLDEN-CI.md index 3fef09fd..3ca01f56 100644 --- a/docs/GOLDEN-CI.md +++ b/docs/GOLDEN-CI.md @@ -6,7 +6,7 @@ Builder pull requests run `.github/workflows/ci.yml`: lint, unit tests, and requ ## Dispatch and concurrency -Pushing the assembled `golden/**` branch starts the full suite, including both coordinated two-host jobs. `workflow_dispatch` is the explicit rerun/manual avenue and must target the same candidate ref; its `twohost` input defaults on and is an explicit opt-out only when isolating other golden evidence. The two-host jobs wait for the suite as a rendezvous barrier but run after any non-cancelled suite result, so an unrelated red cannot turn seam evidence into a dependency skip. Verify two-host evidence from the job list and conclusions—an absent or skipped job is silence, not a pass. Golden runs never cancel in progress. Thin runs may cancel superseded work on the same non-main ref; main evidence is exempt from cancellation. +Pushing the assembled `golden/**` branch starts the full suite, including both coordinated two-host jobs. `workflow_dispatch` is the explicit rerun/manual avenue and must target the same candidate ref; its `twohost` input defaults on and is an explicit opt-out only when isolating other golden evidence. Both two-host jobs use `needs: [test, n1-gate]` as a rendezvous barrier: both matrices must finish before either role becomes eligible on the single-slot runners. They run after any non-cancelled upstream result, so an unrelated red cannot turn seam evidence into a dependency skip. Verify two-host evidence from the job list and conclusions—an absent or skipped job is silence, not a pass. Golden runs never cancel in progress. Thin runs may cancel superseded work on the same non-main ref; main evidence is exempt from cancellation. ## Red protocol diff --git a/docs/INFRA-REGISTER.md b/docs/INFRA-REGISTER.md index 1b342ddf..90405118 100644 --- a/docs/INFRA-REGISTER.md +++ b/docs/INFRA-REGISTER.md @@ -7016,3 +7016,13 @@ the wrapper's harness children orphaned + running") — so IR-80 ships callers, - **Mechanism and rule.** `Start-Process` with redirected output from a PowerShell tool call was observed to end with **`STATUS_CONTROL_C_EXIT`** when the tool call ended: a returned child PID did not establish detachment. The reported detached form uses a **hidden window without redirects**. Where a child must outlive the call, qualify its survival after the caller returns and give it a durable output path of its own; do not treat process creation or a hidden window alone as lifetime evidence. - **Origin clarified (YPLFG3CG).** Claude Code PowerShell tool host, 2026-09-15T07:17Z, #304 S3 Windows attempt-2 launch A: redirected `Start-Process pwsh` PID47560; `rustc` exited `0xc000013a` seconds after the tool returned, driver receipt contained only its start line and no refusal file. The same driver relaunched with `-WindowStyle Hidden -PassThru` and no redirects (PID37536) ran25minutes to exit0. There is no tracked failing launcher to repair; the existing tracked g6 launcher already uses the reported good shape. - **Discipline and receipt.** [Windows ad-hoc rig launch discipline](GOLDEN-CI.md#windows-ad-hoc-rigs-that-outlive-the-tool-call) states the shape, child-owned durable output and post-return PID/birth/output qualification. Preserved harmless-child receipt: `.spt/preserved/hertz-ir137-caller-return/receipt.json`, SHA256 **`e1c9b207544e6313eac5421ebb692786ec18b3a165756b451bff3a704899b178`**. Both valid arms survived under **OMP**, wrote post-return events and exited0; an initial observer-handshake timeout is excluded. All3probe children ended and native handles closed. This does not reproduce the **Claude Code** failure; the host boundary stays explicit. Reopen only for a newly owned callsite or contrary evidence, not to build an unused helper. + +### IR-142 — golden can queue n1-gate ahead of one twohost role and exhaust its partner's rendezvous budget + + +- **Status:** BUILT-pending-golden — symmetric workflow barrier implemented on `ci/307-twohost-rendezvous-barrier`; successor golden acceptance remains unmeasured. Thin CI cannot pair the hosts. +- **Origin:** doyle, 2026-09-18, releases#307 golden #2 `35313912102`; RCA `.spt/preserved/307/golden-35313912102/RCA-twohost-b.md` and adjacent `twohost-b-105517287374.log`. CI-shape defect, separate from the product resume/reconcile race in the same run. +- **Measured negative control:** twohost-b started **2026-09-18T07:22:22Z**, twohost-a **2026-09-18T07:33:01Z**: **639s skew**. B waited its full **900s** for `pairing: A rostered via the daemon-hosted responder` and failed after **900.48s**. Windows n1-gate occupied hfenduleam from 07:22:22Z to 07:32:59Z; A's build/bring-up then outlasted B's remaining window. Golden #1 paired only because the runner dequeued n1-gate before test. +- **Mechanism and remedy:** both roles previously depended only on `test`, while `n1-gate` depended on `changes`. Runner queue order could interleave n1-gate before just one role. Both roles now require `[test, n1-gate]`, so neither becomes eligible until both matrices finish. Retain `!cancelled()` and the manual opt-out; upstream failures must not silently skip independent seam evidence. Leave the **900s** budget unchanged. Adding the edge only to A would still release B early; replacing A's test dependency with n1-gate would allow the mirror ordering failure. +- **Acceptance, not yet claimed:** on the successor golden carrying this workflow and the product repair, record both roles' exact `startedAt` timestamps and conclusions in the PR body/gate receipt; starts must be within seconds of one another and **both jobs green**. Local YAML/graph checks prove the structural delta only. This barrier removes within-run test/n1 queue skew; it does not promise scheduler simultaneity or eliminate external runner contention. +- **Ripe when:** now, the diagnosed golden red; rides the same successor head as the product fix, assembled once by deployah. **Size:** two dependency edges, explanatory comments and operating/register documentation. [raw output: artifact://979]