From 9b9a4bd02a917a9b1e7fbcfbbd265cd9ccb79b71 Mon Sep 17 00:00:00 2001 From: jjangg96 Date: Sat, 3 Oct 2026 22:13:51 +0900 Subject: [PATCH 01/16] docs: record independent G01 offline protocol review --- docs/decisions/0002-scaleset-integration.md | 10 ++++- docs/evidence/g01-contract.md | 47 +++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/decisions/0002-scaleset-integration.md b/docs/decisions/0002-scaleset-integration.md index 02b0eb62..6d7c12a0 100644 --- a/docs/decisions/0002-scaleset-integration.md +++ b/docs/decisions/0002-scaleset-integration.md @@ -1,12 +1,18 @@ # ADR 0002: Released Scale Set listener with independent reconciliation -Status: **provisional integration selection; G01 remains unresolved** pending -independent Luna max protocol review and authorized live contract evidence. +Status: **provisional integration selection; independent offline protocol review +approved on 2026-10-03; G01 closure and production G01/G02 remain unresolved.** Issue: [G01](https://github.com/1XP-AI/gh-runnerd/issues/1). Checked: 2026-09-07. See [measured offline evidence](../evidence/g01-contract.md) and [required live experiment](../evidence/g01-live-canary.md). +The review is limited to the offline evidence and this provisional selection; it +does not satisfy the authorized live canary, sanitized live evidence or safe-drain +gate. See the [independent protocol review](../evidence/g01-contract.md#independent-protocol-review-2026-10-03), +[full review comment](https://github.com/1XP-AI/gh-runnerd/issues/1#issuecomment-5967217026) +and [focused-test supplement](https://github.com/1XP-AI/gh-runnerd/issues/1#issuecomment-5967258854). + ## Decision Pin `github.com/actions/scaleset v0.4.0` (source diff --git a/docs/evidence/g01-contract.md b/docs/evidence/g01-contract.md index 6c9c9b27..0d58c93e 100644 --- a/docs/evidence/g01-contract.md +++ b/docs/evidence/g01-contract.md @@ -6,6 +6,53 @@ review approved the offline artifact at `4e58c55`; the reviewer reproduced race tests, vet and both pinned SDK comparisons. This is not approval of a live canary or the unresolved production integration gate. +## Independent protocol review (2026-10-03) + +**Verdict:** APPROVE, scoped to the offline protocol evidence and provisional +selection of the released `github.com/actions/scaleset v0.4.0` high-level +listener with independent reconciliation. HOLD G01 closure and any production or +live approval. The reviewer found no actionable defect in the reviewed current +protocol evidence. This additive record preserves the historical 2026-09-07 +Astra authorship above. + +The independent reviewer was actual Codex GPT-6-Luna/max, verified before +dispatch, and reviewed immutable parent-main source +`9636e33781c72c32319db419334f49f1bc1866bc`. The complete +[review comment](https://github.com/1XP-AI/gh-runnerd/issues/1#issuecomment-5967217026) +contains the source anchors and scoped findings; the +[supplement](https://github.com/1XP-AI/gh-runnerd/issues/1#issuecomment-5967258854) +records the one corrected test-name gap. The review confirms the recorded +statistics → ACK → acquisition → callbacks order, ACK-to-acquisition loss +window, observational callbacks, 202/stale-statistics and session-fencing limits, +and quarantine and JIT-secret-exposure conclusions. It does not establish +exactly-once behavior or live GitHub semantics. + +The initial focused selection was run with Go 1.26.8: + +```text +GOTOOLCHAIN=go1.26.8 go test -count=1 -timeout=60s -run '^(TestSDKACKBoundaries|TestSDKAcquisitionResponseLossAfterACK|TestSDKRepeatedStatisticsAnd202ReuseLastObservation|TestSDKHTTPFailuresAndSessionRefresh|TestSDKCapacityWithdrawalDoesNotFenceInFlightAcquisition|TestSDKJITResponseLossBeforeCreationDoesNotDiscoverIdentity|TestSDKJITResponseLossWithoutCommitDoesNotDiscoverIdentity|TestSDKJITResponseLossDiscoversIdentityWithoutReissuing)$' . +PASS: github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset (0.359s) +``` + +Seven of the eight regex alternatives matched tests. The alternative +`TestSDKJITResponseLossBeforeCreationDoesNotDiscoverIdentity` matched no test; +the checked-in case is +`TestSDKJITLookupBeforeCreationDoesNotDiscoverIdentity`, which this first +command did not execute. The reviewer closed that execution-evidence gap on the +same unchanged source SHA with: + +```text +GOTOOLCHAIN=go1.26.8 go test -count=1 -timeout=45s -run '^TestSDKJITLookupBeforeCreationDoesNotDiscoverIdentity$' . +PASS: github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset (0.361s) +``` + +That fixture used `httptest` and a transport that rejects non-fixture +addresses; no JIT was created on GitHub and no runner binary was downloaded or +executed. No full suite, race run, SDK comparison matrix, live canary or +production approval is claimed by this review. The authorized canary, sanitized +live evidence, safe-drain decision, and full G01/G02 production gates remain +unresolved. + ## Exact inputs and primary sources | Input | Exact selection / finding | From aa3adf5a25dfdf8d6b9f4fc4e13c3e6eb50555cd Mon Sep 17 00:00:00 2001 From: jjangg96 Date: Sat, 3 Oct 2026 22:19:10 +0900 Subject: [PATCH 02/16] docs: correct JIT test execution attribution --- docs/evidence/g01-contract.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/evidence/g01-contract.md b/docs/evidence/g01-contract.md index 0d58c93e..ab00e1c8 100644 --- a/docs/evidence/g01-contract.md +++ b/docs/evidence/g01-contract.md @@ -38,7 +38,7 @@ Seven of the eight regex alternatives matched tests. The alternative `TestSDKJITResponseLossBeforeCreationDoesNotDiscoverIdentity` matched no test; the checked-in case is `TestSDKJITLookupBeforeCreationDoesNotDiscoverIdentity`, which this first -command did not execute. The reviewer closed that execution-evidence gap on the +command did not execute. The coordinator closed that execution-evidence gap on the same unchanged source SHA with: ```text From 8ae0c1a3dd158360784de64232a4890f3f3b2be6 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 11:02:26 +0900 Subject: [PATCH 03/16] docs: record G01 runner release checkpoint --- docs/evidence/g01-contract.md | 6 ++ docs/evidence/g01-live-canary.md | 7 ++ .../evidence/g01-runner-release-checkpoint.md | 78 +++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 docs/evidence/g01-runner-release-checkpoint.md diff --git a/docs/evidence/g01-contract.md b/docs/evidence/g01-contract.md index ab00e1c8..2deaacef 100644 --- a/docs/evidence/g01-contract.md +++ b/docs/evidence/g01-contract.md @@ -141,6 +141,12 @@ API (must verify bytes before execution): Source: [official runner release](https://github.com/actions/runner/releases/tag/v2.337.0). +Release/source freshness update (2026-10-13): the +[runner release checkpoint](g01-runner-release-checkpoint.md) records official +`v2.338.0` metadata and reviewed source changes. The existing `v2.337.0` +selection remains in force until a named tenant's availability and candidate +archive bytes are qualified; the checkpoint does not change this pin. + | Transport | Evidence and exposure | |---|---| | `Runner.Listener run --jitconfig ` / `run.sh --jitconfig ` | Command parser recognizes `jitconfig`; argv exposes the encoded credential to process inspection and command capture. Avoid for the canary. | diff --git a/docs/evidence/g01-live-canary.md b/docs/evidence/g01-live-canary.md index 9a25b7ba..93e0f201 100644 --- a/docs/evidence/g01-live-canary.md +++ b/docs/evidence/g01-live-canary.md @@ -26,6 +26,13 @@ provisioning/rotation remain unresolved, as does the provider-side conditional delete gate. This template correction closes neither gate and authorizes no live execution. +Release/source freshness (2026-10-13): see the +[runner release checkpoint](g01-runner-release-checkpoint.md). Keep this plan's +`v2.337.0` selection unless a later authorized revision identifies the version +offered to the named organization/repository. Before any candidate change, verify +the archive bytes against the published digest and record the exact runtime/image +digest; the checkpoint is source/metadata evidence only and authorizes no swap. + ## Required environment and authorization record - [ ] Maintainer identifies one disposable **private** repository and one diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md new file mode 100644 index 00000000..d17c2e2e --- /dev/null +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -0,0 +1,78 @@ +# G01 runner release-source readiness checkpoint + +Date: 2026-10-13. This is a read-only check of official GitHub release, tag, +compare, tree, and file metadata/source via `gh api`. No archive bytes were +downloaded or hashed, no runner was extracted or executed, no tenant-specific +availability was checked, and no GitHub write or live operation was performed. + +## Selection and release metadata + +The integration selection remains the released `github.com/actions/scaleset` +`v0.4.0` high-level listener with independent reconciliation. The official +latest-release endpoint still resolves to `v0.4.0`, published +`2026-05-05T15:32:02Z`; its tag points directly to +`6ce025902cd964747a078c2aabe7340ebc667eca`. Upstream `main` resolves to +`e6daac702355cdb5b880b4fbdcf6d85dcd9e48e5` (`2026-09-16T21:46:19Z`). The +historical audited comparison at +`cb0405b2d874500e75ae34eff8d582ab75956b45` remains unchanged: this checkpoint +does not replace that comparison or claim protocol tests against current +`main`. ([release](https://github.com/actions/scaleset/releases/tag/v0.4.0), +[tag commit](https://github.com/actions/scaleset/commit/6ce025902cd964747a078c2aabe7340ebc667eca), +[current main commit](https://github.com/actions/scaleset/commit/e6daac702355cdb5b880b4fbdcf6d85dcd9e48e5)) + +The existing runner canary selection remains `v2.337.0`, as recorded in the +[contract](g01-contract.md#runner-and-jit-transport) and +[canary plan](g01-live-canary.md#required-environment-and-authorization-record). +The latest official runner release is `v2.338.0`, published +`2026-10-06T13:55:11Z`, with tag commit +`197ca027b90de199464dee3bb9ff198a1db60967`. It is a reviewed-source candidate +only; it is not tenant-qualified, selected, or executed. Its release notes say +the progressive release may not yet be available to a particular enterprise, +organization, or repository. The named canary tenant is not established here, +so “latest” does not establish what that tenant can install. ([release and +official rollout note](https://github.com/actions/runner/releases/tag/v2.338.0), +[tag commit](https://github.com/actions/runner/commit/197ca027b90de199464dee3bb9ff198a1db60967)) + +| Official `v2.338.0` asset | Published size | Published SHA-256 | +|---|---:|---| +| `actions-runner-linux-arm64-2.338.0.tar.gz` | 140012091 bytes | `628b4a7258487b80c1d3c221095a7ded349f5ae0175fd3dfab708d07428f041b` | +| `actions-runner-osx-arm64-2.338.0.tar.gz` | 128562863 bytes | `df4cebda25c86a886ed204e49fee63f5c2e7cec5f447b5c98440a826bbdf9df2` | + +These are release-API checksum and size metadata, not independently verified +archive bytes. + +## Source comparison relevant to the existing contract + +The immutable source comparison from runner `v2.337.0` +(`397b032cbf865e9c3ddfab89d533ec19325e1273`) to `v2.338.0` reports +`diverged`, 39 commits ahead, 1 behind, and 43 changed files. Do not describe +the candidate as a descendant or fast-forward of the old source; the findings +below are limited to the inspected files. ([compare](https://github.com/actions/runner/compare/397b032cbf865e9c3ddfab89d533ec19325e1273...197ca027b90de199464dee3bb9ff198a1db60967)) + +| Surface | Read-only source finding | Canary preparation implication | +|---|---|---| +| JIT input and file materialization | `CommandSettings.cs` is blob `7c29e2b6d2a2b44d40e5ed6496af439c62aa543b` (18,579 bytes) at both commits; `Runner.cs` is blob `31c87130257f534a1a30f0cbcc37bc61e6406405` (64,169 bytes) at both. The inspected parsing and materialization source is unchanged. ([v2.337.0 parser](https://github.com/actions/runner/blob/397b032cbf865e9c3ddfab89d533ec19325e1273/src/Runner.Listener/CommandSettings.cs), [v2.338.0 parser](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Listener/CommandSettings.cs), [v2.337.0 materializer](https://github.com/actions/runner/blob/397b032cbf865e9c3ddfab89d533ec19325e1273/src/Runner.Listener/Runner.cs), [v2.338.0 materializer](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Listener/Runner.cs)) | The historical argv/environment and on-disk JIT conclusions retain this specific source basis only; they do not qualify the new runtime. | +| Internal Node and service wrapper | `NodeUtil.cs` now defaults internal operations to `node24`, and `runsvc.sh` selects `node24`. `Constants.cs` changes only the Node 20 removal date from September 16 to September 23; this is not a new JIT masking change. ([NodeUtil](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Common/Util/NodeUtil.cs), [runsvc.sh](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Misc/layoutbin/runsvc.sh), [Constants.cs](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Common/Constants.cs)) | If `v2.338.0` is later selected, include Node 24 compatibility and the service-wrapper runtime in the reviewed no-op canary, and record the exact runtime/image digest. | +| Runner broker session deletion | `BrokerMessageListener` passes its owned `_session.SessionId` to `BrokerServer.DeleteSessionAsync(Guid, ...)`. This is a runner broker-session change; it does not establish Scale Set SDK manager-session replacement or drain semantics. ([listener](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Listener/BrokerMessageListener.cs), [broker server](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Common/BrokerServer.cs)) | Keep runner broker-session deletion observations separate from the SDK manager-session and safe-drain evidence gates. | +| Conditional WebSocket diagnostics | `JobExtension` starts the probe only when the job variable `system.runner.brokerwebsocketprobeurl` is nonempty. `BrokerServer` traces received/replied text and exception details, and `JobExtension` adds connectivity telemetry. This is a conditional diagnostics/logging surface, not evidence of an always-on probe, leaked live secrets, safe raw-log publication, or manager credential inheritance. ([variable](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Sdk/DTWebApi/WebApi/WellKnownDistributedTaskVariables.cs), [job extension](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Worker/JobExtension.cs), [broker server](https://github.com/actions/runner/blob/197ca027b90de199464dee3bb9ff198a1db60967/src/Runner.Common/BrokerServer.cs)) | Before using the candidate, check whether the named service supplies this variable. If a reviewed canary enables it, qualify and sanitize the resulting logs and telemetry before retaining or sharing evidence. | + +## Readiness boundary + +Before any future candidate change, identify the private organization/repository +and confirm the version offered there; verify the downloaded archive bytes against +the published digest and record the exact runtime/image digest. If the candidate +is `v2.338.0`, include the Node 24, runner broker-session, and conditional +diagnostics checks above in the reviewed canary preparation. None of those steps +has occurred here. + +Tenant availability, archive-byte verification, runtime/image qualification, +reviewed live harness authorization, sanitized live results, and the safe-drain +decision remain outstanding. Full G01/G02 and dependent production gates remain +unresolved. No GitHub issue or Project status was changed. + +## Local documentation validation + +On 2026-10-13, relative Markdown links and heading fragments resolved for all +three changed documents; `git diff --check` emitted no diagnostics; and the +credential/token/private-key/personal-path scan found no matches. No tests were +run because this change is documentation-only. From 22e95618fce5a3abc853155f92c283553becb974 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 12:44:55 +0900 Subject: [PATCH 04/16] docs: add advisory screen to G01 checkpoint --- .../evidence/g01-runner-release-checkpoint.md | 105 +++++++++++++++++- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index d17c2e2e..56c41521 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -1,9 +1,11 @@ # G01 runner release-source readiness checkpoint -Date: 2026-10-13. This is a read-only check of official GitHub release, tag, -compare, tree, and file metadata/source via `gh api`. No archive bytes were -downloaded or hashed, no runner was extracted or executed, no tenant-specific -availability was checked, and no GitHub write or live operation was performed. +Date: 2026-10-13. This checkpoint combines read-only public GitHub release, +source, published-advisory, and pinned SDK disclosure-policy queries through the +REST API. The advisory results are a point-in-time screen of the stated filters. +No archive bytes were downloaded or hashed, no runner was extracted or executed, +no tenant-specific availability was checked, and no report submission, GitHub +write, or live operation was performed. ## Selection and release metadata @@ -70,9 +72,104 @@ reviewed live harness authorization, sanitized live results, and the safe-drain decision remain outstanding. Full G01/G02 and dependent production gates remain unresolved. No GitHub issue or Project status was changed. +## Public advisory and reporting-policy screen + +Read-only queries made on 2026-10-13 against public GitHub REST endpoints. List +queries used `--paginate` with no explicit `per_page` override; the two +repository feeds requested `state=published` only. Results are advisory-feed +matches, not a vulnerability scan. Commands below show the endpoint and API +filters; `--jq` was used only to project response counts or fields. + +```text +gh api --paginate 'repos/actions/scaleset/security-advisories?state=published' +gh api --paginate 'repos/actions/runner/security-advisories?state=published' +gh api advisories/GHSA-2c6m-6gqh-6qg3 +gh api --paginate 'advisories?ecosystem=actions&affects=actions/runner@2.337.0' +``` + +The Scale Set repository feed returned `[]` (0). The runner repository feed +returned one record: GHSA-2c6m-6gqh-6qg3 / CVE-2022-39321, severity `medium`, +published and updated `2022-10-24T16:00:18Z`, with vulnerable range `<2.296.1` +and listed patched versions `2.296.2`, `2.293.1`, `2.289.4`, `2.285.2`, and +`2.283.4`. The exact Actions ecosystem query for `actions/runner@2.337.0` +returned `[]` (0). ([runner repository advisory](https://github.com/actions/runner/security/advisories/GHSA-2c6m-6gqh-6qg3)) + +The successful global advisory detail GET returns the same GHSA/CVE as severity +`high`, published `2022-10-25T19:54:27Z` and updated `2023-01-30T05:02:47Z`. +It lists these separate affected ranges and first patched versions: +`<2.283.4` → `2.283.4`; `>=2.284.0,<2.285.2` → `2.285.2`; +`>=2.286.0,<2.289.4` → `2.289.4`; `>=2.290.0,<2.293.1` → `2.293.1`; and +`>=2.294.0,<2.296.1` → `2.296.2`. Keep this global severity/date/range record +separate from the repository-feed record above; do not collapse the different +feed values. Literal runner version `2.337.0` is outside both returned range +forms, which does not verify an archive, image, tenant runtime, or general +vulnerability status. ([canonical global advisory](https://github.com/advisories/GHSA-2c6m-6gqh-6qg3)) + +The coordinator's earlier repository-specific detail GET returned HTTP 404; it +was a failed lookup, not an empty-feed or passing result. A direct confirmation +at `2026-10-13T03:40:16Z` used: + +```text +gh api --include repos/actions/runner/security-advisories/GHSA-2c6m-6gqh-6qg3 +``` + +It returned HTTP 200. Both observations are recorded; the successful global +advisory entry above remains the canonical cross-version record. + +The exact-version Go global-advisory queries were: + +```text +gh api --paginate 'advisories?ecosystem=go&affects=github.com/actions/scaleset@v0.4.0' +gh api --paginate 'advisories?ecosystem=go&affects=github.com/golang-jwt/jwt/v4@v4.5.2' +gh api --paginate 'advisories?ecosystem=go&affects=github.com/google/uuid@v1.6.0' +gh api --paginate 'advisories?ecosystem=go&affects=github.com/hashicorp/go-cleanhttp@v0.5.2' +gh api --paginate 'advisories?ecosystem=go&affects=github.com/hashicorp/go-retryablehttp@v0.7.8' +``` + +Each returned `[]` (0 matching published advisories) for the exact pinned +external module version named in G01's existing dependency files. The positive +query control was: + +```text +gh api --paginate 'advisories?ecosystem=go&affects=github.com/golang-jwt/jwt/v4@v4.5.1' +``` + +It returned GHSA-mh63-6h87-95cp / CVE-2025-30204, severity `high`, published +`2025-03-21T22:04:00Z`, updated `2025-04-10T13:02:35Z`, affected range +`<4.5.2`, first patched `4.5.2`. This control is for the older `v4.5.1` query, +not an advisory match for installed `v4.5.2`. ([query-control advisory](https://github.com/advisories/GHSA-mh63-6h87-95cp)) + +The pinned SDK `SECURITY.md` was read with +`gh api 'repos/actions/scaleset/contents/SECURITY.md?ref=6ce025902cd964747a078c2aabe7340ebc667eca'` +at commit `6ce025902cd964747a078c2aabe7340ebc667eca` (blob +`67a9cbf2c6c4161a66b9ae4fcd9b74bbff8d0b4d`, 1,744 bytes). It requires +coordinated disclosure and says not to report vulnerabilities through public +GitHub issues, discussions, or pull requests. This is a reporting policy, not a +runner-version support or lifetime guarantee. A prior `gh` code search targeting +`github/docs` for runner support-window wording returned no matches; that search +does not establish that no support policy exists. Do not infer a 30-day or +indefinite support promise; support and security status for the named canary +tenant remain a pre-execution qualification. ([pinned SDK SECURITY.md](https://github.com/actions/scaleset/blob/6ce025902cd964747a078c2aabe7340ebc667eca/SECURITY.md)) + +No new actual vulnerability was established by these metadata queries. The five +exact-version Go results do not cover the full module graph, import reachability, +all `go.sum`-only packages, standard library, toolchain, tests, a bundled runtime, +or an SBOM, and are not a `govulncheck` result. This screen does not replace +archive-byte verification, image/runtime auditing, tenant-specific version +qualification, or a fresh public-feed check before a future canary. Existing +G01/G02, live-authorization, and safe-drain gates remain open; no pin changes +follow from this advisory screen. + ## Local documentation validation On 2026-10-13, relative Markdown links and heading fragments resolved for all three changed documents; `git diff --check` emitted no diagnostics; and the credential/token/private-key/personal-path scan found no matches. No tests were run because this change is documentation-only. + +## Advisory-screen addendum validation + +On 2026-10-13, the added local links and heading fragments resolved; +`git diff --check` emitted no diagnostics; and the credential/token/private-key/ +personal-path scan found no matches. No tests, builds, compilers, or vulnerability +scanners were run for this documentation-only addendum. From 7fa9bce30e88bb214d2cc7aec47c76778e9d281d Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 12:47:12 +0900 Subject: [PATCH 05/16] docs: scope G01 advisory screen to reviewed results --- .../evidence/g01-runner-release-checkpoint.md | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 56c41521..5b079888 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -75,16 +75,19 @@ unresolved. No GitHub issue or Project status was changed. ## Public advisory and reporting-policy screen Read-only queries made on 2026-10-13 against public GitHub REST endpoints. List -queries used `--paginate` with no explicit `per_page` override; the two -repository feeds requested `state=published` only. Results are advisory-feed -matches, not a vulnerability scan. Commands below show the endpoint and API -filters; `--jq` was used only to project response counts or fields. +queries used `--paginate` with no explicit `per_page` override. The two +repository feeds requested `state=published`; the global list queries also +specified `type=reviewed`. A zero from a global query means no matching +GitHub-reviewed published advisory for that exact filter, not no unreviewed +reports or all public reports. Results are not a vulnerability scan. Commands +below show endpoint and API filters; `--jq` only projected response counts or +fields. ```text gh api --paginate 'repos/actions/scaleset/security-advisories?state=published' gh api --paginate 'repos/actions/runner/security-advisories?state=published' gh api advisories/GHSA-2c6m-6gqh-6qg3 -gh api --paginate 'advisories?ecosystem=actions&affects=actions/runner@2.337.0' +gh api --paginate 'advisories?type=reviewed&ecosystem=actions&affects=actions/runner@2.337.0' ``` The Scale Set repository feed returned `[]` (0). The runner repository feed @@ -92,7 +95,7 @@ returned one record: GHSA-2c6m-6gqh-6qg3 / CVE-2022-39321, severity `medium`, published and updated `2022-10-24T16:00:18Z`, with vulnerable range `<2.296.1` and listed patched versions `2.296.2`, `2.293.1`, `2.289.4`, `2.285.2`, and `2.283.4`. The exact Actions ecosystem query for `actions/runner@2.337.0` -returned `[]` (0). ([runner repository advisory](https://github.com/actions/runner/security/advisories/GHSA-2c6m-6gqh-6qg3)) +returned `[]` (0 matching GitHub-reviewed published advisories). ([runner repository advisory](https://github.com/actions/runner/security/advisories/GHSA-2c6m-6gqh-6qg3)) The successful global advisory detail GET returns the same GHSA/CVE as severity `high`, published `2022-10-25T19:54:27Z` and updated `2023-01-30T05:02:47Z`. @@ -119,25 +122,25 @@ advisory entry above remains the canonical cross-version record. The exact-version Go global-advisory queries were: ```text -gh api --paginate 'advisories?ecosystem=go&affects=github.com/actions/scaleset@v0.4.0' -gh api --paginate 'advisories?ecosystem=go&affects=github.com/golang-jwt/jwt/v4@v4.5.2' -gh api --paginate 'advisories?ecosystem=go&affects=github.com/google/uuid@v1.6.0' -gh api --paginate 'advisories?ecosystem=go&affects=github.com/hashicorp/go-cleanhttp@v0.5.2' -gh api --paginate 'advisories?ecosystem=go&affects=github.com/hashicorp/go-retryablehttp@v0.7.8' +gh api --paginate 'advisories?type=reviewed&ecosystem=go&affects=github.com/actions/scaleset@v0.4.0' +gh api --paginate 'advisories?type=reviewed&ecosystem=go&affects=github.com/golang-jwt/jwt/v4@v4.5.2' +gh api --paginate 'advisories?type=reviewed&ecosystem=go&affects=github.com/google/uuid@v1.6.0' +gh api --paginate 'advisories?type=reviewed&ecosystem=go&affects=github.com/hashicorp/go-cleanhttp@v0.5.2' +gh api --paginate 'advisories?type=reviewed&ecosystem=go&affects=github.com/hashicorp/go-retryablehttp@v0.7.8' ``` -Each returned `[]` (0 matching published advisories) for the exact pinned -external module version named in G01's existing dependency files. The positive -query control was: +Each returned `[]` (0 matching GitHub-reviewed published advisories) for the +exact pinned external module version named in G01's existing dependency files. +The positive query control was: ```text -gh api --paginate 'advisories?ecosystem=go&affects=github.com/golang-jwt/jwt/v4@v4.5.1' +gh api --paginate 'advisories?type=reviewed&ecosystem=go&affects=github.com/golang-jwt/jwt/v4@v4.5.1' ``` It returned GHSA-mh63-6h87-95cp / CVE-2025-30204, severity `high`, published `2025-03-21T22:04:00Z`, updated `2025-04-10T13:02:35Z`, affected range `<4.5.2`, first patched `4.5.2`. This control is for the older `v4.5.1` query, -not an advisory match for installed `v4.5.2`. ([query-control advisory](https://github.com/advisories/GHSA-mh63-6h87-95cp)) +not a matching advisory for the pinned `v4.5.2` dependency. ([query-control advisory](https://github.com/advisories/GHSA-mh63-6h87-95cp)) The pinned SDK `SECURITY.md` was read with `gh api 'repos/actions/scaleset/contents/SECURITY.md?ref=6ce025902cd964747a078c2aabe7340ebc667eca'` @@ -160,6 +163,10 @@ qualification, or a fresh public-feed check before a future canary. Existing G01/G02, live-authorization, and safe-drain gates remain open; no pin changes follow from this advisory screen. +Rollback scope: remove only this file's advisory-screen addendum; preserve parent +release/source commit `8ae0c1a3dd158360784de64232a4890f3f3b2be6` and its +historical validation. No live cleanup is involved. + ## Local documentation validation On 2026-10-13, relative Markdown links and heading fragments resolved for all From 08842fef7f6bd4a4cf1a39ebc4c7cb064a276919 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 13:19:23 +0900 Subject: [PATCH 06/16] docs: record G01 source vulnerability scan --- .../evidence/g01-runner-release-checkpoint.md | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 5b079888..89056d34 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -180,3 +180,171 @@ On 2026-10-13, the added local links and heading fragments resolved; `git diff --check` emitted no diagnostics; and the credential/token/private-key/ personal-path scan found no matches. No tests, builds, compilers, or vulnerability scanners were run for this documentation-only addendum. + +## Local source-mode Go vulnerability and reachability analysis + +The preceding advisory-screen validation is historical for that earlier +metadata-only addendum; this source analysis is a separate later addition. + +Date: 2026-10-13. This is read-only source analysis of the committed G01 module +and its local G02 replacement. It does not establish a clean security gate: +the source scan returned findings, the Go toolchain pin remains unchanged, and +separate remediation and re-verification are required before dependent G01, +G02, live-canary, and safe-drain gates can close. + +### Source and tool identity + +The scan used parent commit +`7fa9bce30e88bb214d2cc7aec47c76778e9d281d`, G01 tree +`9636ee550304dc8f155a44faa78d93b80939a138`, and local G02 replacement tree +`8015fedeccd7604cedef3e5e1814d190d7443757`. The G01 +[module file](../../experiments/g01-scaleset/go.mod) declares Go `1.26.8` +and replaces +`github.com/1XP-AI/gh-runnerd/experiments/g02-auth` with +`../g02-auth`, whose [local module](../../experiments/g02-auth/go.mod) is in +the same committed tree; both module trees were clean and contained no untracked Go, +`go.mod`, or `go.sum` inputs. + +No `govulncheck` executable was present in the standard tool locations. The +pinned tool was installed only into an ephemeral directory with +`go install golang.org/x/vuln/cmd/govulncheck@v1.7.0`, then checked with +`go version -m` before scanning target source. The binary reports module +`golang.org/x/vuln v1.7.0` with checksum +`h1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=`; a public +`go mod download -json golang.org/x/vuln@v1.7.0` returned the same checksum. +The cached pinned documentation blob matches +`8de6904a51b632fbb4c546ce7b50678798394312` at the immutable +[govulncheck v1.7.0 source](https://github.com/golang/vuln/blob/617f44b718537dccdea1915395650e0529e3b72e/cmd/govulncheck/doc.go). +The source documentation says `-test` includes test files, `-tags` selects +build variants, and source analysis uses the Go command on `PATH`; it also +documents that JSON, SARIF, and VEX formats can exit 0 despite findings. + +Each scanner invocation used +`govulncheck -mode=source -format=text -db=https://vuln.go.dev -test [-tags=] ./...` +from the G01 module. The child environment was built from an allowlist with +Go `1.26.8`, Darwin/ARM64 (`GOARM64=v8.0`), `GOENV=off`, +`GOWORK=off`, `GOFLAGS=-mod=readonly -p=2`, `GOAUTH=off`, public-only +`GOPROXY=https://proxy.golang.org`, `GOSUMDB=sum.golang.org`, and empty +private-module/no-proxy scopes. No HOME, Git/GitHub credentials, SSH settings, +proxy credentials, or ambient Go overlays/tool overrides were passed. For +`CGO_ENABLED=1`, `CC`/`CXX` were set to Apple Clang 21.0.0. Profiles ran +sequentially with a 15-minute per-profile deadline and two-way Go parallelism. +No G01/G02 test or application binary was run; `-test` caused test source to +be analyzed only. + +The scanner queried the live, unpinned `https://vuln.go.dev` database. A +read-only request to the [database index](https://vuln.go.dev/index/db.json) +after the profile batch returned body +`{"modified":"2026-10-08T22:31:09Z"}`, ETag +`8875c8c67555e9c875a431c63837b83d`, and Last-Modified +`2026-10-12T22:21:33Z` (response date `2026-10-13T03:42:05Z`). This is +observed database metadata, not an immutable database snapshot bound to each +scan. The advisory links below point to the public Go vulnerability database; +no advisory publication dates are inferred. + +### Profiles and exit results + +The six requested source profiles ran once in the same batch. A separate +`CGO=1,osusergo` profile was added after checking the build constraints: +G01 imports `os/user`, and this combination selects the unsupported account +lookup source while retaining cgo for other packages. The Android-only +constraint is outside the selected Darwin/ARM64 target. + +| Profile | CGO | Build tags | Elapsed | Result | +|---|---:|---|---:|---| +| A | 1 | default | 3.2 s | exit 3; 10 symbol-result IDs | +| B | 1 | `g01_live,g01_worker` | 2.2 s | exit 3; same 10 symbol-result IDs | +| C | 1 | `g01_pair_fixture` | 2.3 s | exit 3; same 10 symbol-result IDs | +| D | 1 | `g01_live,g01_worker,g01_pair_fixture` | 2.2 s | exit 3; same 10 symbol-result IDs | +| E | 1 | `g01_pair_fixture,g01_pair_real_cadence` | 2.3 s | exit 3; same 10 symbol-result IDs | +| F | 0 | default | 2.2 s | exit 3; same 10 symbol-result IDs | +| G (additional) | 1 | `osusergo` | 2.7 s | exit 3; same 10 symbol-result IDs | + +Text format returned nonzero exit 3 with findings for every profile; none +timed out. Complete raw logs were discarded after normalized result extraction, +so this record does not claim a separate review of every diagnostic line. +An A-profile `-show traces` replay (2.3 s, exit 3) collected call context. +One A-profile and the additional G profile were also run with `-show verbose` +(2.6 s and 2.7 s, exit 3) to distinguish symbol, package, and module results. +Those verbose outputs each reported 10 symbol-level findings, one +package-import finding, and two required-module findings. The non-symbol IDs +below are classified from those A and G verbose outputs; they are not +profile-by-profile verbose results for B–F. + +### Findings and source-call scope + +The text summaries classified these ten IDs as symbol-level findings from the +Go standard library in every requested profile and in profile G: +[GO-2026-6603](https://vuln.go.dev/ID/GO-2026-6603.json), +[GO-2026-6604](https://vuln.go.dev/ID/GO-2026-6604.json), +[GO-2026-6605](https://vuln.go.dev/ID/GO-2026-6605.json), +[GO-2026-6607](https://vuln.go.dev/ID/GO-2026-6607.json), +[GO-2026-6608](https://vuln.go.dev/ID/GO-2026-6608.json), +[GO-2026-6610](https://vuln.go.dev/ID/GO-2026-6610.json), +[GO-2026-6611](https://vuln.go.dev/ID/GO-2026-6611.json), +[GO-2026-6612](https://vuln.go.dev/ID/GO-2026-6612.json), +[GO-2026-6613](https://vuln.go.dev/ID/GO-2026-6613.json), and +[GO-2026-6617](https://vuln.go.dev/ID/GO-2026-6617.json). The scanner reported +the relevant standard-library packages at Go `1.26.8`, with Go `1.26.9` +as the fix version. The Go `1.26.9` tag is +[commit `2ae494ef9fb90e0da0073c31800ba38870249994`](https://github.com/golang/go/commit/2ae494ef9fb90e0da0073c31800ba38870249994); +no toolchain or manifest pin was changed here. + +The trace examples included these source call paths: + +| Finding IDs | Scanner-reported source path | +|---|---| +| GO-2026-6603, GO-2026-6611, GO-2026-6612, GO-2026-6617 | `net/http.CanonicalHeaderKey` / trailer handling, with traces through G01 `drainPollHook.RoundTrip` and `SDKAPI` request paths | +| GO-2026-6613 | `net/http.CanonicalHeaderKey` reached through `drainObservedBody.Close` and the drain response-body path | +| GO-2026-6605, GO-2026-6610 | `net/http.Client.CloseIdleConnections` reached through `drainPollHook.RoundTrip` and `SDKAPI.Preflight` / `SDKAPI.get` | +| GO-2026-6608 | `mime/multipart@go1.26.8`; trace includes `drainObservedBody.Read` and `net/textproto.Reader.ReadMIMEHeader` | +| GO-2026-6607 | `crypto/tls.Conn.HandshakeContext`; the example trace includes test-source function `TestDockerInspectExactRejectsReplacedSocket` | +| GO-2026-6604 | `os@go1.26.8` through `OpenJournal` / `openJournalAtAdmission`; the public Go database marks both affected imports Windows-only | + +GO-2026-6604 appears in the scanner's symbol results, but its Windows-only +metadata makes it inapplicable to these Darwin/ARM64 profiles; this is not a +Darwin exploitability finding. The other nine symbol results are analyzer +call-reachability reports, not proof that attacker-controlled inputs satisfy +the advisory's trigger conditions. Traces include test-source paths because +`-test` was enabled; tests and fixtures were not run. + +The verbose A and G outputs also reported: + +| Result level | Finding | Found / fixed | Classification | +|---|---|---|---| +| Package | [GO-2026-6609](https://vuln.go.dev/ID/GO-2026-6609.json) | `net/http@go1.26.8` → `go1.26.9` | Package is imported; scanner did not find a call from analyzed source | +| Required module | [GO-2026-6599](https://vuln.go.dev/ID/GO-2026-6599.json) | `stdlib@go1.26.8` → `go1.26.9` | Required module only; no package or call result | +| Required module | [GO-2026-6600](https://vuln.go.dev/ID/GO-2026-6600.json) | `stdlib@go1.26.8` → `go1.26.9` | Required module only; no package or call result | + +The public Go database also lists `golang.org/x/net`, fixed at `v0.60.0`, +for GO-2026-6603, GO-2026-6610, GO-2026-6611, GO-2026-6612, and +GO-2026-6617. No `x/net` call, package, or required-module finding appeared +in the verbose A or G output; this does not replace a full module-graph or +SBOM inventory. The scanner's source-level symbol analysis is approximate: +interface and function-pointer paths can be conservative, while reflection +and unsafe can hide paths, as documented by the +[pinned tool source](https://github.com/golang/vuln/blob/617f44b718537dccdea1915395650e0529e3b72e/cmd/govulncheck/doc.go). + +### Gate and scope + +This adds a Go standard-library security gate for the current Go `1.26.8` +source profile. The listed fixes are in Go `1.26.9`, but shared toolchain +remediation and fresh source re-verification need separate ownership and +authorization; no Go pin, dependency, source, workflow, canary, or runner +selection changed. These results do not qualify the tenant, archived runner +bytes, image or bundled runtime, live credentials, safe drain, or production +execution, and do not close full G01/G02. + +No Go tests, application builds, fixture execution, live runner operations, +GitHub writes, or GitHub advisory submissions occurred. The `govulncheck` +tool itself was installed in a temporary directory; the source scanner then +loaded the selected source and test files without running them. Rollback for +this checkpoint is limited to reverting this local evidence addendum; retain +the earlier advisory and release-source evidence unchanged. + +## Source-analysis evidence validation + +On 2026-10-13, all four relative Markdown links and their heading fragments resolved; +`git diff --check` emitted no diagnostics; and the added diff scan for +credential/token/private-key and personal-machine-path patterns found no +matches. No Go tests or application suite were run. From 53757f0f85ab8d3da629488a23243b8e58b1b894 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 13:24:17 +0900 Subject: [PATCH 07/16] docs: clarify G01 source scan execution --- .../evidence/g01-runner-release-checkpoint.md | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 89056d34..c3c69fe7 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -222,15 +222,21 @@ documents that JSON, SARIF, and VEX formats can exit 0 despite findings. Each scanner invocation used `govulncheck -mode=source -format=text -db=https://vuln.go.dev -test [-tags=] ./...` from the G01 module. The child environment was built from an allowlist with -Go `1.26.8`, Darwin/ARM64 (`GOARM64=v8.0`), `GOENV=off`, -`GOWORK=off`, `GOFLAGS=-mod=readonly -p=2`, `GOAUTH=off`, public-only +Go `1.26.8` (`GOTOOLCHAIN=go1.26.8`), Darwin/ARM64 +(`GOARM64=v8.0`), `GOENV=off`, `GOWORK=off`, +`GOFLAGS=-mod=readonly -p=2`, `GOEXPERIMENT=none`, `GOFIPS140=off`, +`GOMAXPROCS=2`, and `GOAUTH=off`, public-only `GOPROXY=https://proxy.golang.org`, `GOSUMDB=sum.golang.org`, and empty -private-module/no-proxy scopes. No HOME, Git/GitHub credentials, SSH settings, -proxy credentials, or ambient Go overlays/tool overrides were passed. For -`CGO_ENABLED=1`, `CC`/`CXX` were set to Apple Clang 21.0.0. Profiles ran -sequentially with a 15-minute per-profile deadline and two-way Go parallelism. -No G01/G02 test or application binary was run; `-test` caused test source to -be analyzed only. +private-module/no-proxy scopes. `GOROOT` was omitted and derived by Go from +the selected toolchain; `GOCACHEPROG` was unset. No HOME, Git/GitHub +credentials, SSH settings, proxy credentials, or ambient Go overlays/tool +overrides were passed. For `CGO_ENABLED=1`, `CC`/`CXX` were set to Apple +Clang 21.0.0. Profiles ran sequentially with a 15-minute per-profile deadline +and two-way Go parallelism. No G01/G02 application or test binary was launched, +no fixture was executed, and no `go test` command ran. `-test` caused test +source to be included in source analysis; Go package loading may compile or +load package export data, and the `govulncheck` tool itself was installed with +`go install`. The scanner queried the live, unpinned `https://vuln.go.dev` database. A read-only request to the [database index](https://vuln.go.dev/index/db.json) @@ -335,12 +341,13 @@ selection changed. These results do not qualify the tenant, archived runner bytes, image or bundled runtime, live credentials, safe drain, or production execution, and do not close full G01/G02. -No Go tests, application builds, fixture execution, live runner operations, -GitHub writes, or GitHub advisory submissions occurred. The `govulncheck` -tool itself was installed in a temporary directory; the source scanner then -loaded the selected source and test files without running them. Rollback for -this checkpoint is limited to reverting this local evidence addendum; retain -the earlier advisory and release-source evidence unchanged. +No Go tests, application/test-binary launches, fixture execution, live runner +operations, GitHub writes, or GitHub advisory submissions occurred. The +`govulncheck` tool itself was installed in a temporary directory; source-mode +analysis loaded the selected source and test files and may compile/load package +export data without launching the application or tests. Rollback for this +checkpoint is limited to reverting this local evidence addendum; retain the +earlier advisory and release-source evidence unchanged. ## Source-analysis evidence validation From c81a17b654686600277474ae63376fdcb1210193 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 16:03:43 +0900 Subject: [PATCH 08/16] Pin Go 1.26.9 and reverify G01 sources --- .github/workflows/ci.yml | 8 +- .github/workflows/pr-fast.yml | 2 +- Makefile | 2 +- docs/CI.md | 8 +- docs/DEPENDENCIES.md | 4 +- docs/evidence/g01-live-canary.md | 6 +- .../evidence/g01-runner-release-checkpoint.md | 133 ++++++++++++++++++ docs/third-party/go-testing-matcher.md | 4 +- experiments/g01-scaleset/README.md | 6 +- experiments/g01-scaleset/cmd/g01-live/main.go | 6 +- .../g01-scaleset/cmd/g01-live/main_test.go | 23 +++ .../g01-scaleset/cmd/g01-worker/main.go | 6 +- .../g01-scaleset/cmd/g01-worker/main_test.go | 22 +++ experiments/g01-scaleset/compare-sdk.sh | 2 +- experiments/g01-scaleset/go.mod | 2 +- experiments/g02-auth/README.md | 2 +- .../g02-auth/broker_paired_prep_test.go | 31 +++- experiments/g02-auth/broker_process.go | 2 +- experiments/g02-auth/broker_process_test.go | 17 ++- experiments/g02-auth/go.mod | 2 +- experiments/r1-credentials/README.md | 6 +- experiments/r1-credentials/go.mod | 2 +- go.mod | 2 +- scripts/check-offline-experiments.sh | 2 +- scripts/check-toolchain.sh | 4 +- scripts/fast-check.sh | 2 +- scripts/tooling_test.go | 122 ++++++++++------ 27 files changed, 347 insertions(+), 81 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 179fea02..1ac862cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: timeout-minutes: 15 env: # Match Make's explicit selection even if the installed default changes. - GOTOOLCHAIN: go1.26.8 + GOTOOLCHAIN: go1.26.9 steps: - name: Check out source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -81,7 +81,7 @@ jobs: timeout-minutes: 15 env: # Match Make's explicit selection even if the installed default changes. - GOTOOLCHAIN: go1.26.8 + GOTOOLCHAIN: go1.26.9 steps: - name: Check out source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -111,7 +111,7 @@ jobs: - experiments/g02-auth - experiments/r1-credentials env: - GOTOOLCHAIN: go1.26.8 + GOTOOLCHAIN: go1.26.9 OFFLINE_EXPERIMENT_MODULE: ${{ matrix.module }} steps: - name: Check out source @@ -136,7 +136,7 @@ jobs: timeout-minutes: 15 env: # Match Make's explicit selection even if the installed default changes. - GOTOOLCHAIN: go1.26.8 + GOTOOLCHAIN: go1.26.9 steps: - name: Check out source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/pr-fast.yml b/.github/workflows/pr-fast.yml index 718baf4c..d92f2c7e 100644 --- a/.github/workflows/pr-fast.yml +++ b/.github/workflows/pr-fast.yml @@ -19,7 +19,7 @@ jobs: env: BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} - GOTOOLCHAIN: go1.26.8 + GOTOOLCHAIN: go1.26.9 steps: - name: Check out source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/Makefile b/Makefile index e6349608..b0b87d83 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ SHELL := /usr/bin/env bash GO ?= go GOFLAGS ?= # A go directive is a minimum under auto, including on a newer installation. -override GOTOOLCHAIN := go1.26.8 +override GOTOOLCHAIN := go1.26.9 export GOTOOLCHAIN export GOFLAGS FAST_MODULE := $(value FAST_MODULE) diff --git a/docs/CI.md b/docs/CI.md index f8a9cec7..a102a757 100644 --- a/docs/CI.md +++ b/docs/CI.md @@ -1,11 +1,11 @@ # Public CI and local checks -G03 establishes the reproducible development baseline. The module requires Go 1.26.8 in [go.mod](../go.mod). That directive is a minimum under automatic toolchain selection; Make explicitly exports `GOTOOLCHAIN=go1.26.8` to select the exact version even on a newer installation. No redundant `toolchain` directive is kept. Go's [release policy](https://go.dev/doc/devel/release) and [security guidance](https://go.dev/doc/security/) support security fixes for the two most recent major releases; on 2026-09-07 the official release history lists Go 1.27.1 and Go 1.26.8. The project uses 1.26.8 because it is the latest patch in the supported 1.26 line observed on that date and the released Scale Set SDK baseline requires Go 1.25.3 or newer. Revisit the pin when a newer supported patch is selected and compatibility is rechecked. +G03 established the reproducible development baseline. Its 2026-09-07 snapshot recorded Go 1.26.8 in [go.mod](../go.mod) and selected it as the latest patch in the supported 1.26 line then observed; the official release history on that date listed Go 1.27.1 and Go 1.26.8. The Go directive is a minimum under automatic toolchain selection, and Make selects an exact toolchain without a redundant `toolchain` directive. Following the 2026-10-13 source-mode vulnerability result for Go 1.26.8, the approved current shared pin is Go 1.26.9. The patch and source re-verification evidence is recorded in the [G01 runner release checkpoint](evidence/g01-runner-release-checkpoint.md); it does not close the remaining G01/G02 or live qualification gates. The released Scale Set SDK baseline requires Go 1.25.3 or newer. -Make and standalone `scripts/check-toolchain.sh` select `go1.26.8` explicitly; +Make and standalone `scripts/check-toolchain.sh` select `go1.26.9` explicitly; they do not change the user's global Go configuration. Go may download that version into its normal per-user toolchain cache. The hosted workflow uses -`actions/setup-go` to install 1.26.8 from `go.mod` and uses the same explicit +`actions/setup-go` to install 1.26.9 from `go.mod` and uses the same explicit `GOTOOLCHAIN` value. The equality check still refuses an unexpected toolchain. Conventional settings such as `make GOFLAGS=-mod=readonly build` are exported through Go's environment, rather than placed before its subcommand. @@ -88,7 +88,7 @@ Individual commands are available when iterating: | Command | Check | | --- | --- | -| `make toolchain` | Confirm the module directives and selected Go toolchain are exactly 1.26.8. | +| `make toolchain` | Confirm the module directives and selected Go toolchain are exactly 1.26.9. | | `make build` | Link the application executable; included in `make check` and hosted CI. | | `make fmt` / `make fmt-check` | Format or verify all Go sources with the selected toolchain. | | `make vet` | Run `go vet ./...`. | diff --git a/docs/DEPENDENCIES.md b/docs/DEPENDENCIES.md index 9317f247..cd1f038e 100644 --- a/docs/DEPENDENCIES.md +++ b/docs/DEPENDENCIES.md @@ -21,7 +21,7 @@ runtime graph contains only the local module; nested experiments remain separate ## Toolchain -Go standard library: `go1.26.8`, BSD-3-Clause, the language/runtime baseline; +Go standard library: `go1.26.9`, BSD-3-Clause, the language/runtime baseline; [official release history](https://go.dev/doc/devel/release). The selector matcher helper adapted from the Go standard library is documented @@ -40,7 +40,7 @@ Both immutable manifests declare `runs.using: node24`; the upstream action documentation lists Actions Runner `v2.327.1` or later as the Node 24 minimum. The workflows stay on GitHub-hosted `ubuntu-24.04`. Setup Go v7's ESM migration does not change its inputs or behavior. The workflow keeps `go-version-file: -go.mod`, the Go 1.26.8 declaration and `GOTOOLCHAIN=go1.26.8`; `cache: false` +go.mod`, the Go 1.26.9 declaration and `GOTOOLCHAIN=go1.26.9`; `cache: false` keeps module caching disabled. Checkout keeps the exact triggering SHA for Public CI, the PR head SHA with `fetch-depth: 0`, and `persist-credentials: false`. The v7 unsafe fork checkout opt-in remains unset. diff --git a/docs/evidence/g01-live-canary.md b/docs/evidence/g01-live-canary.md index 93e0f201..14e2a822 100644 --- a/docs/evidence/g01-live-canary.md +++ b/docs/evidence/g01-live-canary.md @@ -53,9 +53,13 @@ digest; the checkpoint is source/metadata evidence only and authorizes no swap. target after host headroom is checked, 10-minute job deadline. Increase any limit only with new concrete authorization. No service-container workloads in this protocol canary. -- [ ] Use SDK `v0.4.0`, Go `1.26.8` and runner `2.337.0`; verify runner bytes +- [ ] Use SDK `v0.4.0`, Go `1.26.9` and runner `2.337.0`; verify runner bytes against [published digests](g01-contract.md#runner-and-jit-transport) and record exact runtime/image digest. Recheck support/security status before execution. + This supersedes the earlier Go `1.26.8` source profile. Go `1.26.8` commands + embedded in the recovery packet remain inert historical/specimen text and are + not current execution instructions; this checklist does not authorize a + canary or live runner operation. - [ ] Independent Luna max reviews the immutable live harness, authority checks, cleanup, fault barriers and sanitized telemetry. The offline fixture must not be pointed at GitHub by replacing its URL. The separate tagged driver diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index c3c69fe7..2b3372bb 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -355,3 +355,136 @@ On 2026-10-13, all four relative Markdown links and their heading fragments reso `git diff --check` emitted no diagnostics; and the added diff scan for credential/token/private-key and personal-machine-path patterns found no matches. No Go tests or application suite were run. + +## Go 1.26.9 remediation and source re-verification + +This addendum follows the Go 1.26.8 source-mode findings recorded above. The +authorized local remediation selects Go 1.26.9 across the active shared +toolchain pins and updates G01/G02 executable BuildInfo admission to require +the exact version. SDK `v0.4.0` and runner `v2.337.0` +remain unchanged; earlier release, advisory, and Go 1.26.8 scan records are +historical evidence and remain intact. + +### Toolchain and scan provenance + +Go `1.26.9` was resolved as the native Darwin/ARM64 +`golang.org/toolchain@v0.0.1-go1.26.9.darwin-arm64` module through +the public Go module proxy, with checksum verification through sum.golang.org: +module `h1:u1IV5D8HPeURJjWAqzcC8QRXDJqvXlh7FpsA4lGIg1c=`, go.mod +`h1:8wlg68NqwW7eMnI1aABk/C2pDYXj8mrMY4TyRfiLeS0=`. The official +Go `1.26.9` source tag resolves to commit +[`2ae494ef9fb90e0da0073c31800ba38870249994`](https://github.com/golang/go/commit/2ae494ef9fb90e0da0073c31800ba38870249994). +The trusted `govulncheck@v1.7.0` module is +`h1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=`; its pinned +source documentation is +[`cmd/govulncheck/doc.go`](https://github.com/golang/vuln/blob/617f44b718537dccdea1915395650e0529e3b72e/cmd/govulncheck/doc.go). +Before the batch, `go version` reported +`go1.26.9 darwin/arm64` and `govulncheck -version` +reported scanner `v1.7.0`, database URL +`https://vuln.go.dev`, and database-modified metadata +`2026-10-08T22:31:09Z`. The native cgo compiler was Apple Clang +`21.0.0`. + +The seven-profile source tree was staged at tree +`e37ee1834af7e6ba2543eed373396eb9da657b3a`; the G01 module +subtree was `da98e542ea2a8066a3af664a4b5d3f7bdf655ebb` and the G02 +module subtree was `4526e7951921658b5b0fc13979e488667cc0d98b`. +These identify the scanned local source before this evidence text was added; +no untracked Go files were present. + +Each profile ran sequentially from `experiments/g01-scaleset` +with `govulncheck -mode=source -format=text +-db=https://vuln.go.dev -test [-tags=] ./...`, with a 900-second +per-profile deadline. The child +environment was built from an allowlist: exact Go `1.26.9` first +on `PATH`; `GOTOOLCHAIN=go1.26.9`, +`GOENV=off`, `GOWORK=off`, +`GOFLAGS=-mod=readonly -p=2`, `GOAUTH=off`, +`GOEXPERIMENT=none`, `GOFIPS140=off`, +`GOMAXPROCS=2`; Darwin/ARM64 with `GOARM64=v8.0`; +and `GOPROXY=https://proxy.golang.org` only, +`GOSUMDB=sum.golang.org`, and empty private module/no-proxy +scopes. The existing Go module/build caches were explicitly selected; +`GOCACHEPROG` was unset, `GOROOT` was omitted for +default toolchain derivation, and no `HOME`, Git/GitHub, SSH, +proxy credentials, overlays, or ambient Go settings were passed. For cgo +profiles, `CC`/`CXX` selected the recorded Apple +Clang compiler. The scan date was 2026-10-13 UTC. + +| Profile | CGO | Build tags | Elapsed | Text result | +|---|---:|---|---:|---| +| A | 1 | default | 1.6 s | exit 0; no finding IDs | +| B | 1 | `g01_live,g01_worker` | 1.3 s | exit 0; no finding IDs | +| C | 1 | `g01_pair_fixture` | 1.3 s | exit 0; no finding IDs | +| D | 1 | `g01_live,g01_worker,g01_pair_fixture` | 1.3 s | exit 0; no finding IDs | +| E | 1 | `g01_pair_fixture,g01_pair_real_cadence` | 1.3 s | exit 0; no finding IDs | +| F | 0 | default | 1.5 s | exit 0; no finding IDs | +| G | 1 | `osusergo` | 1.3 s | exit 0; no finding IDs | + +All seven invocations completed without scanner, package-loading, or database +errors; text output contained no vulnerability IDs. The scanner queried the +mutable public database without an immutable snapshot identifier. A separate +GET to the database index after the batch returned body field +`modified=2026-10-08T22:31:09Z`, ETag +`8875c8c67555e9c875a431c63837b83d`, Last-Modified +`2026-10-13T04:17:36Z`, and HTTP Date +`2026-10-13T06:33:35Z`; its +`Cache-Control` was `public, max-age=3600`. These +mutable index/response times are not per-invocation scan timestamps or a +database snapshot bound to every profile. + +The Go 1.26.8 findings and exit-3 results above remain historical. This +Go 1.26.9 run found no known vulnerabilities in the seven stated source +profiles; that is not a guarantee that the toolchain, dependencies, tests, or +all runtime paths are vulnerability-free. `-test` loaded test +source for analysis but did not execute tests or fixtures. The source analyzer +may load or compile package export data; the scanner itself was installed with +`go install`. No G01/G02 application or test binary was launched by +the scan, and the scan batch ran no `go test` command. + +### Pin admission and focused verification + +Tests were added before implementation. Against the prior Go 1.26.8 state, +`TestToolingCheckToolchainRequiresGo1269` failed because the +checker still accepted 1.26.8 and rejected the required 1.26.9 fixture; +G01 live and worker `TestBuildRevisionAdmissionRequiresGo1269` +also failed their Go 1.26.9 admission cases, and G02 +`TestBrokerBuildMustMatchReviewedController` rejected the new +reviewed-build metadata. After the pin and exact BuildInfo gates changed, +the focused tests passed under Go 1.26.9. The tests accept only the exact +`go1.26.9` build value and reject Go 1.26.8, Go 1.27.1, and an +empty version while retaining the existing revision, SDK, tag, cgo, and +platform checks. + +Focused verification under the controlled Go 1.26.9 environment: + +- `make toolchain`: exit 0; selected `go1.26.9`. +- Root tooling subset + `go test -count=1 -run '^(TestToolingCheckToolchainRequiresGo1269|TestToolingPinsNewerSystemGo|TestToolingEstablishedModulesAreRequired|TestToolingOfflineModuleSelection|TestToolingDefaultG01PartitionsRun|TestToolingDefaultG02PartitionsRun|TestFastCheck.*)$' ./scripts`: + exit 0, 304.652 s; the subsequent exact toolchain-table rerun also passed + (0.809 s). +- G01 admission tests + `go test -count=1 -tags=g01_live -run '^TestBuildRevisionAdmissionRequiresGo1269$' ./cmd/g01-live` + and the corresponding `g01_worker`/`./cmd/g01-worker` + command: both exit 0 (0.351 s and 0.298 s). +- G02 focused build-admission tests + `go test -count=1 -run '^(TestBrokerBuildMustMatchReviewedController|TestBrokerBuildRejectsFixtureCapability|TestBrokerBuildUnsupportedNativeAdmissionRefuses|TestPairedFixtureBuildRequiresExactGo1269)$' .`: + exit 0 (0.334 s). +- Final `go vet` checks for `./scripts`, + G01 `./cmd/g01-live` with `g01_live`, G01 + `./cmd/g01-worker` with `g01_worker`, and G02 + `.`: all exit 0. +- `go mod tidy -diff` for the root, G01, G02, and R1 modules: + exit 0 with no module changes. No `go.sum` changed. + `gofmt -d` on changed Go files and `git diff --check` + emitted no differences or diagnostics. + +The focused Go tests exercise synthetic tooling and admission fixtures only; +they do not run the full root, G01, G02, or R1 suites and do not execute +production runner, live-canary, or real-cadence operations. No packet specimen, +live service, runner, credential, Docker, or host operation was used. Existing +G01/G02 source, authorization, safe-drain, tenant/archive/image, and live +qualification gates remain open; no issue or Project state changed. SDK and +runner pins remain `v0.4.0` and `v2.337.0`. No Go +dependency or checksum pin changed. Rollback for this local remediation is the +single coherent local documentation/code pin commit; no external state changed. diff --git a/docs/third-party/go-testing-matcher.md b/docs/third-party/go-testing-matcher.md index 3ab4594c..903540a7 100644 --- a/docs/third-party/go-testing-matcher.md +++ b/docs/third-party/go-testing-matcher.md @@ -20,8 +20,8 @@ The upstream source identifies its notice as follows: // license that can be found in the LICENSE file. ``` -The applicable Go license text from the pinned Go 1.26.8 toolchain is reproduced -verbatim below. +The applicable Go license text from the Go 1.26.8 source used for this +adaptation is reproduced verbatim below. ```text Copyright 2009 The Go Authors. diff --git a/experiments/g01-scaleset/README.md b/experiments/g01-scaleset/README.md index a331a204..9775c6fb 100644 --- a/experiments/g01-scaleset/README.md +++ b/experiments/g01-scaleset/README.md @@ -8,15 +8,15 @@ own test server. Public dependency/toolchain downloads are separate from tests. ```sh cd experiments/g01-scaleset -GOTOOLCHAIN=go1.26.8 go test -race -count=1 -timeout=45s ./... -GOTOOLCHAIN=go1.26.8 go vet ./... +GOTOOLCHAIN=go1.26.9 go test -race -count=1 -timeout=45s ./... +GOTOOLCHAIN=go1.26.9 go vet ./... ./compare-sdk.sh ``` `compare-sdk.sh` copies the module to a disposable directory and runs the same suite against release `v0.4.0` and the immutable audited pseudo-version. It does not change this module's pin. With dependencies cached, the tests are offline. -`GOTOOLCHAIN=go1.26.8` makes the verification toolchain exact; the module's Go +`GOTOOLCHAIN=go1.26.9` makes the verification toolchain exact; the module's Go directive alone is a minimum and the toolchain directive alone is a suggestion. The red commit contains a compiling callback-only recovery baseline. The green diff --git a/experiments/g01-scaleset/cmd/g01-live/main.go b/experiments/g01-scaleset/cmd/g01-live/main.go index c08dc0ca..c6a18da8 100644 --- a/experiments/g01-scaleset/cmd/g01-live/main.go +++ b/experiments/g01-scaleset/cmd/g01-live/main.go @@ -21,7 +21,11 @@ import ( func buildRevision() (string, bool) { info, ok := debug.ReadBuildInfo() - if !ok || info.GoVersion != "go1.26.8" { + return buildRevisionFromInfo(info, ok) +} + +func buildRevisionFromInfo(info *debug.BuildInfo, ok bool) (string, bool) { + if !ok || info == nil || info.GoVersion != "go1.26.9" { return "", false } version, clean, sdk := "", false, false diff --git a/experiments/g01-scaleset/cmd/g01-live/main_test.go b/experiments/g01-scaleset/cmd/g01-live/main_test.go index fb52658c..53325b67 100644 --- a/experiments/g01-scaleset/cmd/g01-live/main_test.go +++ b/experiments/g01-scaleset/cmd/g01-live/main_test.go @@ -10,6 +10,7 @@ import ( "io" "os" "path/filepath" + "runtime/debug" "strings" "syscall" "testing" @@ -19,6 +20,28 @@ import ( "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/liveworker" ) +func TestBuildRevisionAdmissionRequiresGo1269(t *testing.T) { + revision := strings.Repeat("a", 40) + good := &debug.BuildInfo{ + GoVersion: "go1.26.9", + Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, + Settings: []debug.BuildSetting{ + {Key: "vcs.revision", Value: revision}, + {Key: "vcs.modified", Value: "false"}, + }, + } + if got, ok := buildRevisionFromInfo(good, true); !ok || got != revision { + t.Fatalf("Go 1.26.9 reviewed build rejected: revision=%q admitted=%v", got, ok) + } + for _, version := range []string{"go1.26.8", "go1.27.1", ""} { + bad := *good + bad.GoVersion = version + if _, ok := buildRevisionFromInfo(&bad, true); ok { + t.Errorf("build toolchain %q admitted", version) + } + } +} + type unreadable struct{ t *testing.T } func (r unreadable) Read([]byte) (int, error) { diff --git a/experiments/g01-scaleset/cmd/g01-worker/main.go b/experiments/g01-scaleset/cmd/g01-worker/main.go index 780399f7..2a358823 100644 --- a/experiments/g01-scaleset/cmd/g01-worker/main.go +++ b/experiments/g01-scaleset/cmd/g01-worker/main.go @@ -16,7 +16,11 @@ import ( func buildRevision() (string, bool) { info, ok := debug.ReadBuildInfo() - if !ok || info.GoVersion != "go1.26.8" { + return buildRevisionFromInfo(info, ok) +} + +func buildRevisionFromInfo(info *debug.BuildInfo, ok bool) (string, bool) { + if !ok || info == nil || info.GoVersion != "go1.26.9" { return "", false } revision := "" diff --git a/experiments/g01-scaleset/cmd/g01-worker/main_test.go b/experiments/g01-scaleset/cmd/g01-worker/main_test.go index 3fb38e42..b9cd5a24 100644 --- a/experiments/g01-scaleset/cmd/g01-worker/main_test.go +++ b/experiments/g01-scaleset/cmd/g01-worker/main_test.go @@ -6,11 +6,33 @@ import ( "bytes" "context" "io" + "runtime/debug" "strings" "testing" "time" ) +func TestBuildRevisionAdmissionRequiresGo1269(t *testing.T) { + revision := strings.Repeat("a", 40) + good := &debug.BuildInfo{ + GoVersion: "go1.26.9", + Settings: []debug.BuildSetting{ + {Key: "vcs.revision", Value: revision}, + {Key: "vcs.modified", Value: "false"}, + }, + } + if got, ok := buildRevisionFromInfo(good, true); !ok || got != revision { + t.Fatalf("Go 1.26.9 reviewed build rejected: revision=%q admitted=%v", got, ok) + } + for _, version := range []string{"go1.26.8", "go1.27.1", ""} { + bad := *good + bad.GoVersion = version + if _, ok := buildRevisionFromInfo(&bad, true); ok { + t.Errorf("build toolchain %q admitted", version) + } + } +} + type unreadable struct{ t *testing.T } func (r unreadable) Read([]byte) (int, error) { diff --git a/experiments/g01-scaleset/compare-sdk.sh b/experiments/g01-scaleset/compare-sdk.sh index 584cfa8a..23856ea7 100755 --- a/experiments/g01-scaleset/compare-sdk.sh +++ b/experiments/g01-scaleset/compare-sdk.sh @@ -5,7 +5,7 @@ set -eu experiment_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd) comparison_dir=$(mktemp -d "${TMPDIR:-/tmp}/g01-compare.XXXXXXXX") trap 'rm -rf -- "$comparison_dir"' EXIT HUP INT TERM -export GOTOOLCHAIN=go1.26.8 +export GOTOOLCHAIN=go1.26.9 for sdk_version in v0.4.0 v0.4.1-0.20260721134647-cb0405b2d874; do mkdir "$comparison_dir/$sdk_version" cp "$experiment_dir/go.mod" "$experiment_dir/go.sum" "$experiment_dir/"*.go "$comparison_dir/$sdk_version/" diff --git a/experiments/g01-scaleset/go.mod b/experiments/g01-scaleset/go.mod index e53d6274..7ace3e69 100644 --- a/experiments/g01-scaleset/go.mod +++ b/experiments/g01-scaleset/go.mod @@ -1,6 +1,6 @@ module github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset -go 1.26.8 +go 1.26.9 require ( github.com/1XP-AI/gh-runnerd/experiments/g02-auth v0.0.0 diff --git a/experiments/g02-auth/README.md b/experiments/g02-auth/README.md index aba894b8..03848196 100644 --- a/experiments/g02-auth/README.md +++ b/experiments/g02-auth/README.md @@ -10,7 +10,7 @@ go vet ./... go run ./cmd/g02-synthetic ``` -The command generates a new RSA key, verifies two synthetic organization/installation bindings through a fake API, commits them once to an in-memory sink, and prints only a sanitized summary. It has no live mode. Tests make a local random-port HTTP request and use fake GitHub responses. No existing credentials are read, no App/installation/runner is created, and the synthetic demo saves no key. Driver input tests create only their own temporary synthetic PEM fixture. Go 1.26.8 is pinned; there are no third-party module dependencies. +The command generates a new RSA key, verifies two synthetic organization/installation bindings through a fake API, commits them once to an in-memory sink, and prints only a sanitized summary. It has no live mode. Tests make a local random-port HTTP request and use fake GitHub responses. No existing credentials are read, no App/installation/runner is created, and the synthetic demo saves no key. Driver input tests create only their own temporary synthetic PEM fixture. Go 1.26.9 is pinned; there are no third-party module dependencies. The library contains: diff --git a/experiments/g02-auth/broker_paired_prep_test.go b/experiments/g02-auth/broker_paired_prep_test.go index 2a619077..8c8a9317 100644 --- a/experiments/g02-auth/broker_paired_prep_test.go +++ b/experiments/g02-auth/broker_paired_prep_test.go @@ -20,7 +20,7 @@ const ( pairedRealCadenceBridgeTags = "g01_live,g01_pair_fixture,g01_pair_real_cadence" pairedFixtureProgramPath = "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live" pairedFixtureSDKVersion = "v0.4.0" - pairedFixtureGoVersion = "go1.26.8" + pairedFixtureGoVersion = "go1.26.9" ) type preparedBridgeBinary struct { @@ -101,7 +101,7 @@ func compilePairedG01Binaries(t *testing.T, tagSets []string) map[string]prepare } command = exec.Command("go", "build", "-buildvcs=true", "-tags", tags, "-o", out, "./cmd/g01-live") command.Dir = filepath.Join(cloneRoot, "experiments", "g01-scaleset") - command.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.8") + command.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.9") if output, err := command.CombinedOutput(); err != nil { _ = output t.Fatal("build reviewed g01 bridge binary") @@ -176,6 +176,33 @@ func validPairedFixtureBuild(info *debug.BuildInfo, expectedHead, expectedTags s return goos == runtime.GOOS && goarch == runtime.GOARCH && cgo == "1" && revision == expectedHead && clean && sdk && tags == expectedTags } +func TestPairedFixtureBuildRequiresExactGo1269(t *testing.T) { + head := strings.Repeat("a", 40) + info := &debug.BuildInfo{ + GoVersion: pairedFixtureGoVersion, + Path: pairedFixtureProgramPath, + Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: pairedFixtureSDKVersion}}, + Settings: []debug.BuildSetting{ + {Key: "GOOS", Value: runtime.GOOS}, + {Key: "GOARCH", Value: runtime.GOARCH}, + {Key: "CGO_ENABLED", Value: "1"}, + {Key: "-tags", Value: pairedFixtureBridgeTags}, + {Key: "vcs.revision", Value: head}, + {Key: "vcs.modified", Value: "false"}, + }, + } + if !validPairedFixtureBuild(info, head, pairedFixtureBridgeTags) { + t.Fatal("Go 1.26.9 fixture build rejected") + } + for _, version := range []string{"go1.26.8", "go1.27.1", ""} { + previous := *info + previous.GoVersion = version + if validPairedFixtureBuild(&previous, head, pairedFixtureBridgeTags) { + t.Fatalf("fixture build with Go %q admitted", version) + } + } +} + func formatPreparedBridgeReceipt(head, digest, tags string) []byte { return []byte(strings.Join([]string{ "head " + head, diff --git a/experiments/g02-auth/broker_process.go b/experiments/g02-auth/broker_process.go index e93616a6..4f3ad7c7 100644 --- a/experiments/g02-auth/broker_process.go +++ b/experiments/g02-auth/broker_process.go @@ -45,7 +45,7 @@ func pairedChildDeadline(parent context.Context, now time.Time) (time.Time, erro } func validBrokerBuild(info *debug.BuildInfo, expected string) bool { - if info == nil || info.GoVersion != "go1.26.8" || info.Path != "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live" || !brokerSHA40.MatchString(expected) { + if info == nil || info.GoVersion != "go1.26.9" || info.Path != "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live" || !brokerSHA40.MatchString(expected) { return false } revision, clean, sdk := "", false, false diff --git a/experiments/g02-auth/broker_process_test.go b/experiments/g02-auth/broker_process_test.go index 0998eef6..61514e0d 100644 --- a/experiments/g02-auth/broker_process_test.go +++ b/experiments/g02-auth/broker_process_test.go @@ -395,11 +395,11 @@ func TestBrokerChildBoundsAndReplacedBinaryRefuse(t *testing.T) { } func TestBrokerBuildMustMatchReviewedController(t *testing.T) { sha := strings.Repeat("a", 40) - good := debug.BuildInfo{GoVersion: "go1.26.8", Path: "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live", Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, Settings: []debug.BuildSetting{{Key: "vcs.revision", Value: sha}, {Key: "vcs.modified", Value: "false"}, {Key: "GOOS", Value: runtime.GOOS}, {Key: "GOARCH", Value: runtime.GOARCH}, {Key: "CGO_ENABLED", Value: "1"}, {Key: "-tags", Value: "g01_live"}}} + good := debug.BuildInfo{GoVersion: "go1.26.9", Path: "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live", Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, Settings: []debug.BuildSetting{{Key: "vcs.revision", Value: sha}, {Key: "vcs.modified", Value: "false"}, {Key: "GOOS", Value: runtime.GOOS}, {Key: "GOARCH", Value: runtime.GOARCH}, {Key: "CGO_ENABLED", Value: "1"}, {Key: "-tags", Value: "g01_live"}}} if !validBrokerBuild(&good, sha) { t.Fatal("reviewed controller metadata rejected") } - for _, kind := range []string{"revision", "dirty", "SDK", "program"} { + for _, kind := range []string{"revision", "dirty", "SDK", "program", "toolchain"} { bad := good bad.Settings = append([]debug.BuildSetting(nil), good.Settings...) switch kind { @@ -411,16 +411,25 @@ func TestBrokerBuildMustMatchReviewedController(t *testing.T) { bad.Deps = []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.1"}} case "program": bad.Path = "arbitrary/program" + case "toolchain": + bad.GoVersion = "go1.26.8" } if validBrokerBuild(&bad, sha) { t.Errorf("accepted %s", kind) } } + for _, version := range []string{"go1.27.1", ""} { + bad := good + bad.GoVersion = version + if validBrokerBuild(&bad, sha) { + t.Errorf("accepted toolchain %q", version) + } + } } func TestBrokerBuildRejectsFixtureCapability(t *testing.T) { sha := strings.Repeat("a", 40) - fixture := debug.BuildInfo{GoVersion: "go1.26.8", Path: "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live", Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, Settings: []debug.BuildSetting{{Key: "vcs.revision", Value: sha}, {Key: "vcs.modified", Value: "false"}, {Key: "GOOS", Value: runtime.GOOS}, {Key: "GOARCH", Value: runtime.GOARCH}, {Key: "CGO_ENABLED", Value: "1"}, {Key: "-tags", Value: "g01_live,g01_pair_fixture"}}} + fixture := debug.BuildInfo{GoVersion: "go1.26.9", Path: "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live", Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, Settings: []debug.BuildSetting{{Key: "vcs.revision", Value: sha}, {Key: "vcs.modified", Value: "false"}, {Key: "GOOS", Value: runtime.GOOS}, {Key: "GOARCH", Value: runtime.GOARCH}, {Key: "CGO_ENABLED", Value: "1"}, {Key: "-tags", Value: "g01_live,g01_pair_fixture"}}} if validBrokerBuild(&fixture, sha) { t.Fatal("fixture-enabled controller build accepted by production broker gate") } @@ -428,7 +437,7 @@ func TestBrokerBuildRejectsFixtureCapability(t *testing.T) { func TestBrokerBuildUnsupportedNativeAdmissionRefuses(t *testing.T) { sha := strings.Repeat("a", 40) - base := debug.BuildInfo{GoVersion: "go1.26.8", Path: "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live", Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, Settings: []debug.BuildSetting{{Key: "vcs.revision", Value: sha}, {Key: "vcs.modified", Value: "false"}, {Key: "GOOS", Value: runtime.GOOS}, {Key: "GOARCH", Value: runtime.GOARCH}, {Key: "CGO_ENABLED", Value: "1"}, {Key: "-tags", Value: "g01_live"}}} + base := debug.BuildInfo{GoVersion: "go1.26.9", Path: "github.com/1XP-AI/gh-runnerd/experiments/g01-scaleset/cmd/g01-live", Deps: []*debug.Module{{Path: "github.com/actions/scaleset", Version: "v0.4.0"}}, Settings: []debug.BuildSetting{{Key: "vcs.revision", Value: sha}, {Key: "vcs.modified", Value: "false"}, {Key: "GOOS", Value: runtime.GOOS}, {Key: "GOARCH", Value: runtime.GOARCH}, {Key: "CGO_ENABLED", Value: "1"}, {Key: "-tags", Value: "g01_live"}}} for _, tc := range []struct{ key, value string }{{"CGO_ENABLED", "0"}, {"CGO_ENABLED", ""}, {"-tags", "g01_live,osusergo"}, {"-tags", "g01_live osusergo"}, {"GOOS", "other"}, {"GOARCH", "other"}} { t.Run(tc.key+tc.value, func(t *testing.T) { bad := base diff --git a/experiments/g02-auth/go.mod b/experiments/g02-auth/go.mod index ce8f7166..2d555f3d 100644 --- a/experiments/g02-auth/go.mod +++ b/experiments/g02-auth/go.mod @@ -1,3 +1,3 @@ module github.com/1XP-AI/gh-runnerd/experiments/g02-auth -go 1.26.8 +go 1.26.9 diff --git a/experiments/r1-credentials/README.md b/experiments/r1-credentials/README.md index 5b29a17a..a30e9bce 100644 --- a/experiments/r1-credentials/README.md +++ b/experiments/r1-credentials/README.md @@ -24,9 +24,9 @@ credential expiry remains authoritative. Run the candidate checks from this module directory: ```sh -GOTOOLCHAIN=go1.26.8 go test ./... -GOTOOLCHAIN=go1.26.8 go test -race -count=1 ./... -GOTOOLCHAIN=go1.26.8 go vet ./... +GOTOOLCHAIN=go1.26.9 go test ./... +GOTOOLCHAIN=go1.26.9 go test -race -count=1 ./... +GOTOOLCHAIN=go1.26.9 go vet ./... ``` The repository-level offline gate must run from the repository root because its diff --git a/experiments/r1-credentials/go.mod b/experiments/r1-credentials/go.mod index fa69079c..c4ed93e4 100644 --- a/experiments/r1-credentials/go.mod +++ b/experiments/r1-credentials/go.mod @@ -1,3 +1,3 @@ module github.com/1XP-AI/gh-runnerd/experiments/r1-credentials -go 1.26.8 +go 1.26.9 diff --git a/go.mod b/go.mod index 8877525c..34d287c6 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/1XP-AI/gh-runnerd -go 1.26.8 +go 1.26.9 diff --git a/scripts/check-offline-experiments.sh b/scripts/check-offline-experiments.sh index f3faca04..f3c50836 100644 --- a/scripts/check-offline-experiments.sh +++ b/scripts/check-offline-experiments.sh @@ -3,7 +3,7 @@ set -euo pipefail go_cmd="${GO:-go}" -exact_toolchain="go1.26.8" +exact_toolchain="go1.26.9" default_heavy_test_regex='^TestBaselineStatisticsPresenceAndEligibility$' default_handoff_test_regex='^TestControllerHandoff' default_heavy_and_handoff_skip_regex='^Test(BaselineStatisticsPresenceAndEligibility|ControllerHandoff.*)$' diff --git a/scripts/check-toolchain.sh b/scripts/check-toolchain.sh index 4b829123..83142090 100644 --- a/scripts/check-toolchain.sh +++ b/scripts/check-toolchain.sh @@ -3,8 +3,8 @@ set -euo pipefail go_cmd="${GO:-go}" -expected_toolchain="go1.26.8" -expected_go_directive="1.26.8" +expected_toolchain="go1.26.9" +expected_go_directive="1.26.9" # Standalone invocation must select the pin too; auto never downgrades a newer Go. export GOTOOLCHAIN="${expected_toolchain}" diff --git a/scripts/fast-check.sh b/scripts/fast-check.sh index 06b1fc7c..b3097b4a 100755 --- a/scripts/fast-check.sh +++ b/scripts/fast-check.sh @@ -3,7 +3,7 @@ set -euo pipefail go_cmd="${GO:-go}" -exact_toolchain="go1.26.8" +exact_toolchain="go1.26.9" # Keep this standalone entry point on the same pinned toolchain as Make and # hosted CI. It is an iteration aid, not a replacement for the complete gate. diff --git a/scripts/tooling_test.go b/scripts/tooling_test.go index 63aca05b..ffff33c2 100644 --- a/scripts/tooling_test.go +++ b/scripts/tooling_test.go @@ -18,10 +18,10 @@ const ( g01TerminalHeavyRegex = `^TestPairedTerminal(FinalResultCapacity|PendingChildCapacity|EligibilityUsesFreshExactFacts|CapturedAcknowledgementCancellation|MissingAcknowledgementsAndPostchecks)$` g01TerminalRemainderSkipRegex = `^TestPairedTerminal(FinalResultCapacity|PendingChildCapacity|EligibilityUsesFreshExactFacts|CapturedAcknowledgementCancellation|MissingAcknowledgementsAndPostchecks|Actual(Controller|Worker)SyncFailures|PostIntent(JournalIdentity|AuthorityBoundaries)|ClosedReplayActualFile|WorkerReceiptSurvivesControllerWriteFailure|FixtureStorageFailure)$` g01TerminalStorageRegex = `^TestPairedTerminal(Actual(Controller|Worker)SyncFailures|PostIntent(JournalIdentity|AuthorityBoundaries)|ClosedReplayActualFile|WorkerReceiptSurvivesControllerWriteFailure|FixtureStorageFailure)$` - g01TerminalHeavyInvocation = "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run " + g01TerminalHeavyRegex + " ./livecanary" - g01TerminalRemainderInvocation = "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPairedTerminal -skip " + g01TerminalRemainderSkipRegex + " ./livecanary" - g01TerminalStorageInvocation = "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run " + g01TerminalStorageRegex + " ./livecanary" - g01LegacyTerminalInvocation = "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPairedTerminal -skip " + g01TerminalStorageRegex + " ./livecanary" + g01TerminalHeavyInvocation = "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run " + g01TerminalHeavyRegex + " ./livecanary" + g01TerminalRemainderInvocation = "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPairedTerminal -skip " + g01TerminalRemainderSkipRegex + " ./livecanary" + g01TerminalStorageInvocation = "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run " + g01TerminalStorageRegex + " ./livecanary" + g01LegacyTerminalInvocation = "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPairedTerminal -skip " + g01TerminalStorageRegex + " ./livecanary" ) func toolingFile(t *testing.T, root, name, data string, mode os.FileMode) { @@ -48,7 +48,7 @@ func toolingRun(t *testing.T, root string, extra []string, args ...string) (stri } env = append(env, entry) } - cmd.Env = append(env, "GOTOOLCHAIN=go1.26.8", "GOFLAGS=", "GOWORK=off") + cmd.Env = append(env, "GOTOOLCHAIN=go1.26.9", "GOFLAGS=", "GOWORK=off") cmd.Env = append(cmd.Env, extra...) data, err := cmd.CombinedOutput() return string(data), err @@ -85,7 +85,7 @@ func toolingFixture(t *testing.T) string { toolingFile(t, root, "cmd/gh-runnerd/main.go", "package main\n\nfunc main() {}\n", 0600) for _, module := range []string{"g01-scaleset", "g02-auth", "r1-credentials"} { base := "experiments/" + module - toolingFile(t, root, base+"/go.mod", "module example.test/"+module+"\n\ngo 1.26.8\n", 0600) + toolingFile(t, root, base+"/go.mod", "module example.test/"+module+"\n\ngo 1.26.9\n", 0600) toolingFile(t, root, base+"/fixture.go", "package fixture\n", 0600) } toolingFile(t, root, "experiments/g01-scaleset/livecanary/fixture.go", "package livecanary\n\nfunc fixtureValue() string { return \"livecanary-fixture\" }\n", 0600) @@ -127,10 +127,10 @@ func TestToolingPinsNewerSystemGo(t *testing.T) { } // Controlled newer-installation fixture: only an explicit exact selection // delegates to the actual installed Go; auto reports a newer bundled version. - toolingFile(t, root, "newer-go", "#!/bin/sh\nif [ \"${GOTOOLCHAIN:-auto}\" = go1.26.8 ]; then exec \"$TOOLING_REAL_GO\" \"$@\"; fi\nif [ \"$1\" = version ]; then echo 'go version go1.27.1 linux/amd64'; else exit 88; fi\n", 0700) + toolingFile(t, root, "newer-go", "#!/bin/sh\nif [ \"${GOTOOLCHAIN:-auto}\" = go1.26.9 ]; then exec \"$TOOLING_REAL_GO\" \"$@\"; fi\nif [ \"$1\" = version ]; then echo 'go version go1.27.1 linux/amd64'; else exit 88; fi\n", 0700) for _, args := range [][]string{{"make", "GO=" + filepath.Join(root, "newer-go"), "toolchain"}, {"bash", "scripts/check-toolchain.sh"}} { env := []string{"GOTOOLCHAIN=auto", "GO=" + filepath.Join(root, "newer-go"), "TOOLING_REAL_GO=" + realGo} - if out, err := toolingRun(t, root, env, args...); err != nil || !strings.Contains(out, "toolchain: go1.26.8") { + if out, err := toolingRun(t, root, env, args...); err != nil || !strings.Contains(out, "toolchain: go1.26.9") { t.Errorf("newer system selection did not use pin: %s", out) } } @@ -142,6 +142,46 @@ func TestToolingPinsNewerSystemGo(t *testing.T) { } } +func TestToolingCheckToolchainRequiresGo1269(t *testing.T) { + for _, tc := range []struct { + name, reportedVersion, want string + wantError bool + }{ + {name: "accept exact patch", reportedVersion: "go1.26.9", want: "toolchain: go1.26.9"}, + {name: "reject previous patch", reportedVersion: "go1.26.8", want: "selected go1.26.8, want go1.26.9", wantError: true}, + {name: "reject different newer patch", reportedVersion: "go1.27.1", want: "selected go1.27.1, want go1.26.9", wantError: true}, + } { + t.Run(tc.name, func(t *testing.T) { + root := toolingFixture(t) + toolingFile(t, root, "go.mod", "module example.test/root\n\ngo 1.26.9\n", 0600) + toolingFile(t, root, "reported-go", `#!/bin/sh +set -eu +if [ "${1:-}" = version ]; then + printf 'go version %s darwin/arm64\n' "$TOOLING_REPORTED_GO_VERSION" +elif [ "${1:-}" = env ] && [ "${2:-}" = GOTOOLCHAIN ]; then + printf '%s\n' "$GOTOOLCHAIN" +else + exit 88 +fi +`, 0700) + goPath := filepath.Join(root, "reported-go") + out, err := toolingRun(t, root, []string{ + "GO=" + goPath, + "TOOLING_REPORTED_GO_VERSION=" + tc.reportedVersion, + }, "bash", "scripts/check-toolchain.sh") + if tc.wantError { + if err == nil || !strings.Contains(out, tc.want) { + t.Fatalf("old Go toolchain was not rejected explicitly: err=%v output=%s", err, out) + } + return + } + if err != nil || !strings.Contains(out, tc.want) { + t.Fatalf("Go 1.26.9 did not pass exact toolchain admission: err=%v output=%s", err, out) + } + }) + } +} + func assertFastCheckRequiresExplicitSelectors(t *testing.T, root, fastCheck string) { t.Helper() for _, tc := range []struct { @@ -797,14 +837,14 @@ func TestNestedFastSelected(t *testing.T) {} module: ".", packagePath: "./...", test: "^TestFastSelected$", - invocation: "go1.26.8\tlist -json=false -f {{.Dir}} ./...\ngo1.26.8\ttest -v -json=false -list= -bench= -fuzz= -skip= -c=false -count=1 -cpu=1 -exec= -run ^TestFastSelected$ ./... -args -test.v=test2json", + invocation: "go1.26.9\tlist -json=false -f {{.Dir}} ./...\ngo1.26.9\ttest -v -json=false -list= -bench= -fuzz= -skip= -c=false -count=1 -cpu=1 -exec= -run ^TestFastSelected$ ./... -args -test.v=test2json", }, { name: "nested module", module: "./experiments/g01-scaleset", packagePath: ".", test: "^TestNestedFastSelected$", - invocation: "go1.26.8\tlist -json=false -f {{.Dir}} .\ngo1.26.8\ttest -v -json=false -list= -bench= -fuzz= -skip= -c=false -count=1 -cpu=1 -exec= -run ^TestNestedFastSelected$ . -args -test.v=test2json", + invocation: "go1.26.9\tlist -json=false -f {{.Dir}} .\ngo1.26.9\ttest -v -json=false -list= -bench= -fuzz= -skip= -c=false -count=1 -cpu=1 -exec= -run ^TestNestedFastSelected$ . -args -test.v=test2json", }, } { t.Run(tc.name, func(t *testing.T) { @@ -2128,7 +2168,7 @@ func TestToolingTaggedPairFixturePartitionsRun(t *testing.T) { terminalHeavyPath := "experiments/g01-scaleset/livecanary/pair_fixture_terminal_heavy_regression_test.go" terminalFuturePath := "experiments/g01-scaleset/livecanary/pair_fixture_terminal_future_regression_test.go" storagePath := "experiments/g01-scaleset/livecanary/pair_fixture_storage_regression_test.go" - remainingCollectionInvocation := "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -skip ^TestPaired ./livecanary" + remainingCollectionInvocation := "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -skip ^TestPaired ./livecanary" taggedPositiveSource := func(testName, marker string) string { return `//go:build g01_pair_fixture && !g01_live && !g01_worker @@ -2302,7 +2342,7 @@ func TestPairedTerminalFutureCoverage(t *testing.T) { "paired-collection", pairedCollectionSource, pairedCollectionPositiveSource, - "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPaired -skip ^TestPairedTerminal ./livecanary", + "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPaired -skip ^TestPairedTerminal ./livecanary", }, { listenerPath, @@ -2420,12 +2460,12 @@ func TestPairedTerminalFutureCoverage(t *testing.T) { log := string(data) lines := strings.Split(strings.TrimSpace(log), "\n") for _, invocation := range []string{ - "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPaired -skip ^TestPairedTerminal ./livecanary", + "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -run ^TestPaired -skip ^TestPairedTerminal ./livecanary", remainingCollectionInvocation, g01TerminalHeavyInvocation, g01TerminalRemainderInvocation, g01TerminalStorageInvocation, - "go1.26.8\tvet -tags=g01_pair_fixture ./livecanary", + "go1.26.9\tvet -tags=g01_pair_fixture ./livecanary", } { count := 0 for _, line := range lines { @@ -2437,7 +2477,7 @@ func TestPairedTerminalFutureCoverage(t *testing.T) { t.Fatalf("offline gate logged %q %d times; wrapper log:\n%s", invocation, count, log) } } - legacyCollectionInvocation := "go1.26.8\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -skip ^TestPairedTerminal ./livecanary" + legacyCollectionInvocation := "go1.26.9\ttest -race -count=1 -timeout=120s -tags=g01_pair_fixture -skip ^TestPairedTerminal ./livecanary" for _, line := range lines { if line == legacyCollectionInvocation { t.Fatalf("offline gate retained the unsplit collection invocation: %s", line) @@ -2574,7 +2614,7 @@ func toolingListLivecanary(t *testing.T, run string) []string { defer cancel() cmd := exec.CommandContext(ctx, "go", "test", "-count=1", "-tags=g01_pair_fixture", "-list", run, "./livecanary") cmd.Dir = filepath.Join("..", "experiments", "g01-scaleset") - cmd.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.8", "GOFLAGS=", "GOWORK=off") + cmd.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.9", "GOFLAGS=", "GOWORK=off") out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("list run=%q: %s", run, out) @@ -2595,7 +2635,7 @@ func toolingLivecanarySkipCheck(t *testing.T, run, skip string) string { defer cancel() cmd := exec.CommandContext(ctx, "go", "test", "-count=1", "-timeout=15s", "-tags=g01_pair_fixture", "-run", run, "-skip", skip, "./livecanary") cmd.Dir = filepath.Join("..", "experiments", "g01-scaleset") - cmd.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.8", "GOFLAGS=", "GOWORK=off") + cmd.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.9", "GOFLAGS=", "GOWORK=off") out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("skip check run=%q skip=%q: %s", run, skip, out) @@ -2844,13 +2884,13 @@ func FuzzDefaultG01Fixture(f *testing.F) { log := string(logData) lines := strings.Split(strings.TrimSpace(log), "\n") for _, invocation := range []string{ - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestBaselineStatisticsPresenceAndEligibility$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestControllerHandoff ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -skip ^Test(BaselineStatisticsPresenceAndEligibility|ControllerHandoff.*)$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerPrepareReviewedG01LiveBinary$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBroker(PrepareReviewedG01LiveBinary|RealCadenceChildExceedsThirtySeconds)$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -skip ^TestPaired ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestBaselineStatisticsPresenceAndEligibility$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestControllerHandoff ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -skip ^Test(BaselineStatisticsPresenceAndEligibility|ControllerHandoff.*)$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerPrepareReviewedG01LiveBinary$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBroker(PrepareReviewedG01LiveBinary|RealCadenceChildExceedsThirtySeconds)$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -skip ^TestPaired ./...", } { count := 0 for _, line := range lines { @@ -2862,7 +2902,7 @@ func FuzzDefaultG01Fixture(f *testing.F) { t.Fatalf("default G01 partition invocation %q ran %d times; wrapper log:\n%s", invocation, count, log) } } - r1Invocation := "go1.26.8\ttest -race -count=1 -timeout=45s ./..." + r1Invocation := "go1.26.9\ttest -race -count=1 -timeout=45s ./..." r1Count := 0 for _, line := range lines { if line == r1Invocation { @@ -2873,9 +2913,9 @@ func FuzzDefaultG01Fixture(f *testing.F) { t.Fatalf("offline gate ran the R1 fixture invocation %d times; wrapper log:\n%s", r1Count, log) } for _, invocation := range []string{ - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=120s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=120s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", } { for _, line := range lines { if line == invocation { @@ -3135,10 +3175,10 @@ func FuzzG02Fixture(f *testing.F) { log := string(logData) lines := strings.Split(strings.TrimSpace(log), "\n") for _, invocation := range []string{ - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerPrepareReviewedG01LiveBinary$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBroker(PrepareReviewedG01LiveBinary|RealCadenceChildExceedsThirtySeconds)$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -skip ^TestPaired ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerPrepareReviewedG01LiveBinary$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBroker(PrepareReviewedG01LiveBinary|RealCadenceChildExceedsThirtySeconds)$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -skip ^TestPaired ./...", } { count := 0 for _, line := range lines { @@ -3151,10 +3191,10 @@ func FuzzG02Fixture(f *testing.F) { } } for _, invocation := range []string{ - "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=45s -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=120s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", - "go1.26.8\ttest -race -count=1 -timeout=120s -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPaired -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=45s -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=120s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", + "go1.26.9\ttest -race -count=1 -timeout=120s -skip ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./...", } { for _, line := range lines { if line == invocation { @@ -3162,7 +3202,7 @@ func FuzzG02Fixture(f *testing.F) { } } } - r1Invocation := "go1.26.8\ttest -race -count=1 -timeout=45s ./..." + r1Invocation := "go1.26.9\ttest -race -count=1 -timeout=45s ./..." r1Count := 0 for _, line := range lines { if line == r1Invocation { @@ -3404,7 +3444,7 @@ exec "$TOOLING_REAL_GO" "$@" defer cancel() cmd := exec.CommandContext(ctx, "bash", "scripts/check-offline-experiments.sh") cmd.Dir = root - cmd.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.8", "GOFLAGS=", "GOWORK=off") + cmd.Env = append(os.Environ(), "GOTOOLCHAIN=go1.26.9", "GOFLAGS=", "GOWORK=off") cmd.Env = append(cmd.Env, env...) var out bytes.Buffer cmd.Stdout = &out @@ -3538,7 +3578,7 @@ func toolingMustNotInvokeCadence(t *testing.T, env []string) { if err != nil { t.Fatal(err) } - cadence := "go1.26.8\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./..." + cadence := "go1.26.9\ttest -race -count=1 -timeout=45s -run ^TestPairedBrokerRealCadenceChildExceedsThirtySeconds$ ./..." for _, line := range strings.Split(string(data), "\n") { if line == cadence { t.Fatalf("cadence ran after G02 prep cleanup path; wrapper log:\n%s", data) @@ -3629,8 +3669,8 @@ func toolingSignalExactPID(t *testing.T, pid int, spec string) { func TestToolingLicenseIdentityAndStaleRows(t *testing.T) { root := toolingFixture(t) - toolingFile(t, root, "go.mod", "module example.test/audit\n\ngo 1.26.8\n\nrequire example.test/dependency v1.2.0\n\nreplace example.test/dependency => ./replacement\n", 0600) - toolingFile(t, root, "replacement/go.mod", "module example.test/dependency\n\ngo 1.26.8\n", 0600) + toolingFile(t, root, "go.mod", "module example.test/audit\n\ngo 1.26.9\n\nrequire example.test/dependency v1.2.0\n\nreplace example.test/dependency => ./replacement\n", 0600) + toolingFile(t, root, "replacement/go.mod", "module example.test/dependency\n\ngo 1.26.9\n", 0600) toolingFile(t, root, "replacement/LICENSE", "Synthetic license fixture\n", 0600) base := "## Runtime modules\n\n| Module | Version | Replacement | License | Source |\n| --- | --- | --- | --- | --- |\n| `example.test/audit` | `local` | `none` | MIT | root |\n" good := "| `example.test/dependency` | `v1.2.0` | `./replacement` | MIT | local fixture |\n" From 9776562fc792e0fb76684fb7be90a7ed118ed0ec Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Tue, 13 Oct 2026 22:58:34 +0900 Subject: [PATCH 09/16] Clarify Go 1.26.9 red evidence and review --- .../evidence/g01-runner-release-checkpoint.md | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 2b3372bb..938d445e 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -445,8 +445,11 @@ the scan, and the scan batch ran no `go test` command. ### Pin admission and focused verification Tests were added before implementation. Against the prior Go 1.26.8 state, -`TestToolingCheckToolchainRequiresGo1269` failed because the -checker still accepted 1.26.8 and rejected the required 1.26.9 fixture; +`TestToolingCheckToolchainRequiresGo1269` failed because its synthetic +`go.mod` declares Go 1.26.9 and the prior checker exits on the Go-directive +mismatch before reaching the fake reported-version cases. This showed that +the prior checker rejected the Go 1.26.9 fixture; it did not establish that +the checker accepted a fake Go 1.26.8 report. G01 live and worker `TestBuildRevisionAdmissionRequiresGo1269` also failed their Go 1.26.9 admission cases, and G02 `TestBrokerBuildMustMatchReviewedController` rejected the new @@ -488,3 +491,18 @@ qualification gates remain open; no issue or Project state changed. SDK and runner pins remain `v0.4.0` and `v2.337.0`. No Go dependency or checksum pin changed. Rollback for this local remediation is the single coherent local documentation/code pin commit; no external state changed. + +### Independent review of the Go 1.26.9 pin commit + +On 2026-10-13, independent Codex GPT-6-Luna/max reviewed the exact +27-file commit `c81a17b654686600277474ae63376fdcb1210193`. +The reviewer found its Go 1.26.9 pin and G01/G02 BuildInfo-admission changes +internally consistent. Four focused synthetic selectors passed, and one +Go 1.26.9 `govulncheck@v1.7.0` Profile A verbose source-only scan exited 0 +with no finding IDs. + +The review held on the inaccurate toolchain-test RED interpretation corrected +above. It did not independently repeat all seven source profiles or the full +module/CI matrix, qualify live behavior, or perform GitHub PR review. Those +gates remain open. The documentation correction in this follow-up has not +received an exact-head review; no new-head review approval is claimed. From 4e5eb6641b37edf84661c121fbffda529e35301f Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Wed, 14 Oct 2026 00:20:10 +0900 Subject: [PATCH 10/16] docs: inventory active Go 1.26.9 pins with Muse --- docs/evidence/g01-toolchain-pin-inventory.md | 142 +++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 docs/evidence/g01-toolchain-pin-inventory.md diff --git a/docs/evidence/g01-toolchain-pin-inventory.md b/docs/evidence/g01-toolchain-pin-inventory.md new file mode 100644 index 00000000..d4262a1b --- /dev/null +++ b/docs/evidence/g01-toolchain-pin-inventory.md @@ -0,0 +1,142 @@ +# G01 toolchain pin inventory — Go 1.26.9 ACTIVE vs historical + +Source: `9776562fc792e0fb76684fb7be90a7ed118ed0ec` +(`9776562 Clarify Go 1.26.9 red evidence and review`), +branch `orca/issue-1-offline-protocol-signoff`. +Static inventory only; bounded scope, no G01 closure claim. +Writer: Cursor Agent, Muse Spark 1.3 Max, selected by the current user override. +Independent and GitHub review were not requested for this local work. + +## Method and boundary + +Static file reads plus `rg` text search only. No `go`/`make`/script +execution of any kind, no builds, tests, vet, scans, or advisory queries. +Packet recipes and specimens are inert text: never executed, compiled, +evaluated, or imported. No independent review, GitHub review, pushes, PRs, +merges, or live operations. No source, pin, or `go.sum` edits; no +`git add`/`git commit` (the coordinator owns the index). Only this new +file is added; all historical records are unaltered. + +## ACTIVE pin catalog (Go 1.26.9) + +| # | Anchor | Value | +| --- | --- | --- | +| 1 | Module directives: [root](../../go.mod), [G01](../../experiments/g01-scaleset/go.mod), [G02](../../experiments/g02-auth/go.mod), [R1](../../experiments/r1-credentials/go.mod) | `go 1.26.9` in all four; no `toolchain` directive in any | +| 2 | [Makefile](../../Makefile) | `override GOTOOLCHAIN := go1.26.9`; `GOVULNCHECK_VERSION ?= v1.7.0` | +| 3 | [check-toolchain.sh](../../scripts/check-toolchain.sh) | `expected_toolchain go1.26.9`, `expected_go_directive 1.26.9`; rejects a redundant `toolchain` directive and any mismatched `go version` | +| 4 | [check-offline-experiments.sh](../../scripts/check-offline-experiments.sh) | `exact_toolchain go1.26.9` for every partition (G01 static, G02 static, R1, tagged `g01_live,g01_worker`, five `g01_pair_fixture` livecanary partitions, vet) | +| 5 | [fast-check.sh](../../scripts/fast-check.sh) | `exact_toolchain go1.26.9`, exported with `GOWORK=off` | +| 6 | [compare-sdk.sh](../../experiments/g01-scaleset/compare-sdk.sh) | `export GOTOOLCHAIN=go1.26.9` | +| 7 | [ci.yml](../../.github/workflows/ci.yml) | `GOTOOLCHAIN: go1.26.9` in `root`, `race`, `offline`, `vuln`; `go-version-file: go.mod`; `checkout@3d3c42e5aac5ba805825da76410c181273ba90b1` (`v7.0.1`), `setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e` (`v7.0.0`) | +| 8 | [pr-fast.yml](../../.github/workflows/pr-fast.yml) | `GOTOOLCHAIN: go1.26.9`; same immutable action SHAs; `go-version-file: go.mod` | +| 9 | G01 gates: [live](../../experiments/g01-scaleset/cmd/g01-live/main.go) and [worker](../../experiments/g01-scaleset/cmd/g01-worker/main.go) `buildRevisionFromInfo` | Require `GoVersion == "go1.26.9"` plus a clean 40-hex revision (live additionally requires SDK `v0.4.0` with no replace) | +| 10 | G02 broker [broker_process.go](../../experiments/g02-auth/broker_process.go) `validBrokerBuild` | Requires `go1.26.9`, program `cmd/g01-live`, tags exactly `g01_live`, SDK `v0.4.0` with no replace, matching `GOOS`/`GOARCH`, `CGO_ENABLED=1`, clean expected revision; fixture tags refused | +| 11 | G02 paired fixture [broker_paired_prep_test.go](../../experiments/g02-auth/broker_paired_prep_test.go) | `pairedFixtureGoVersion = "go1.26.9"`; fixture builds compiled with `GOTOOLCHAIN=go1.26.9`; prepared receipt line `go go1.26.9`; `validPairedFixtureBuild` enforces version, path, SDK, tags, platform, cgo, and revision | +| 12 | Tooling harness [tooling_test.go](../../scripts/tooling_test.go) | Fixture child env sets `GOTOOLCHAIN=go1.26.9`; synthetic `go.mod` fixtures declare `go 1.26.9` | +| 13 | govulncheck `v1.7.0` | Makefile default, [script default](../../scripts/govulncheck.sh), [DEPENDENCIES CI-only tool](../DEPENDENCIES.md#ci-only-vulnerability-tool), [CI command table](../CI.md) | +| 14 | Dependency/CI prose | [DEPENDENCIES Toolchain](../DEPENDENCIES.md#toolchain) (`go1.26.9`, `go.mod` declaration, `GOTOOLCHAIN=go1.26.9`, `cache: false`, [matcher notice](../third-party/go-testing-matcher.md)); [CI.md](../CI.md) (approved current shared pin Go 1.26.9; `make toolchain` row requires exactly 1.26.9); [G01 README](../../experiments/g01-scaleset/README.md) (`GOTOOLCHAIN=go1.26.9` verify commands); [G02 README](../../experiments/g02-auth/README.md) (Go 1.26.9 pinned, no third-party deps); [R1 README active instructions](../../experiments/r1-credentials/README.md) (lines 27-29); [live-canary checklist](g01-live-canary.md#required-environment-and-authorization-record) (SDK `v0.4.0`, Go `1.26.9`, runner `2.337.0`) | + +SDK `v0.4.0` and runner `2.337.0` are unchanged by the toolchain +remediation; no Go dependency or checksum pin changed. + +## Stale ACTIVE pin finding: none + +- `rg -n "1\.26\.8"` over the twelve active pin files (four `go.mod`, + `Makefile`, `check-toolchain.sh`, `check-offline-experiments.sh`, + `fast-check.sh`, `compare-sdk.sh`, both workflows, + `DEPENDENCIES.md`) returned no matches (exit 1). +- `rg -n "^toolchain "` over the four `go.mod` files returned no + matches (exit 1): no redundant directive, as the checker requires. +- `go.sum` exists only at `experiments/g01-scaleset/go.sum`; root, G02, + and R1 have none, consistent with the dependency-free runtime module + record. No out-of-scope fix made; none required by this sweep. + +## Negative-test 1.26.8 (ACTIVE source, intentional reject fixtures) + +These tests accept only the exact `go1.26.9` build value and reject +`go1.26.8`, `go1.27.1`, and empty versions while retaining the existing +revision, SDK, tag, cgo, and platform checks. They are not stale pins: + +- [tooling_test.go:151](../../scripts/tooling_test.go) + `TestToolingCheckToolchainRequiresGo1269`, case `reject previous patch`. +- [g01-live main_test.go:36](../../experiments/g01-scaleset/cmd/g01-live/main_test.go) + `TestBuildRevisionAdmissionRequiresGo1269`. +- [g01-worker main_test.go:27](../../experiments/g01-scaleset/cmd/g01-worker/main_test.go) + `TestBuildRevisionAdmissionRequiresGo1269`. +- [broker_process_test.go:415](../../experiments/g02-auth/broker_process_test.go) + `TestBrokerBuildMustMatchReviewedController` toolchain case. +- [broker_paired_prep_test.go:197](../../experiments/g02-auth/broker_paired_prep_test.go) + `TestPairedFixtureBuildRequiresExactGo1269`. + +Per the corrected [pin admission record](g01-runner-release-checkpoint.md#pin-admission-and-focused-verification), +the RED showed the prior checker rejecting the Go 1.26.9 fixture on the +go-directive mismatch; it did not establish acceptance of a fake 1.26.8 +report. No new RED/RUN interpretation is claimed here. + +## Historical and provenance 1.26.8 (unaltered, truthful) + +- G03 baseline and audit: the [G03 evidence record](../G03-EVIDENCE.md) + and the [CI audit table](../CI.md#issue-73-audit-evidence) record Go + 1.26.8 as the 2026-09-07 snapshot and warmed baseline. Historical + measurements, not current pins. +- Checkpoint: the [Go 1.26.8 source-mode findings](g01-runner-release-checkpoint.md#local-source-mode-go-vulnerability-and-reachability-analysis) + (exit 3, ten symbol-result IDs, fix Go 1.26.9) remain historical; the + [Go 1.26.9 remediation and re-verification](g01-runner-release-checkpoint.md#go-1269-remediation-and-source-re-verification) + (seven profiles, exit 0, no finding IDs) is the recorded + re-verification. The [independent review note](g01-runner-release-checkpoint.md#independent-review-of-the-go-1269-pin-commit) + covered the pin commit plus one Profile A verbose scan only; it did + not repeat all seven source profiles or the full module/CI matrix. + No independent rerun of any kind is claimed by this inventory. +- Dated evidence commands issued under 1.26.8 at record time: the + [R1 2026-09-13 evidence section](../../experiments/r1-credentials/README.md#evidence-recorded-for-issue-67), + [G01 contract](g01-contract.md) (including historical + `govulncheck@v1.1.4`), [strict inventory](g01-strict-inventory.md), + [G02 offline packet](g02-offline-packet.md), + [worker harness](g01-worker-harness.md), handoffs, and paired and + live-safety followups. Historical; not current instructions. +- Matcher provenance: the [adaptation notice](../third-party/go-testing-matcher.md) + records `splitSelector`, `rewrite`, and `isSpace` as adapted from the + Go 1.26.8 `src/testing/match.go` source, with the Go license text + reproduced verbatim. Preserved as provenance truth, not a toolchain + pin to bump. + +## Packet execution recipes: inert, requalification remaining + +- The [recovery packet](g01-recovery-packet.md) embeds + `reviewed_toolchain = "go1.26.8"` and 171 `go1.26.8` recipe lines + (`rg -c`; lines counted, not expanded here). Inert text only: never + executed, compiled, evaluated, or imported for this inventory. +- The [live-canary checklist](g01-live-canary.md#required-environment-and-authorization-record) + states those embedded 1.26.8 commands remain inert + historical/specimen text rather than current execution instructions, + superseded by the Go 1.26.9 checklist pin. +- Remaining: packet recipe requalification under separate authorized + ownership. No packet fix in this inventory; historical packet text + unaltered. No exhaustive packet AST was performed. + +## Static evidence (actual commands, sanitized) + +| Command | Exit | Result | +| --- | --- | --- | +| `git rev-parse HEAD` | 0 | `9776562fc792e0fb76684fb7be90a7ed118ed0ec` | +| `git status --short` | 0 | Empty at run start; only this new file added by this task (a co-worker's separate new file is preserved untouched) | +| `rg -n "^go 1\." go.mod experiments/*/go.mod` | 0 | Four `go 1.26.9` directives | +| Pin sweep over `Makefile` and `scripts/` plus `compare-sdk.sh` | 0 | Every exact/expected toolchain anchor is `go1.26.9` | +| Pin sweep over `.github/workflows/ci.yml` and `pr-fast.yml` | 0 | Five `GOTOOLCHAIN: go1.26.9` anchors, `go-version-file: go.mod`, immutable checkout/setup-go SHAs | +| `rg` over live/worker `main.go`, `broker_process.go`, `broker_paired_prep_test.go` | 0 | All BuildInfo/fixture gates require `go1.26.9` | +| `rg` for `GOVULNCHECK_VERSION` and `govulncheck@` | 0 | `v1.7.0` in `Makefile`, script default, `DEPENDENCIES.md`, `CI.md` | +| `rg -n "^toolchain "` over four `go.mod` files | 1 | No matches; no redundant directive | +| `rg -n "1\.26\.8"` over twelve active pin files | 1 | No matches; no stale ACTIVE pin | +| `rg -n "go1\.26\.8"` over five test files | 0 | Five intentional reject fixtures listed above | +| `rg -c "go1\.26\.8" docs/evidence/g01-recovery-packet.md` | 0 | `171` (inert count only; not executed) | +| `ls go.sum experiments/*/go.sum` | — | Only `experiments/g01-scaleset/go.sum` exists | +| `git show --oneline -s HEAD` | 0 | `9776562 Clarify Go 1.26.9 red evidence and review` | + +No dynamic tests, scans, builds, packet operations, independent review, +or live operations were run for this inventory. + +## Remaining gaps + +Packet recipe requalification is outstanding. Full G01/G02, +live-authorization, safe-drain, and tenant/archive/image qualification +gates remain open. No G01 closure is claimed. From 0d308ece6583304406645e97c7fda018c8ffef19 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Wed, 14 Oct 2026 00:20:10 +0900 Subject: [PATCH 11/16] docs: record Sol offline module security scans --- .../go1269-offline-module-security.md | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 docs/evidence/go1269-offline-module-security.md diff --git a/docs/evidence/go1269-offline-module-security.md b/docs/evidence/go1269-offline-module-security.md new file mode 100644 index 00000000..d3bad61e --- /dev/null +++ b/docs/evidence/go1269-offline-module-security.md @@ -0,0 +1,138 @@ +# Go 1.26.9 supplemental offline-module security evidence + +Three sequential source-mode analyses completed on 2026-10-13 UTC with +`govulncheck@v1.7.0`, Go `1.26.9`, and test source included. Each text-mode +invocation exited 0, printed `No vulnerabilities found.`, and reported no finding +IDs or scanner/package-loading/database errors. This supplements the +[prior seven-profile G01 record](g01-runner-release-checkpoint.md#go-1269-remediation-and-source-re-verification); +those seven profiles were not repeated. This is local evidence, not G01 closure. +Writer: Codex, GPT-6.1 Sol with medium reasoning, selected by the current user +override. Independent and GitHub review were not requested for this local work. + +## Immutable source identity + +The source HEAD was `9776562fc792e0fb76684fb7be90a7ed118ed0ec`, with repository +tree `5ded54289aba0b1e98c9eab99730c10b4d289478`. Before and after the batch, +`git diff --quiet HEAD -- go.mod scripts internal experiments/g02-auth +experiments/r1-credentials` exited 0, and `git ls-files --others +--exclude-standard` found no untracked files. Source files were therefore the +committed files, before this evidence document was added. + +| Module directory | Immutable tree/blob identity | +|---|---| +| Root (`.`) | Repository tree above; `go.mod` blob `34d287c65da1a4ae10fffddfa62ae37a622686ac`, `scripts` tree `e8f3bd9eebb9dad41af297e5080014a3442dacd3`, `internal` tree `1f937c6d8d78558e5ecd014eaf1190d32a011368` | +| `experiments/g02-auth` | Tree `4526e7951921658b5b0fc13979e488667cc0d98b` | +| `experiments/r1-credentials` | Tree `74743be69ce087c7c3e7c4167de4ccc41f27cd8a` | + +Each module declares Go `1.26.9` and has no required external modules. Root +`./...` does not traverse nested modules; the two experiment modules received +their own invocations. The default G02 selection includes native cgo account +lookup and excludes the `g02runtime`-tagged Keychain probe. No extra build tags +were supplied for any module. + +## Tool and environment identity + +The installed cached Darwin/ARM64 toolchain was compared to public +`sum.golang.org/lookup` record `67208878`: + +- `golang.org/toolchain@v0.0.1-go1.26.9.darwin-arm64`: + `h1:u1IV5D8HPeURJjWAqzcC8QRXDJqvXlh7FpsA4lGIg1c=`. +- Its module-file checksum: + `h1:8wlg68NqwW7eMnI1aABk/C2pDYXj8mrMY4TyRfiLeS0=`. + +Scanner public checksum record `59745603` contained: + +- `golang.org/x/vuln@v1.7.0`: + `h1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=`. +- Its module-file checksum: + `h1:Xw7zvU3e1bsCYYBXu+w4wcn2Kgn27f34WBCTw8LL5Us=`. + +A fresh Python preflight implemented the inspected `x/mod/sumdb/dirhash.Hash1` +algorithm over each cached ZIP and matched the public module checksum. It also +compared every unpacked archive file byte-for-byte, with no missing or changed +archive files. The scanner directory had no extras. The toolchain directory had +20 extra `go.mod` files, each identical to its adjacent archived `_go.mod`, as +generated by the trusted Go toolchain selector. The first naive directory-hash +preflight exited 1 because it included those generated copies; the corrected +archive-and-copy verification succeeded. No packet recipe or specimen was +executed, compiled, evaluated, or imported. + +`go version` and `go env GOROOT GOVERSION CGO_ENABLED GOOS GOARCH GOARM64 CC CXX` +both exited 0 and confirmed exact Go `1.26.9`, default-derived cached GOROOT, +Darwin/ARM64 `v8.0`, and cgo enabled. Explicit `CC`/`CXX` selected the Xcode +toolchain's `clang`/`clang++`; `clang --version` exited 0 and reported Apple +Clang `21.0.0` (`clang-2100.3.34.2`). + +`go install golang.org/x/vuln/cmd/govulncheck@v1.7.0` initially exited 1 +in 0.010 s because the checksum client could not locate its state with neither +`HOME` nor `GOPATH` set. Adding an explicit existing `GOPATH` corrected that +environment boundary; installation then exited 0 in 2.123 s. The scanner was +installed in an owned mode-0700 temporary directory and removed automatically +at the end. No analysis was retried. + +`go version -m ` exited 0 and confirmed path +`golang.org/x/vuln/cmd/govulncheck`, module `v1.7.0` with the checksum above, +and build identity `go1.26.9-X:nogreenteagc,norandomizedheapbase64`, +`-buildmode=exe`, `-compiler=gc`, `CGO_ENABLED=1`, `GOEXPERIMENT=none`, +`GOOS=darwin`, `GOARCH=arm64`, `GOARM64=v8.0`, and empty cgo flags. +Its `DefaultGODEBUG` was +`cryptocustomrand=1,httpservecontentmaxranges=1,tlssecpmlkem=0,urlstrictcolons=0`. +Binary SHA-256 was +`d0f052d5972dfc295b2c73cdface54c2f36806aa635732a6190eb858e20228b9`. +`govulncheck -version` exited 0, reporting Go `go1.26.9`, scanner `v1.7.0`, +database `https://vuln.go.dev`, and DB updated `2026-10-08T22:31:09Z`. + +Every Go/scanner child received a fresh allowlisted environment: exact cached +Go `1.26.9` first on `PATH`, followed by `/usr/bin:/bin`; +`GOTOOLCHAIN=go1.26.9`, `GOENV=off`, `GOWORK=off`, +`GOFLAGS=-mod=readonly -p=2`, `GOAUTH=off`, `GOEXPERIMENT=none`, +`GOFIPS140=off`, `GOMAXPROCS=2`, `GOOS=darwin`, `GOARCH=arm64`, +`GOARM64=v8.0`, `CGO_ENABLED=1`, and the explicit trusted `CC`/`CXX` above. +`GOPROXY=https://proxy.golang.org` had no direct fallback; +`GOSUMDB=sum.golang.org`; `GOPRIVATE`, `GONOPROXY`, and `GONOSUMDB` were empty. +Existing `GOPATH`, module cache and build cache were explicitly selected; +`TMPDIR` was the private temporary directory; `GOTELEMETRY=off`. +`GOBIN` was supplied only during scanner installation. No `HOME`, credentials, +Git/SSH tokens, credential proxies, overlays, `GOCACHEPROG`, ambient compiler +flags, or `GOROOT` override were inherited. + +## Actual analyses + +The exact command in each module directory was: +`govulncheck -mode=source -format=text -db=https://vuln.go.dev -test ./...`. +Each direct child had a 900-second subprocess deadline. Text-mode exit 3 would +indicate findings; an error or timeout would not pass. No JSON-mode exit was +used as a success criterion. + +| Module | UTC start | UTC end | Duration | Exit / finding IDs | +|---|---|---|---:|---| +| Root | 2026-10-13T15:16:18.824618Z | 2026-10-13T15:16:19.707203Z | 0.882 s | 0 / none | +| G02 auth | 2026-10-13T15:16:19.707263Z | 2026-10-13T15:16:21.343202Z | 1.636 s | 0 / none | +| R1 credentials | 2026-10-13T15:16:21.343231Z | 2026-10-13T15:16:22.480574Z | 1.137 s | 0 / none | + +A separate post-batch database index GET returned body +`modified=2026-10-08T22:31:09Z`, ETag `8875c8c67555e9c875a431c63837b83d`, +Last-Modified `2026-10-13T10:17:48Z`, HTTP Date `2026-10-13T14:30:44Z`, and +`Cache-Control: public, max-age=3600`. These cached mutable response fields are +not scan timestamps, an immutable database snapshot, or proof that every +invocation used identical database bytes. + +## Limits and remaining gates + +`-test` loaded test source for static analysis; no tests or fixtures ran. Source +analysis may compile/load export data, and the trusted scanner was compiled and +executed. No application or test binary was launched, no `go test` command was +run, and the full matrix was not repeated. Known-vulnerability results are +limited to the selected source profiles and database knowledge; they do not +prove exploitability or absence of unknown vulnerabilities, reflection/unsafe +paths, other tags/platforms, or runtime/image vulnerabilities. + +No code, pins, checksum files, Git index, commits, GitHub state, Docker settings, +credentials, or live runners changed. G01/G02 dependency, authorization, +live-safety and qualification gates remain open. This document received local +evidence checks only; no independent or GitHub review is claimed. + +Local document validation checked the relative link and heading fragment, +secret/private-path patterns, and three-result timestamp structure successfully. +The scoped source diff still exited 0 after drafting; no artificial Go test was +added for this documentation-only evidence change. From 02fbe7064dffef603c718391eebb0e441efd93e7 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Wed, 14 Oct 2026 00:36:03 +0900 Subject: [PATCH 12/16] docs: split remaining Project work into bounded waves --- docs/handoffs/2026-10-14-parallel-dispatch.md | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/handoffs/2026-10-14-parallel-dispatch.md diff --git a/docs/handoffs/2026-10-14-parallel-dispatch.md b/docs/handoffs/2026-10-14-parallel-dispatch.md new file mode 100644 index 00000000..5eeb29f7 --- /dev/null +++ b/docs/handoffs/2026-10-14-parallel-dispatch.md @@ -0,0 +1,85 @@ +# Remaining Project work: bounded parallel dispatch + +Planning checkpoint: 2026-10-14 Asia/Seoul. The live +[GitHub Project](https://github.com/orgs/1XP-AI/projects/2) has 44 cards: +20 Done, 3 In progress, 17 Backlog, 3 Blocked, and 1 Future. The remaining +24 cards are not 24 completed implementations. There are no Ready cards in +this snapshot. This plan neither changes the board nor dispatches gated work. + +## Current execution choice + +- Cursor Agent: Muse Spark 1.3 Max. +- Codex: GPT-6.1 Sol, medium reasoning; do not reuse Luna Max for new work. +- At most two active workers. One issue per branch/worktree. Reuse suitable + existing checkouts; create another only for an eligible distinct issue. +- Local implementation, relevant red/green checks, and coherent commits only. + Independent review and GitHub review are deferred by current user choice. + No push, PR creation, merge, issue closure, or live operation is implied. +- The coordinator owns shared interfaces and integration. No concurrent + changes to common configuration, protocol/state types, or the Git index. +- Deferred reviews are not passing reviews. Local completion does not satisfy + an issue's remaining merge, qualification, or live evidence criteria. + +## Wave and ownership map + +The owner column is a proposed allocation, not an active agent or completion +claim. Before each dispatch, read that issue's current acceptance contract and +Project status; dependencies must be Done. Path boundaries are assigned then, +not invented here as already implemented features. + +| Wave / lane | Issues | Proposed owner | Scope boundary / entry condition | +|---|---|---|---| +| Gate A | #1 G01, #79 supporting evidence | Codex Sol medium, one at a time | Scale Set delivery/acquisition/JIT/drain evidence. Preserve the two existing local branches; no repeated unchanged checks or specimen execution. Full G01 remains open. | +| Gate B | #2 G02, #67 R1 credentials | Muse Max, one at a time | Enrollment, credential/service identity, and foreground credential evidence. #67 does not complete #2. Keep credential work separate from Gate A's protocol files. | +| 1: contracts | #4 G04 | Codex Sol medium | Requires #1/#2/#3 Done. Freeze configuration/provider/ownership/scaling contracts before parallel consumers; coordinator owns shared interfaces. | +| R1 lane | #68 foreground lifecycle -> #69 qualification | Muse Max, serial | #68 requires #60/#66/#67 and full #1/#2 before production implementation. Its isolated contract/offline scope is not production authorization. #69 requires #1/#68; real-job evidence needs concrete authorization. | +| 2: state | #5 G05 | Codex Sol medium | Requires #3/#4. Durable state and operation journal; owns persistence interfaces. | +| 2: scaling | #12 G12 | Muse Max | Requires #4/#5. Pure deterministic proposals, not live reservations. Existing completed #40 arithmetic is reused, not reimplemented. Can run beside #6 after #5 settles. | +| 3: daemon | #6 G06 | Codex Sol medium | Requires #5. Supervision and authorized local IPC; owns daemon/IPC surface. | +| 3: credentials | #7 G07 | Muse Max | Requires #2/#5. Credential and installation-binding implementation; separate from daemon/IPC files. Queue after #12 if the two-worker cap is reached. | +| 4: providers / enrollment | #8 G08, #9 G09, #10 G10, #11 G11 | Codex: #9/#11; Muse: #8/#10 | Queue pairs, never four workers. #8 needs #6/#7; #9 needs #1/#5/#7; #10 needs #4/#5/#7; #11 needs #2/#4/#5/#7. Each issue owns its adapter/enrollment files, not shared contract definitions. | +| 5: integration | #13 G13 | Codex Sol medium | Requires #6/#9/#10/#11/#12. One integrator for reconciliation, drain, restart and atomic admission. | +| 6: diagnostics | #14 G14 | Muse Max | Requires #6/#13. Sanitized status/logs/diagnostics, separate from service lifecycle. | +| 6: service / trust | #15 G15, #19 G19 | Codex Sol medium, serial | #15 needs #2/#6/#13; #19 needs #8/#10/#11/#13. Service/startup and trust-boundary work do not authorize installing services or changing host identities. | +| 7: runtime qualification | #16 G16 | Codex Sol medium | Requires #8/#13/#14/#15. Two-organization runtime evidence; concrete trusted environment and maintainer authorization required. | +| 8: reliability | #17 G17 | Codex Sol medium | Requires #16/#19. Recovery, soak and resource budgets; actual authorized evidence, not planned passes. | +| 9: release | #18 G18 | Muse Max | Requires #3/#15/#17. Reproducible packaging/signing/distribution; no publication without authorization. | +| 10: migration | #20 G20 | Codex Sol medium | Requires #17/#18. Reversible legacy-runner handoff; preserve manually installed runners. | +| Future | #21 G21 | Not dispatched | Requires #17 and remains Future. Optional VM/multi-host research is not part of current production implementation. | + +All 24 unfinished cards appear exactly once. The R1 lane is a separate delivery +lane, not a bypass of the full G01/G02 gates. The nominal wave numbers do not +override the dependency column; in particular #12 starts only after #5. + +## Immediate boundary: what actually unlocks implementation + +Gate A: G01 still lacks the authorized product canary and its real server-side +recovery/drain observations. See the +[canary authority checklist](../evidence/g01-live-canary.md#required-environment-and-authorization-record). +Its local offline evidence and Go remediation do not authorize registering +resources, issuing JIT, dispatching jobs, fault injection, or cleanup. +The #79 local evidence-hardening branch is preserved; remote closure/merge is +not part of the current local-only workflow. + +Gate B: G02 already records a disposable enrollment/manual recovery and bounded +source-build/same-account platform observations. Do not repeat those as though +they were never collected. The +[G02 readiness packet](../evidence/g02-mac-live-readiness.md#acceptance-status) +distinguishes those results from remaining service identity/support and +qualification boundaries; its retired execution procedure must not be run. +The [R1 foreground evidence](../evidence/g02-r1-foreground.md) is offline evidence, +not #67's authorized real manual-credential result or full G02 completion. + +Concrete live targets, resource limits, phases and ownership must be authorized +separately. Do not request secret values in chat. Until the relevant evidence +and dependencies are satisfied and the live Project permits dispatch, later +waves are queued plans, not background implementations. + +## Exit accounting + +Record per issue: changed files, actual red/green and focused checks, local +commit, remaining criteria, and worktree cleanup decision. A finished local +unit can be committed while the parent issue stays open. Clean up only fully +finished, inactive, recoverable worktrees; preserve unpushed work and uncertain +ownership. This planning change has no application behavior change and needs +no artificial Go test or additional review loop. From eb26f182fc0bcaeaf79fff18c5756a78dba7e0c3 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Thu, 15 Oct 2026 15:24:32 +0900 Subject: [PATCH 13/16] docs(g01): record Go 1.26.9 offline runtime diagnostics --- .../evidence/g01-runner-release-checkpoint.md | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 938d445e..03370563 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -506,3 +506,103 @@ above. It did not independently repeat all seven source profiles or the full module/CI matrix, qualify live behavior, or perform GitHub PR review. Those gates remain open. The documentation correction in this follow-up has not received an exact-head review; no new-head review approval is claimed. + +### Go 1.26.9 offline runtime follow-up — 2026-10-15 + +Local source at the start of this follow-up was +`02fbe7064dffef603c718391eebb0e441efd93e7`. The G01 module tree remained +`da98e542ea2a8066a3af664a4b5d3f7bdf655ebb`, the G02 module tree remained +`4526e7951921658b5b0fc13979e488667cc0d98b`, and the offline checker blob was +`f3c508365f1044dc36fcc625f593556c907a950a`. No source, dependency, or timeout +policy changed for these observations. The earlier seven-profile source scans +were reused by those source identities rather than repeated. + +The default local module cache initially lacked Go 1.26.9 and the pinned SDK +dependencies. Go 1.26.9 was obtained through the official module proxy with +`GOSUMDB=sum.golang.org`; `go version` reported `go1.26.9 darwin/arm64`. +The first offline checker attempt reported `module lookup disabled by +GOPROXY=off` and exited 1 after remaining compilation finished. It was a setup +failure, not TDD RED or a test pass. A separate `go mod download` in the G01 +module used the official proxy and checksum database and exited 0; the worktree +and checksum pins remained unchanged. + +Subsequent tests used an allowlisted environment: exact Go 1.26.9 first on PATH, +explicit module/build caches, `GOENV=off`, `GOWORK=off`, +`GOFLAGS=-mod=readonly -p=2`, `GOMAXPROCS=2`, `CGO_ENABLED=1`, `GOAUTH=off`, +`GOEXPERIMENT=none`, `GOFIPS140=off`, `GOPROXY=off`, `GOSUMDB=off`, and C +locales. No HOME, credentials, ambient Go configuration, or proxy settings were +forwarded. Dependency acquisition above preceded these offline tests. + +The repository-root invocation was: + +```text +OFFLINE_EXPERIMENT_MODULE=experiments/g01-scaleset bash scripts/check-offline-experiments.sh +``` + +With dependencies available, it still exited 1: its first partition timed out +after 45 seconds in `TestBaselineStatisticsPresenceAndEligibility`, while the +`nested/totalAcquiredJobs/null` case was establishing a fixture-only TLS +connection. The package reported 47.511 seconds. No later checker partition ran +in that invocation. The machine had severe concurrent load during this batch; +the following diagnostic results are consistent with aggregate execution-time +pressure, but do not establish that the original gate passed. + +From `experiments/g01-scaleset`, these diagnostic commands were actually run: + +```text +go test -race -count=1 -timeout=45s -run '^TestBaselineStatisticsPresenceAndEligibility$/^nested$/^totalAcquiredJobs$/^null$' ./livecanary +go test -race -count=1 -timeout=45s -run '^TestBaselineStatisticsPresenceAndEligibility$/^set$' ./livecanary +go test -race -count=1 -timeout=45s -run '^TestBaselineStatisticsPresenceAndEligibility$/^session$' ./livecanary +go test -race -count=1 -timeout=45s -run '^TestBaselineStatisticsPresenceAndEligibility$/^nested$' ./livecanary +go test -race -count=1 -timeout=45s -run '^TestBaselineStatisticsPresenceAndEligibility$/^poll1$' ./livecanary +go test -race -count=1 -timeout=45s -run '^TestBaselineStatisticsPresenceAndEligibility$/^poll2$' ./livecanary +go test -race -count=1 -timeout=120s -run '^TestBaselineStatisticsPresenceAndEligibility$/^poll2$' ./livecanary +``` + +| Diagnostic selection | Timeout | Exit | Package duration / result | +| --- | --- | --- | --- | +| Isolated `nested/totalAcquiredJobs/null` | 45 s | 0 | 7.398 s | +| `set` | 45 s | 0 | 18.160 s | +| `session` | 45 s | 0 | 23.673 s | +| `nested` | 45 s | 0 | 14.788 s | +| `poll1` | 45 s | 0 | 26.019 s | +| `poll2`, first attempt | 45 s | 1 | 46.303 s; timeout during `totalIdleRunners/null` | +| `poll2`, bounded diagnostic retry | 120 s | 0 | 56.916 s | + +The five successful stage selections cover all 166 subcases generated by the +current test: 35 set, 35 session, 33 nested, 35 poll1, and 28 poll2 cases, +including the six whole-statistics missing/null cases. The 120-second diagnostic +is not a replacement for the unchanged 45-second repository gate. Neither +timeout is presented as a passing run. Test recipes in the recovery packet were +not executed; these commands ran the inspected, fixture-backed Go test sources. + +The next partition was run separately after the statistics diagnostics: + +```text +go test -race -count=1 -timeout=45s -run '^TestControllerHandoff' ./... +``` + +It exited 1. The livecanary package reported 24.609 seconds, with +`TestControllerHandoffJournalFailuresDenyBeforeReader/baseline_mode` failing +during fixture preparation: `prepare baseline-mode journal: state uncertain; +quarantine and inspect only`. That subcase took 5.74 seconds; its fixture's +`run` method has a five-second context deadline. The timing is consistent with +the resource-pressure hypothesis, but the failure alone does not prove its +cause. The default remainder, tagged commands, paired fixture partitions, and +vet steps queued after it did not run as part of that continuation because it +stopped on this failure. + +The isolated diagnostic retry +`go test -race -count=1 -timeout=45s -run '^TestControllerHandoffJournalFailuresDenyBeforeReader$/^baseline_mode$' ./livecanary` +exited 0 in 9.424 seconds without changing source or fixture deadlines. The +failure did not reproduce in isolation. This does not certify the full handoff +partition, prove the resource-pressure hypothesis, or exclude an intermittent +code defect. + +The remaining offline partitions require their own recorded results. This +follow-up does not claim full-module verification, independent review, hosted +CI, live qualification, or G01 completion. The live Project was read through +`gh`: G01 and G02 were In progress, and supporting #79 was In review. No remote +status or resource was changed. This evidence-only addition has no behavior +change and needs no artificial RED test; rollback is reverting its local +documentation commit. From 9ec45d128e766326fa6c3faeffd9be51cbcddc9a Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Thu, 15 Oct 2026 15:27:03 +0900 Subject: [PATCH 14/16] docs(g01): record Go 1.26.9 static vet results --- docs/evidence/g01-runner-release-checkpoint.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 03370563..71397ceb 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -606,3 +606,17 @@ CI, live qualification, or G01 completion. The live Project was read through status or resource was changed. This evidence-only addition has no behavior change and needs no artificial RED test; rollback is reverting its local documentation commit. + +#### Static compilation follow-up + +Using the same offline Go 1.26.9 environment, the following three static +checks each exited 0 with no diagnostics: + +```text +go vet ./... +go vet -tags=g01_live,g01_worker ./cmd/g01-live ./cmd/g01-worker +go vet -tags=g01_pair_fixture ./livecanary +``` + +These inspect the default, tagged command, and paired fixture sources. They +do not turn the timed-out runtime partitions into passing tests. From 122969078ef1ba6422f6aa24bf92c93e99e8a850 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Thu, 22 Oct 2026 17:53:50 +0900 Subject: [PATCH 15/16] docs(g01): record complete Go 1.26.9 offline check --- .../evidence/g01-runner-release-checkpoint.md | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/evidence/g01-runner-release-checkpoint.md b/docs/evidence/g01-runner-release-checkpoint.md index 71397ceb..c6d289f2 100644 --- a/docs/evidence/g01-runner-release-checkpoint.md +++ b/docs/evidence/g01-runner-release-checkpoint.md @@ -620,3 +620,50 @@ go vet -tags=g01_pair_fixture ./livecanary These inspect the default, tagged command, and paired fixture sources. They do not turn the timed-out runtime partitions into passing tests. + +### Go 1.26.9 complete G01 offline check — 2026-10-22 + +The existing checker completed successfully on local head +`9ec45d128e766326fa6c3faeffd9be51cbcddc9a`: exit 0 and +`offline experiment checks passed: 1 module(s)`. The G01 source tree was still +`da98e542ea2a8066a3af664a4b5d3f7bdf655ebb`, and the checker blob was still +`f3c508365f1044dc36fcc625f593556c907a950a`. This rerun addressed the unresolved +October 15 failures after observed machine load had fallen substantially. +No code, test selection, fixture deadline, or checker timeout was changed. + +The command ran from the repository root, using the same allowlisted offline +environment documented above and the verified `go1.26.9 darwin/arm64` toolchain: + +```text +OFFLINE_EXPERIMENT_MODULE=experiments/g01-scaleset bash scripts/check-offline-experiments.sh +``` + +All nine race-test partitions used `-count=1` and passed: + +| Checker partition | Timeout | Reported package duration(s) | +| --- | --- | --- | +| Baseline statistics | 45 s | livecanary 15.391 s | +| Controller handoff | 45 s | livecanary 3.705 s | +| Default remainder, including examples and fuzz seeds | 45 s | root 1.206 s; livecanary 33.173 s; liveworker 9.432 s | +| Tagged command fixtures (`g01_live,g01_worker`) | 45 s | g01-live 4.849 s; g01-worker 1.361 s | +| Paired non-terminal collection (`g01_pair_fixture`) | 120 s | livecanary 76.259 s | +| Non-paired complement (`g01_pair_fixture`) | 120 s | livecanary 57.553 s | +| Paired terminal heavy families | 120 s | livecanary 115.716 s | +| Paired terminal remainder | 120 s | livecanary 34.238 s | +| Paired terminal storage failures | 120 s | livecanary 95.893 s | + +The baseline and handoff selectors also retained `./...` package discovery; +the root and liveworker packages reported no matching tests for those two +selectors. Default, tagged-command, and paired-fixture `go vet` checks all +completed without diagnostics. The success marker follows all test and vet +commands in the inspected `set -euo pipefail` checker. + +This closes the recorded G01-module offline rerun gap for these source and +toolchain identities. The earlier failures remain historical observations; +this result does not prove that resource pressure was their only possible +cause. It is not the complete root/G02/R1 matrix, an SDK-version comparison +rerun, a recovery-packet recipe execution, or live server evidence. G01 was +still OPEN and In progress when checked through `gh`; #79 was In review. +The live canary, remaining review/merge criteria, and production G01/G02 gates +remain unresolved. No GitHub write or live operation occurred. This is an +evidence-only addition; rollback is reverting its local documentation commit. From 4ba3a1b0d8264c2b50c3eb0e8d5570e3b1663a78 Mon Sep 17 00:00:00 2001 From: JinWoo Lee Date: Thu, 22 Oct 2026 18:30:44 +0900 Subject: [PATCH 16/16] docs(g01): record resumed review workflow and canary readiness gaps --- docs/evidence/g01-live-canary.md | 30 +++++++++++++++++++ docs/handoffs/2026-10-14-parallel-dispatch.md | 13 ++++++++ 2 files changed, 43 insertions(+) diff --git a/docs/evidence/g01-live-canary.md b/docs/evidence/g01-live-canary.md index 14e2a822..bd03c24e 100644 --- a/docs/evidence/g01-live-canary.md +++ b/docs/evidence/g01-live-canary.md @@ -35,6 +35,36 @@ digest; the checkpoint is source/metadata evidence only and authorizes no swap. ## Required environment and authorization record +### Read-only preparation checkpoint — 2026-10-22 + +The maintainer authorized preparation, not execution. A dedicated private, +non-archived repository was located through `gh`; its name and local endpoint +remain in the private approval conversation, not this public record. Its current +workflow is manual-only, has empty token permissions, one ten-minute job and +non-cancelling concurrency. However, it targets macOS ARM64 with a fixed label +and prints the runner name. It is **not** the nonce-scoped Linux workload in +`experiments/g01-canary-assets`, and is not approved for this experiment. + +The preparation host is macOS ARM64 and has a configured Docker Desktop Linux +context. Only local context metadata was inspected: daemon availability, worker +isolation and resources have not been verified. No context was switched, image +pulled, container started or runner changed. Approximately 7.5 GiB free disk was +observed, so runtime preparation must wait for adequate measured headroom. +The proposed first scope is one disposable Linux ARM64 worker (1 vCPU / 1 GiB), +one controller/session/scale set and one baseline job, with no host socket or +controller mounts in the worker. No current native runner is a fallback target. + +The organization runner-group metadata request returned HTTP 403. Selected-only +repository policy, group identity and existing-runner inventory therefore remain +unverified; no authentication scopes or App permissions were changed. A reviewed +nonce-bound workflow commit, immutable executor/runtime inputs, separate +controller/broker identities, authenticated provenance/trust roots and supported +conditional cleanup are still required. A configured context or a successful +source review cannot clear these live gates. Later fault phases need their own +explicit approval; do not dispatch even the baseline from this checkpoint. + +### Execution checklist + - [ ] Maintainer identifies one disposable **private** repository and one organization; no public fork/PR execution. Record the reviewed workflow SHA. - [ ] Dedicated runner group allows only that repository, and a unique canary diff --git a/docs/handoffs/2026-10-14-parallel-dispatch.md b/docs/handoffs/2026-10-14-parallel-dispatch.md index 5eeb29f7..253a3ecf 100644 --- a/docs/handoffs/2026-10-14-parallel-dispatch.md +++ b/docs/handoffs/2026-10-14-parallel-dispatch.md @@ -8,6 +8,19 @@ this snapshot. This plan neither changes the board nor dispatches gated work. ## Current execution choice +### 2026-10-22 authorization update + +The maintainer resumed push, PR creation, independent/GitHub review and merge. +This supersedes the local-only/review-deferral bullets below, which describe the +October 14 checkpoint. Exact-head review, finding triage and PR quick checks +remain mandatory. The explicit Codex Sol medium model choice is unchanged. +The coordinator owns GitHub writes and integration; delegated fixes stay local +until a stable batch is reviewed. Canary preparation is authorized, but actual +live execution still requires separate concrete approval. Keep G01 open and do +not dispatch dependent production implementation from this permission change. + +### October 14 checkpoint + - Cursor Agent: Muse Spark 1.3 Max. - Codex: GPT-6.1 Sol, medium reasoning; do not reuse Luna Max for new work. - At most two active workers. One issue per branch/worktree. Reuse suitable