Repository navigation
Conversation
The results bot verified seals, regenerated the replay namespaces and built the database twice, but never ran the suite or the format check, so #195, #204 and #206 opened ready and failed CI. The build job now runs ci.yml's own ruff and pytest lines (pinned word for word) and its no-drift check on the assembled tree, with no token and no step command files in reach. A failure no longer means a red ready PR: the PR opens as a draft whose body names the failing tests, files or paths, and a failing rebuild turns an open PR back into a draft. Nothing marks a PR ready. runs_pipeline_code matched shell names before quote removal, so b''ash and b\ash ran bash past it. It now lists every command bash would run from propose (substitutions, groups, compound commands, function bodies) and requires each command word, as written, to be one propose uses; what the parser does not model is flagged. Both bypasses are test cases. Review of 2443472, findings 2 and 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ctor
Bash evaluates an array subscript, a substring offset, ${!name}, $[...]
and an array literal's [index] as arithmetic, and arithmetic runs a
command substitution held in a value: with x='a[$(touch m)]', each of
${a[x]}, ${y:x}, ${!x}, a[x]=1, $[x] and a+=([x]=v) ran touch under bash
3.2, past the allowlist. Parameter expansions are now a name with at most
a literal default, alternative or error word, subscripts are @, * or
digits, and indices and $[...] are unmodelled, so flagged.
printf's format must be a literal that is not an option (quoted -v or an
expansion is still -v). git's options that run a program or write a file
are matched after quote removal and as abbreviations, and --output joins
them; gh may not open an editor or browser. The script-level shadowing
check also finds `name () {` and `function name` definitions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three checks listing 100 names of up to 300 characters could reach about 90,000 characters, past the 65,536 GitHub accepts for a pull request body, and the branch would already be pushed when gh pr create failed. Each check now lists at most 50 names of at most 200 characters (about 31,000 for all three), and an end-to-end test fails every check with 80 names of the longest listable length and checks the body still fits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The suite runs with $GITHUB_OUTPUT and the other command-file variables unset, which stops a test that writes one by name. A process that finds the files on the runner's disk can still write them; job 2 already takes every build output as build's word, checked for shape. The script comment, the release doc and a test comment claimed more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of cf8066b (GPT-6.1 Sol, CHANGES REQUESTED on the test-side detector only) found 14 inputs bash runs that the detector passed, each executed under bash 3.2, 5.2.37 and 5.3: [ -v 'a[$(cmd)]' ], an array redeclared from a quoted value, process substitution inside ${...}, brace-expanded printf -v, and git or gh options passed through variables, arrays, braces, backslash line breaks or short-option bundles. Its patch is applied as written: options are checked in every word, after a backslash line break is removed, and brace expansion, [ -v ] and a local declared twice are flagged. The claim is narrowed to options written as words; one assembled at run time is beyond any rule on words. git's -u is dropped from the rule: in git 2.55 it is --set-upstream. Function definitions now count wherever they start, and the script holds no eval, source or . to build one. A node id's brackets end at the first ] its message follows, so an unbalanced [ no longer glues the message on; the report's count bound is 10^9; a duplicate failure counts once. The build job reads what it outputs about the commit before the suite runs in its tree, and pauses workflow commands (::stop-commands:: with a token only it holds) around the checks' output. A rebuild that should be a draft turns its open pull request back into one before the push, not after, and every gh pr ready carries --undo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This closes findings 3 and 2 of the GPT-6.1 Sol review of the results-PR stack (#199, #196, #201, #202). Both were non-blocking gaps. The report,
RESULTS_STACK_REVIEW.md, is copied to~/reviews/scorecard-results-stack-review/. Finding 1, the HF-token fetch order inci.yml, is a separate task.1. The results bot runs CI's own checks before it proposes (finding 3)
The App opened results PRs #195, #204 and #206 as ready, and each failed CI's
pytest · ruff formatjob. The builder verified seals, regenerated the replay namespaces and built the database twice. It never ran the suite or the format check.Now, after every check that stops the run, the
buildjob runsci.yml'spython-job lines on the assembled tree:uvx ruff format --check be nz scorecard_db tests pipeline;uv run --with pytest --with hypothesis --with pypdf --with pyyaml --with numpy --with psutil --with rfc8785==0.1.4 --with jsonschema pytest tests/ -q, withPYTHONPATH=.;git status --porcelain.A test pins both lines, and their environments, to
ci.ymlword for word.Permissions and token handling are unchanged. The checks run in
build, which hascontents: read, unpersisted credentials and no secret. Around them:GH_TOKENorGITHUB_TOKENis set.proposetakes everybuildoutput asbuild's word, checked for shape.::stop-commands::with a token only the script holds).buildoutputs about the commit is read before the checks run.A failure doesn't stop the run. Instead:
preflightsubcommand reports each check's exit status, how many things failed, and the first 50 listable names, as one line of JSON. The names are pytest's node ids from the last short test summary, ruff's files in either output format, and git's paths. Listable means printable ASCII, no backtick, no space at either end, at most 200 characters, so three full lists keep the body under GitHub's 65,536-character limit.proposepasses the report into the body, whereread_preflightrefuses any other shape.gh pr ready --undo) before the force-push. The builder never marks a PR ready.2. The detector checks an allowlist, not shell names (finding 2)
runs_pipeline_code's shell-name regex matched text before bash's quote removal, so{ …; } | b''ashand| b\ashgot past it and ran bash.The regex is gone.
Commandsreads the output ofshell_residue(#202's lexer, unchanged) and lists every simple command bash would run, in all of these places:if,whileanduntilbodies;{ }and( );$(…),<(…)and>(…);${ …; }and${|…;};Anything it doesn't model raises
Unlexed, so it is flagged:case,for, arithmetic, array indices, brace expansion, a parameter expansion beyond a name with a literal default, and a word after a compound command.disallowedthen requires every command word, as written, to be inPROPOSE_RUNS. That set is exactly whatproposeruns, and a test pins the equality:git,gh,grep,cut,cat,printf,echo,:,[,local,exit,plan,pushgit. It also flags:localwith options or declaring a name twice,printfwithout a literal non-option format, and[ … -v … ].@/*subscript (${a[x]},${y:x},${!x},$[x],a[x]=,([x]=v)). Arithmetic expands a command substitution held in a value (x='a[$(cmd)]').proposeuses, andgit -cother than the credential helper.--upload-pack,--receive-pack,--exec,--output), and gh's--editor/--web. This covers arguments, variable values and array elements, however quoted, escaped (backslash line breaks included), abbreviated (git takes any unambiguous prefix) or bundled (-dw).>&2and>> "$GITHUB_STEP_SUMMARY".pushgit. Its definition is pinned, and it must sit at the top level before its calls.A function with an allowlisted name would shadow that program. So the test pins that no definition anywhere in the script has one, except
planandpushgit, and that the script contains noeval,sourceor.. It also pinsplanand itsfieldhelper: the isolated runner's Python, running a fixed program that imports only json and sys.Both bypasses from the stack review are must-flag cases, as are the 14 found by the review of this PR (below).
Invariants (each run as a test)
read_preflightaccepts unchanged.-,], extra lines) and when a parametrised id holds-or an unmatched[.Review
The GPT-6.1 Sol review (lane run
20261021-225349-pr217-review-3; report in~/reviews/scorecard-results-stack-review/pr217-review-3/) returned CHANGES REQUESTED. It confirmed the production change, the credential boundary, the shape check, the draft rule, the parsers, the size limits and CI-line equality. Fifteen of its 16 mutations were caught by the tests.It found 14 inputs the detector missed. Each was executed under bash 3.2, 5.2.37 (the CI runner's version) and 5.3. The current
proposeuses none of them.[ -v 'a[$(cmd)]' ];${…};printf {-v,PATH};The commit after the review applies the reviewer's patch and fixes its other findings:
eval/sourcepin;-udropped (in git 2.55 it is--set-upstream, not a program);A re-review of the fixes follows.
Known limits
propose's body and the helpers it calls. It doesn't read the script's top-level lines, which every job runs: variable settings, the request-id check and the dispatchcase.u=--w; u+=eb) is beyond any rule on words.verify-sealedand content-hash lines. A package in job 1 could claim the checks passed; CI on the PR reruns them.FAILEDorERRORis read as another node id. This changes only what is listed, not the draft decision, which uses exit codes.Checks run
cf8066bc, including the full suite and the 6.9.0 replay leg from main.tests/test_uk_replay_results_pr.pywith-n 4: 128 passed after the review fixes.results_pr,ci_gates,discover,variants,qualify,determinismandengine_matrix): 444 passed and 1 skipped at56ebf542.uvx ruff format --check be nz scorecard_db tests pipelinepasses.axiom: n/a: CI and test tooling
🤖 Generated with Claude Code