Skip to content

W0 gate: gate convention, w0.sh exit gate, and fixes for its false greens - #475

Merged
hyperpolymath merged 4 commits into
mainfrom
claude/zen-brahmagupta-opqqle-w0-integ
Nov 9, 2026
Merged

hyperpolymath merged 4 commits into
mainfrom
claude/zen-brahmagupta-opqqle-w0-integ

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

This PR adds the W0 exit gate (ultraplan NEW:gate-convention, and W0 exit checks 1-13). Every other W0 lane is judged by this gate, so it has to be sound first. A skeptic review of the first version found eight ways it reported green or deferred without checking anything. The second commit fixes each of them and adds a fixture test for each.

Changes

  • scripts/gates/lib.sh records each check as PASS, FAIL or DEFERRED(reason).
    • DEFERRED is accepted only for these reasons, each with a name: ruling:, secret:, hardware:, owner-host: and no-push:.
    • An empty gate fails, and so does a check id recorded twice.
    • GATE_REPORT writes JCS JSON Lines atomically. A failed write fails the gate.
    • gate_cmd keeps working under a caller's set -e.
    • A detail containing a newline cannot forge a result line.
  • scripts/gates/w0.sh runs the 13 exit checks. Fixes from review:
    • check_runs dropped results on large commits. It passed runs to jq through argv, which hit E2BIG past 100 runs. jq printed nothing and that read as green. 2ab7574 (159 runs) and a81467b (144 runs) were silently skipped. It now collects pages in a file and fails closed.
    • Check 11 matched governance jobs. Its pattern was the bare word "conformance". It now requires exact job names: prove-result-conformance, and verisim-api-list for verisimdb. Check 12 requires agda-proofs. The script header states these as the contract the consumer lanes implement.
    • Handovers deferred too easily. Any file with a matching name, even empty or untracked, deferred checks 11 and 12. Now the live check runs first. DEFERRED(no-push) needs a committed, clean handover with a non-empty patch, issue text and PUSH-REFUSED.txt.
    • No token no longer defers. The repos are public, so the API is read anonymously when no token is set. A rate-limited or unreadable API is a FAIL.
    • Checks that accepted planted fakes:
      • 06a: blank and glob backend names.
      • 09: {} and nudged copies of the fabricated metrics.
      • 10a: one heading naming all rulings, and any URL accepted as the owner's record.
      • 13: "flake" matched as a lake build, and "14.13.01" as version 4.13.0.
      • 7: matched text inside comments.
    • Subset runs and configuration. W0_CHECKS runs a subset, which always exits non-zero. The effective configuration is printed first.
  • scripts/gates/hotspot-goldens.sh also captures router composition, so routes moved into a sub-router that is never mounted show as a diff. It now joins help file names with . instead of -, so foo-bar and foo bar cannot collide.
  • scripts/gates/w0.selftest.sh (new) has 50 fixture cases with a stub curl and no network. lib.selftest.sh now has 24 cases. Both run in MVP Smoke and through just test-gates.

One reading for the owner to see. Exit check (2) says "at success". Every merge on main carries schedule-only and matrix jobs that GitHub records as skipped, so the literal reading can never pass. The gate counts skipped and neutral as green and states the count in its PASS line. This is recorded in the script header, not hidden.

RSR Quality Checklist

Required

  • Tests pass: just test-gates gives lib 24/24 and w0 50/50.
  • Code is formatted: shell only, so there is nothing for rustfmt to change.
  • Linter is clean: shellcheck -x scripts/gates/*.sh gives no findings. The disabled rules are named with the reason.
  • No banned language patterns.
  • No unsafe blocks.
  • No banned functions.
  • SPDX headers on all new and modified files.
  • No secrets.

As Applicable

  • Docs: the gate convention is documented in the script headers. STATUS wiring belongs to D-2a (W2b).

Testing

  • Self-tests: bash scripts/gates/lib.selftest.sh gives 24 cases with 0 failed, and bash scripts/gates/w0.selftest.sh gives 50 cases with 0 failed.
  • Mutation checks on the tests themselves:
    • A faithful copy of the old check_runs fails the 150-run case.
    • Each of seven planted regressions (uncommitted, empty or unscheduled handover cases, the backend-name check, the claim regex, subset runs) fails at least one case.
    • The old lib.sh fails all four new library cases.
  • Live run against GitHub (checks 1, 2 and 6-13):
    • Every artefact still missing from main FAILs, as expected until the other lanes land. 7c PASSes.
    • Check 2 now lists main's real failures, including 2ab7574's.
    • echidnabot and proof-burrower were not readable from this sandbox (403), so those checks FAIL here.
  • Not run here: checks 3-5 need cargo builds.
  • Branch history: this branch merges main instead of rebasing. The first commit's Cargo.lock change (tokio 1.53.3, clipboard-win 5.4.3) is already on main through audit: routing/rule-engine recon, Logtalk quarantine; Agda proofs re-checked under PROOF-POLICY §2.1 #455, so this PR changes no lockfile.

Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 35 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 5e3c57ac-390c-4202-b143-e5149ee6d8f1
Commits

Reviewing files that changed from the base of the PR and between cea26cd and 7304141.

Files selected for processing: 7

  • .github/workflows/mvp-smoke.yml
  • Justfile
  • scripts/gates/hotspot-goldens.sh
  • scripts/gates/lib.selftest.sh
  • scripts/gates/lib.sh
  • scripts/gates/w0.selftest.sh
  • scripts/gates/w0.sh
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Copy link
Copy Markdown
Owner Author

Status of the red checks on the previous head (7236e9d). None of them is caused by this PR's gate code; the first two now have a fix ported in:


Generated by Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T21:26:50.644327Z 7304141 New commits
🔒 Security Review ❌ Failed 2026-11-09T21:19:12.081235Z
We couldn’t complete this review. Comment @codex security review to try again.
7304141 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ff728af28

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/gates/w0.sh Outdated
if ! rules=$(gh_get "repos/$REPO/rules/branches/main"); then
fail "$id" "cannot read the live ruleset for $REPO main"; return
fi
if ! req=$(jq -er '[.[] | select(.type == "required_status_checks") | .parameters.required_status_checks[].context] | unique | .[]' <<<"$rules"); then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the required check's integration ID

When a ruleset pins a required context to an expected GitHub App, this extraction discards integration_id, and the later match accepts any successful check run or legacy status with the same name. GitHub defines integration_id as the optional integration from which the check must originate (GitHub REST rules documentation), so an unrelated app can make this gate pass while GitHub still blocks the probe PR; retain each (context, integration_id) pair and compare it with the check run's app.id.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/hotspot-goldens.sh Outdated
Comment on lines +93 to +94
rg --no-filename --no-line-number --glob '*.rs' '^\s*\.route\(' src/rust \
| sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' | sort > "$out/routes.txt" || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep router ownership in the route golden

Using --no-filename and globally sorting the route lines erases which router owns each endpoint. This tree already has separate router builders in src/rust/server.rs and src/rust/groove.rs, so accidentally moving an unchanged .route(...) line from the served application router into the other router produces an identical golden even though the endpoint disappears from the application; preserve file/router grouping rather than comparing a global bag of lines.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh Outdated
Comment on lines +145 to +146
# strip_hash_comments <file>: the file without shell/YAML `#` comment lines.
strip_hash_comments() { grep -vE '^[[:space:]]*#' "$1"; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude inline comments from hygiene detection

This helper removes only full-line comments, so YAML such as run: echo ok # grep postulate survives and makes check 07a report PASS even though no command scans for postulate; the same issue can satisfy the command searches in 07c. Inspect actual run commands or otherwise remove YAML inline comments before using textual matches as proof that these checks execute.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh Outdated
Comment on lines +237 to +238
if ! runs=$(check_runs "$REPO" "$c") || ! statuses=$(gh_get "repos/$REPO/commits/$c/status") \
|| ! nr=$(jq -e 'length' <<<"$runs") || ! ns=$(jq -e '.statuses | length' <<<"$statuses"); then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Paginate legacy commit statuses

When a commit has more than 30 legacy status contexts, this fetch reads only the first page of the combined-status response and check 2 inspects only that partial .statuses array. GitHub documents a default page size of 30 and exposes the aggregate state across all contexts (GitHub commit-status API documentation), so a failed or pending context omitted from page one can leave bad and st empty and make the merge-history gate pass; paginate the statuses or require the top-level combined state to be success.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh Outdated
Comment on lines +102 to +103
curl -fsS --retry 2 \
${auth[@]+"${auth[@]}"} \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound each GitHub API request

When DNS, connection establishment, or response transfer stalls, --retry 2 does not impose a deadline, so any API-backed check can block the entire W0 gate indefinitely. The curl documentation specifically recommends --max-time to prevent batch jobs from hanging and notes that retries require their own total bound (curl man page); add connection, per-transfer, and retry time limits here.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
Comment on lines +534 to +535
if ! hit=$(jq -e '[.. | objects
| select(([.id, .name, .claim] | map(strings) | join(" ")) | test("\\blake[ _-]build\\b|\\blean4?[ _-]build\\b"; "i"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require the claims ledger root to be an object

The documented contract requires claims.json to hold an object, but this recursive query accepts any JSON root containing a qualifying object. For example, a root array containing one green Lean-build entry passes check 13 even though consumers expecting the ledger object schema cannot read it; validate type == "object" before searching its descendants.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh Outdated
Comment on lines +190 to +191
if ! rules=$(gh_get "repos/$REPO/rules/branches/main"); then
fail "$id" "cannot read the live ruleset for $REPO main"; return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Paginate all rules that apply to main

When more than 30 rules apply to main, this request reads only the first page, yet check 1 treats the returned subset as the complete live ruleset. GitHub documents a default page size of 30 for this endpoint (GitHub rules API documentation), so if page one contains one required-status rule while another appears later, the probe can pass without checking the later rule's contexts; collect every page before extracting required checks.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
Comment on lines +419 to +423
/^==+[[:space:]]/ {
named = ""
for (k = 1; k <= n; k++)
if (match($0, "(^|[^A-Za-z0-9-])" id[k] "([^A-Za-z0-9]|$)")) named = named " " id[k]
print NR named

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude AsciiDoc block comments from ruling sections

This parser treats every raw == line as a ruling section without accounting for AsciiDoc comment blocks. A ledger can therefore place all required headings and :status: open lines between //// delimiters and still pass check 10a even though the rendered document contains none of those rulings; strip block comments and other verbatim blocks before identifying headings and attributes, or parse the AsciiDoc structure.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins.

1 similar comment
@chatgpt-codex-connector

Copy link
Copy Markdown

This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f4dcd2b0f5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/gates/w0.sh
if ! [[ ${W0_PROBE_PR:-} =~ ^[0-9]+$ ]]; then
fail "$id" "W0_PROBE_PR is not set to the no-op probe PR number ($(wc -l <<<"$req") required contexts to check)"; return
fi
if ! sha=$(gh_get "repos/$REPO/pulls/$W0_PROBE_PR" | jq -er '.head.sha'); then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject closed or unrelated probe PRs

When W0_PROBE_PR names an old closed or merged PR, or a PR targeting another branch, this extracts only its head SHA, so historical green runs with the same context names can make check 1 pass without any live no-op probe demonstrating that the current main rules are satisfiable. Require the pull response to describe an open probe targeting main before accepting its statuses.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh

check_7() {
local wf=.github/workflows/idris2-abi-ci.yml ipkg=src/abi/echidnaabi.ipkg rel mod mods missing=()
if [ -f "$wf" ] && strip_hash_comments "$wf" | grep -E '\bpostulate\b' | grep -qE 'grep|rg |for pattern in'; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require an actual hygiene command

The inline-comment case is fixed, but a workflow line such as run: echo "grep postulate" still survives stripping and satisfies both grep stages even though it scans neither src/abi nor any other file; the analogous echoed agda ...AxiomTrackerCompleteness.agda also satisfies 07c. Parse the workflow's executable run commands or otherwise verify the command and target path rather than accepting arbitrary textual mentions.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
Comment on lines +536 to +537
ruled) grep -qE 'https://github\.com/hyperpolymath/[^[:space:]]+' <<<"$block" \
|| problems+=("$r: ruled without a link to the owner's record on github.com/hyperpolymath") ;;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ignore AsciiDoc line comments when validating ruling links

Although delimited comment blocks are now stripped, a ruled section whose only record is // https://github.com/hyperpolymath/... still passes this grep even though AsciiDoc omits that line from the rendered ledger. Strip single-line // comments as well before treating the URL as the owner's ruling record.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
Comment on lines +589 to +590
elif handover_ok "$repo" "$sub"; then
deferred "$id" "no-push:$repo" "$C_DETAIL; handover committed under $(handover_dir "$repo")/"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail consumer checks when their API cannot be read

When a committed handover exists and a consumer API request is rate-limited, unreachable, or unparseable, consumer_eval merely leaves C_GREEN empty and stores an error detail, after which this branch reports DEFERRED(no-push:...). The gate can therefore exit successfully without reading the consumer's state, contrary to its contract that an unreadable API is a failure; propagate a distinct evaluation-error state and fail before considering the handover.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
Comment on lines +231 to +233
*.patch|*.diff) [[ ${base,,} == *"${sub,,}"* ]] && patch=1 ;;
esac
[[ ${base,,} == *issue* ]] && issue=1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require separate patch and issue files in handovers

When the patch is named issue.patch (or, for check 12, agda-issue.patch), the same file sets both patch here and issue below, so adding PUSH-REFUSED.txt makes handover_ok accept only two files. This permits a deferred consumer check without the separate issue text required by the documented three-file handover contract; retain the matched paths and require them to be distinct.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
Comment on lines +358 to +359
gate_cmd "$id" "help, route table and just --list match $GOLDENS" -- \
"$here/hotspot-goldens.sh" check --dir "$GOLDENS"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the hotspot baseline immutable

When the hotspot-split change also recaptures and commits $GOLDENS, this invocation compares the generated output only with that modified working-tree directory, so changed help, routes, or recipes and their newly captured goldens match and the supposedly pure move passes. Verify that the golden directory is unchanged from W0_BASE (or read it directly from that immutable revision) before running the comparison.

Useful? React with 👍 / 👎.

@hyperpolymath
hyperpolymath enabled stacked auto-merge (squash) November 9, 2026 20:53
Gate convention (NEW:gate-convention): scripts/gates/lib.sh records each
check as PASS, FAIL or DEFERRED(reason). DEFERRED is accepted only for
ruling:, secret:, hardware:, owner-host: and no-push: reasons with a
name; any other reason is recorded as a FAIL. The summary prints at the
end and the gate exits 0 iff nothing failed. An empty gate and a
duplicated check id fail. GATE_REPORT writes JCS JSON Lines for STATUS.
scripts/gates/lib.selftest.sh covers all-pass, FAIL, every permitted
DEFERRED kind, eight forbidden reasons, the empty gate and the report.

scripts/gates/w0.sh scripts the 13 W0 exit checks. The GitHub checks
read GITHUB_TOKEN and are DEFERRED(secret:GITHUB_TOKEN) without it.
Checks whose artefacts come from other W0 lanes fail on main today.

scripts/gates/hotspot-goldens.sh captures and diffs the hotspot-split
goldens: every `echidna <sub> --help`, the .route( table under src/rust
and `just --list`.

CI-2 follow-up: cargo audit on main exited 0 with two allowed warnings.
Cargo.lock now takes tokio 1.53.1 -> 1.53.3 (RUSTSEC-2026-0386,
unsound AsyncFd constructors) and clipboard-win 5.4.1 -> 5.4.3 (yanked).
Only the two version and checksum pairs change. cargo update would also
have re-resolved windows-sys in nine Windows-only entries, so the two
entries were edited directly and checked with --locked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS4mfQeC3N1DWjcCQJaQqw
A review of the integ lane reproduced eight ways the W0 gate reported
green, or deferred, without checking anything. Each is fixed here, and
each has a fixture case in the new scripts/gates/w0.selftest.sh.

- check_runs passed the accumulated runs to jq through argv. On a
  commit with more than 100 runs, page 2 hit E2BIG, jq printed nothing,
  and checks 2 and 11 read the empty result as green. 2ab7574 (159 runs)
  and a81467b (144) were silently skipped. Pages are now collected in a
  file. Any unreadable page, unparseable page or page overflow returns
  an error.
- Check 11 matched the bare word "conformance", which governance's UUID
  and KYAML jobs already satisfy. It now requires an exact job name, or
  that name after " / ": prove-result-conformance, and verisim-api-list
  for verisimdb. Check 12 requires agda-proofs. The header states these
  names as the contract the consumer lanes implement.
- A handover deferred checks 11 and 12 on any file name, empty or
  untracked, and before the live check ran. Now the live check runs
  first. DEFERRED(no-push) needs a committed, clean handover with a
  non-empty patch, the issue text and PUSH-REFUSED.txt.
- No GITHUB_TOKEN deferred checks 1, 2, 11 and 12. The repositories are
  public, so the API is now read anonymously when no token is set. A
  rate limit or an unreadable API is a FAIL.
- 06a: blank, multi-word and glob backend names slipped through an
  unquoted loop. Names must now match ^[a-z0-9_]+$ and are read line by
  line.
- Check 9 passed `{}` and nudged copies of the fabricated metrics. It
  now requires the file to be absent, or to carry provenance.commit and
  provenance.run_id, and it still refuses the fabricated values.
- 10a accepted one heading that named all 19 rulings, the document
  title, and any URL as the owner's record. It now requires one section
  per ruling, exactly one :status: line, and a github.com/hyperpolymath
  link for a ruled section. 10b passes the W0 range to
  ruling-cited.sh.
- Check 13 matched "flake" and "14.13.01". It now requires a whole
  "lake build" or "lean build" token and the whole version 4.13.0. A
  repair counts only as an object with an id and "before": "F-3".
- Check 7 read comments: 7a and 7c ignore comments now, and 7b parses
  the ipkg modules list in both layouts. 7c follows check-agda.sh, which
  is how the meta-checker job runs MetaChecker.agda, so main's real
  import passes.
- Check 1 now treats a context that is not green as an answer, not as
  an evaluation error. The selftest caught this.

lib.sh changes:
- A report that cannot be written now fails the gate. The report is
  written to a temporary file and moved into place, so a failed write
  leaves no partial or stale file.
- gate_cmd keeps recording under a caller's `set -e`.
- Newlines in a detail are flattened, so a detail cannot print a forged
  PASS line.
lib.selftest.sh gains four cases. The old lib.sh fails all four.

w0.sh now prints its effective configuration first. W0_CHECKS runs a
subset, which always exits non-zero: a subset is a diagnostic, not a
gate result.

Check 2 still counts skipped and neutral runs as green, but the PASS
detail now counts them. The ultraplan's "at success" is unmet on every
merge on main, because schedule-only and matrix jobs record as skipped.
That reading is stated in the header. It is a departure from the letter
of exit check (2), recorded rather than hidden.

hotspot-goldens.sh:
- It captures router composition (Router::new, merge, nest, with_state,
  layer, fallback), so routes moved into a sub-router that is never
  mounted show as a diff.
- It joins help file names with "." so `foo-bar` and `foo bar` cannot
  collide.

The self-tests run in MVP Smoke and through `just test-gates`. Checking
the tests themselves: a faithful copy of the old check_runs fails the
150-run case, and each of seven planted regressions fails at least one
case.

Live run against GitHub (checks 1, 2 and 6-13): every artefact still
missing on main FAILs. 7c PASSes. Check 2 now lists main's real
failures, including 2ab7574.

The original commit's CI-2 Cargo.lock change is already on main through
a81467b (#455), so after merging main this lane changes no lockfile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS4mfQeC3N1DWjcCQJaQqw
Each finding is fixed at its source in scripts/gates/w0.sh and covered by
a w0.selftest.sh case that fails on the previous gate and passes now.

1. (P1) Check 2 read only the first 30 legacy commit statuses. Statuses
   are now read over every page (per_page=100) and must add up to
   total_count, and GitHub's combined state must also be success whenever
   any status exists: it is computed over every context, so even a page
   the gate failed to read cannot hide a red status.
   Cases: "check 2 reads a red legacy status on page 2 of the statuses",
   "check 2 fails closed when a statuses page is missing",
   "check 2 requires the combined legacy state to be success".
2. (P1) Check 1 dropped integration_id from required contexts. It keeps
   (context, integration_id) pairs; a pinned context needs a green check
   run from that app (runs are now kept latest per name and app), and a
   legacy status cannot satisfy it. Unpinned contexts are unchanged.
   Cases: "a run from another app does not satisfy a pinned context",
   "a legacy status does not satisfy a pinned context".
3. (P2) Check 1 read one page of branch rules. Every page is collected
   (per_page=100) before required checks are extracted.
   Cases: "a required context in rules page 2 still gates check 1",
   "check 1 fails closed when a rules page is missing".
4. (P2) gh_get's curl was unbounded. It sets --connect-timeout 10,
   --max-time 60 and --retry-max-time 120.
   Case: "every GitHub API request sets connect, total and retry time
   limits" (the stub curl logs its arguments).
5. (P2) strip_hash_comments kept inline `#` comments. It now cuts a `#`
   at line start or after whitespace outside quotes; an apostrophe inside
   a word does not open a quote.
   Cases: "a postulate grep in an inline comment fails 07a",
   "an agda call in an inline comment fails 07c",
   "an apostrophe does not hide an inline comment from 07c".
6. (P2) Check 10a counted headings and :status: lines inside AsciiDoc
   blocks. Comment (////), listing (----), literal (....), passthrough
   (++++) and fenced (```) blocks are blanked first, line numbers kept.
   Cases: "a section inside a //// comment block does not count for 10a",
   "status lines and headings in listing blocks do not count for 10a".
7. (P2) Check 13 accepted a claims.json whose root is an array. The root
   must be an object.
   Case: "a claims.json whose root is an array fails 13".

Shared paging lives in gh_pages, used by check_runs, commit_statuses and
the rules read; any unreadable page, non-array page or page 21 is a FAIL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS4mfQeC3N1DWjcCQJaQqw
The route golden was a global, sorted bag of `.route(...)` lines. A
route moved from the served application router into the groove router
gave an identical golden while dropping the endpoint from the app
(Codex P1). Each line is now prefixed with its owning module: the first
path component under src/rust/, with `.rs` removed. server.rs and
server/prove.rs both map to `server`, and groove.rs maps to `groove`.
Moving a route between routers now changes the golden, while splitting
a module into files does not.

Checked on the W0 split. Labelled routes (18 server, 2 groove) and
router composition are byte-identical before (535274c) and after the
server.rs split. w0.selftest: 68/68. shellcheck clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS4mfQeC3N1DWjcCQJaQqw
@hyperpolymath
hyperpolymath force-pushed the claude/zen-brahmagupta-opqqle-w0-integ branch from f4dcd2b to 7304141 Compare November 9, 2026 21:19
@chatgpt-codex-connector

Copy link
Copy Markdown

This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins.

@sonarqubecloud

sonarqubecloud Bot commented Nov 9, 2026

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7304141dca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/gates/w0.sh
Comment on lines +308 to +310
if [ "$nr" -eq 0 ] && [ "$ns" -eq 0 ]; then
problems+=("${c:0:9} has no check runs"); continue
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require the expected checks on every W0 commit

When one workflow never creates a check run—for example because it has a startup failure, is accidentally disabled, or stops matching the commit—this accepts the commit as long as any unrelated check or legacy status is green. Consequently check 2 can report that every run succeeded while most of the intended W0 validation never ran; compare each commit against the applicable expected contexts rather than rejecting only commits with zero total results.

Useful? React with 👍 / 👎.

Comment thread scripts/gates/w0.sh
is_jcs() {
local f="$1"
[ "$(jq -s 'length' "$f" 2>/dev/null)" = 1 ] || return 1
cmp -s <(jq -cS . "$f") "$f"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate JCS numbers with an actual canonicalizer

When either ledger contains a decimal such as 1.0, jq 1.7 preserves that numeric lexeme, so jq -cS produces identical bytes and this check accepts the file even though JCS canonicalizes the value as 1; exponent spelling and Unicode key ordering have similar differences. Thus checks 06a and 13 can claim a noncanonical ledger is JCS, so use an RFC 8785 canonicalizer rather than jq's compact sorted output.

Useful? React with 👍 / 👎.

@hyperpolymath
hyperpolymath merged commit d7abedc into main Nov 9, 2026
83 of 85 checks passed
@hyperpolymath
hyperpolymath deleted the claude/zen-brahmagupta-opqqle-w0-integ branch November 9, 2026 21:28
hyperpolymath added a commit that referenced this pull request Nov 9, 2026
…pre-split goldens (#483)

## Summary

This is the W0 "split" lane. It is stacked on #475, which carries the
gate it is checked against. Three hotspot files are broken into modules
by area. Behaviour is held fixed by goldens captured on the pre-split
tree, and W0 exit check 5 compares them. Nothing is renamed or
redesigned.

## Changes

- **Goldens first** (535274c). `tests/golden/hotspot/` holds 27 files
captured before any move: every route, the router composition, and
`--help` for each CLI command and subcommand.
`scripts/gates/hotspot-goldens.sh` regenerates them and compares.
- **`src/rust/server.rs` →
`server/{mod,agent,prove,search,session,status,ui,verify}.rs`**
(a2fb862). Handlers move by route family. `mod.rs` keeps router
composition and shared state.
- **`src/rust/main.rs` →
`cli/{args,util,prove,verify,search,session,provers,lexicon,corpus,design}.rs`**
(ee2ed98). `main.rs` keeps only parsing, tracing set-up and dispatch;
`cli/mod.rs` re-exports the command functions.
- **`Justfile` → `just/*.just`** (9444837). There are 14 files, one per
area, pulled in by `import`. The contractile import stays last. Recipe
names and bodies are unchanged; `just --list` matches before and after.
- **Merged from #475's base:** the #465 fix for the red checks on `main`
(rmcp 3.9.0, rustfmt on `proof_search.rs`, and the Zig-cast
annotations).

## RSR Quality Checklist

### Required

- [x] Tests pass. W0 check 5 (hotspot goldens) passes, and so does
`cargo check --bins` after the merge. I have not run the full `just
test` on this branch: disk here is limited. This PR's CI runs it.
- [x] Code is formatted (`cargo fmt --all -- --check` is clean).
- [x] Linter is clean (`cargo clippy` was clean when the split landed).
- [x] No banned language patterns.
- [x] No new `unsafe`.
- [x] No banned functions.
- [x] SPDX headers on all new files.
- [x] No secrets.

### As Applicable

- [ ] Documentation: `CLAUDE.md`'s structure tree still lists
`server.rs` and `main.rs`. That reconcile is reserved for the rulings
lane (#58), so this PR does not edit `CLAUDE.md`.

## Testing

- `bash scripts/gates/hotspot-goldens.sh check` exits 0: routes, router
composition and CLI help are byte-identical to the pre-split capture.
- `cargo check --bins` and `cargo fmt --all -- --check` pass on the
merged head.
- Already broken on the pre-split tree, and not changed here: `echidna
corpus import-octads --help` panics (exit 101). It has its own
follow-up.

Refs #416

---
_Generated by [Claude
Code](https://claude.ai/code/session_01WS4mfQeC3N1DWjcCQJaQqw)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants