v1.91.25.0 feat(cso): private two-architecture release scoring + self-checking runtime release gates (#3036)

* v1.91.23.0 feat(cso): private two-architecture release scoring and self-checking runtime release gates

* Keep the Linux-only native-evidence and requalification tests out of the Windows lane

* Skip the two Linux-release-only checks on Windows in-file instead of growing the shard list

* fix(cso): opaque producer inputs and receipts; requalification triggers independent of cwd

Producer inputs are {schemaVersion: 2, cellRef, skill, source, execution} and
receipts bind cellRef + inputHash; collection rebuilds the cell from the
matrix, so a cell VM never learns its case or variant. requalificationTriggers
resolves Bun's cwd-relative metafile inputs against the repository root.

* test(evals): bound the review judge's thinking; guarded browser cleanup is not a probe

review/SKILL.md workflow: the ~64k-token bundle let default-effort thinking
spend all 8192 output tokens without an answer in CI. Medium effort with a
64k streaming cap kept 24/24 measured samples under 5k tokens and 63 s with
the same gating scores (as ship already does).

qa-only-no-fix: the fixture prompt routes browser cleanup through the deadline
guard, but the checkpoint detector treated every guarded run as a probe that
needs a checkpoint. A child that only closes the tab with the supplied browse
binary, after the last probe, is cleanup; anything else stays a probe. The
captured CI transcript (run 37252022510) now passes and new scenarios pin
the negative controls.

* test(evals): keep the review judge at default effort; only lift its output cap

Truncation was the defect: thinking and the answer share max_tokens, and the
~64k-token review bundle once spent all 8192. The registration keeps default
effort and response format and gets ship's 64k streaming cap; the guard test
pins exactly that.
This commit is contained in:
Garry Tan authored and GitHub committed 2026-10-04 21:47:21 -07:00
1 parent 55fbe77195
commit 857466ff8b
39 files changed
+2465 -280

No files matched your search

+19 -18
View File
@@ -12,6 +12,7 @@ on:
- 'scripts/cso-image-matrix.ts'
- 'scripts/cso-verify-runtime-base.ts'
- 'scripts/cso-runtime-promotion.ts'
- 'scripts/cso-requalification.ts'
- 'scripts/cso-public-ghcr.ts'
- 'test/cso-*.test.ts'
workflow_dispatch:
@@ -42,6 +43,15 @@ jobs:
set -eu
matrix="$(bun run scripts/cso-image-matrix.ts)"
printf 'matrix=%s\n' "$matrix" >> "$GITHUB_OUTPUT"
- name: Record the requalification trigger inputs of this source commit
run: bun run scripts/cso-requalification.ts triggers > requalification.json
- if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: cso-requalification-triggers
path: requalification.json
if-no-files-found: error
retention-days: 30
validate-native:
needs: reviewed-inputs
@@ -279,6 +289,7 @@ jobs:
retention-days: 30
qualify-native:
name: qualify-native ${{ matrix.runtimeId }}
needs: [reviewed-inputs, stage]
if: github.ref == 'refs/heads/main' && github.event_name == 'workflow_dispatch'
environment: cso-runtime-release
@@ -344,31 +355,21 @@ jobs:
set -eu
bun install --frozen-lockfile --ignore-scripts
bun run build:cso
bun run test:cso:docker
- name: Record native gate evidence without claiming runtime qualification
bun run test:cso:docker --reporter=junit --reporter-outfile=native-tests.junit.xml
- name: Derive native gate evidence from the executed test report
env:
CSO_STACK: ${{ matrix.stack }}
CSO_PLATFORM: ${{ matrix.platform }}
run: |
set -eu
jq --arg stack "$CSO_STACK" --arg platform "$CSO_PLATFORM" '
. + {
state:"native-gates-passed",
nativeChecks:(if $stack == "postgresql" then {
containmentPassed:true,coldStartPassed:true,multiDatabasePassed:true,readinessPassed:true
} else {
containmentPassed:true,coldStartPassed:true,positiveNegativeAssertionsPassed:true,
acquisitionPublicOnlyPassed:true,offlineLifecyclePassed:true
} + (if $stack == "rails" then {
railsSqlitePassed:true,railsPostgresqlPassed:true,nativeExtensionsPassed:true
} else {} end) end),
privateChecks:{heldOutRepairPassed:"pending",accuracyGatesPassed:"pending",secretCanaryPassed:"pending",watchdogCleanupPassed:"pending"},
qualified:false,
promotion:"prohibited until authenticated private qualification evidence completes every release gate"
}' staged-application/staged-image.json > qualification-evidence.json
bun run scripts/cso-native-evidence.ts --stack "$CSO_STACK" --platform "$CSO_PLATFORM" \
--junit native-tests.junit.xml --staged staged-application/staged-image.json \
--output qualification-evidence.json
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: cso-qualification-gates-${{ matrix.stack }}-${{ matrix.arch }}
path: qualification-evidence.json
path: |
qualification-evidence.json
native-tests.junit.xml
if-no-files-found: error
retention-days: 30
+5 -1
View File
@@ -3,6 +3,9 @@ name: Propose CSO Runtime Catalog Promotion
# This workflow never deploys a catalog. It converts authenticated
# same-repository qualification artifacts into an attested candidate, verifies
# those exact bytes, and opens a normal source-review PR from a protected job.
# Pushes and PRs made with GITHUB_TOKEN start no workflows, so the job
# dispatches the required free-tests check on the pushed branch head; a
# workflow_dispatch is the documented exception to that rule.
on:
workflow_dispatch:
inputs:
@@ -28,7 +31,7 @@ jobs:
permissions:
contents: write
pull-requests: write
actions: read
actions: write
packages: read
id-token: write
attestations: write
@@ -161,6 +164,7 @@ jobs:
cmp runtime-catalog.candidate.json committed-runtime-catalog.json
test "$expected_candidate_sha256" = "sha256:$(sha256sum committed-runtime-catalog.json | cut -d ' ' -f 1)"
git push --set-upstream origin "$branch"
gh workflow run free-tests.yml --repo "$GITHUB_REPOSITORY" --ref "$branch"
cat > pr-body.md <<EOF
Promotes the complete CSO runtime catalog from authenticated qualification run $CSO_QUALIFICATION_RUN. The protected promotion workflow verified the exact candidate attestation and committed those same bytes after a previous-revision compare-and-swap.
+63 -11
View File
@@ -1,8 +1,10 @@
name: CSO Runtime Qualification
# A private evaluator sends only gate results and public runtime identities.
# Its held-out assertions remain outside this repository. GitHub authenticates
# the dispatch actor; the protected environment supplies the human review gate.
# A private evaluator sends only gate results, public runtime identities, and an
# optional opaque evaluation reference. Its held-out assertions remain outside
# this repository. GitHub authenticates the dispatch actor; the protected
# environment supplies the human review gate. The unprotected summary job runs
# first so the reviewer sees what the dispatch claims before approving.
on:
repository_dispatch:
types: [cso-runtime-qualified]
@@ -13,7 +15,43 @@ permissions:
attestations: read
jobs:
dispatch-summary:
if: github.ref == 'refs/heads/main' && github.event_name == 'repository_dispatch'
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions: {}
steps:
- name: Require the bounded payload and summarize it for the approver
run: |
set -euo pipefail
jq -e '
.action == "cso-runtime-qualified" and
((.client_payload | keys) as $keys | $keys == ["statements"] or (
$keys == ["evaluationRef", "statements"] and
(.client_payload.evaluationRef | type == "string" and test("^sha256:[a-f0-9]{64}$"))
)) and
(.client_payload.statements | type == "array" and length == 10) and
(.client_payload.statements | all(
type == "object" and
(.runtimeId | type == "string" and test("^[a-z0-9][a-z0-9._-]{0,100}$")) and
(.image | type == "string" and test("^ghcr\\.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$")) and
(.sourceCommit | type == "string" and test("^[a-f0-9]{40}$"))
)) and
([.client_payload.statements[].sourceCommit] | unique | length == 1)
' "$GITHUB_EVENT_PATH"
jq -r '
"## CSO runtime qualification dispatch",
"",
"- evaluationRef: `\(.client_payload.evaluationRef // "none")`",
"- sourceCommit: `\(.client_payload.statements[0].sourceCommit)`",
"",
"| runtimeId | image |",
"| --- | --- |",
(.client_payload.statements[] | "| `\(.runtimeId)` | `\(.image)` |")
' "$GITHUB_EVENT_PATH" >> "$GITHUB_STEP_SUMMARY"
qualify:
needs: dispatch-summary
if: github.ref == 'refs/heads/main' && github.event_name == 'repository_dispatch'
runs-on: ubuntu-24.04
timeout-minutes: 40
@@ -22,6 +60,7 @@ jobs:
contents: read
packages: read
attestations: read
actions: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
@@ -29,18 +68,13 @@ jobs:
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: 1.4.0
- name: Require the configured private-evaluator actor and bounded matrix
- name: Require the configured private-evaluator actor
env:
CSO_QUALIFICATION_ACTOR: ${{ vars.CSO_QUALIFICATION_ACTOR }}
run: |
set -euo pipefail
test -n "$CSO_QUALIFICATION_ACTOR"
test "$GITHUB_ACTOR" = "$CSO_QUALIFICATION_ACTOR"
jq -e '
.action == "cso-runtime-qualified" and
(.client_payload | keys == ["statements"]) and
(.client_payload.statements | type == "array" and length == 10)
' "$GITHUB_EVENT_PATH"
- name: Recheck public visibility and anonymous pulls for every qualified digest
env:
GH_TOKEN: ${{ github.token }}
@@ -49,7 +83,7 @@ jobs:
mkdir public-image-evidence
jq -c '.client_payload.statements[]' "$GITHUB_EVENT_PATH" | while IFS= read -r statement; do
runtime_id="$(printf '%s' "$statement" | jq -er '.runtimeId | select(test("^[a-z0-9][a-z0-9._-]{0,100}$"))')"
image="$(printf '%s' "$statement" | jq -er '.image | select(test("^ghcr.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$"))')"
image="$(printf '%s' "$statement" | jq -er '.image | select(test("^ghcr\\.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$"))')"
platform="$(printf '%s' "$statement" | jq -er '.platform | select(. == "linux/amd64" or . == "linux/arm64")')"
bun run scripts/cso-public-ghcr.ts verify \
--image "$image" --platform "$platform" --repository "$GITHUB_REPOSITORY" \
@@ -66,7 +100,7 @@ jobs:
mkdir qualification-evidence
jq -c '.client_payload.statements[]' "$GITHUB_EVENT_PATH" | while IFS= read -r statement; do
runtime_id="$(printf '%s' "$statement" | jq -er '.runtimeId | select(test("^[a-z0-9][a-z0-9._-]{0,100}$"))')"
image="$(printf '%s' "$statement" | jq -er '.image | select(test("^ghcr.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$"))')"
image="$(printf '%s' "$statement" | jq -er '.image | select(test("^ghcr\\.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$"))')"
source_commit="$(printf '%s' "$statement" | jq -er '.sourceCommit | select(test("^[a-f0-9]{40}$"))')"
output="qualification-evidence/$runtime_id"
mkdir "$output"
@@ -92,6 +126,23 @@ jobs:
}' \
> "$output/qualified-runtime.json"
done
- name: Require one successful protected-main staging run with every native gate passed
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir staging-run-evidence
run_id="$(bun run scripts/cso-staging-run.ts run-id --repository "$GITHUB_REPOSITORY" \
qualification-evidence/*/provenance-verification.json)"
gh api "repos/$GITHUB_REPOSITORY/actions/runs/$run_id" > staging-run-evidence/run.json
gh api --paginate --slurp "repos/$GITHUB_REPOSITORY/actions/runs/$run_id/jobs?filter=latest&per_page=100" \
> staging-run-evidence/jobs.json
bun run scripts/cso-staging-run.ts verify --repository "$GITHUB_REPOSITORY" --run-id "$run_id" \
--event "$GITHUB_EVENT_PATH" --run staging-run-evidence/run.json --jobs staging-run-evidence/jobs.json
gh run download "$run_id" --repo "$GITHUB_REPOSITORY" \
--name cso-requalification-triggers --dir requalification-download
mv requalification-download/requalification.json qualification-evidence/requalification.json
rmdir requalification-download
- name: Enforce the complete release contract before retaining evidence
run: |
set -euo pipefail
@@ -105,5 +156,6 @@ jobs:
path: |
qualification-evidence
public-image-evidence
staging-run-evidence
if-no-files-found: error
retention-days: 30
+2 -1
View File
@@ -319,7 +319,7 @@ jobs:
permissions:
contents: write
pull-requests: write
actions: read
actions: write
packages: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
@@ -365,6 +365,7 @@ jobs:
git add lib/cso/scanner-images/catalog.json
git commit -m "Promote qualified CSO scanner catalog"
git push --set-upstream origin "$branch"
gh workflow run free-tests.yml --repo "$GITHUB_REPOSITORY" --ref "$branch"
cat > pr-body.md <<'EOF'
Promotes the complete scanner catalog produced by native amd64/arm64 qualification for all six CSO scanners. Each profile binds its immutable image, exact version-output hash, offline asset hash when required, containment and adapter gates, SBOM, provenance, source commit, and workflow run.