Repository navigation
Close the review notes on the results PR builder's test pins - #202
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Oct 21, 2026
MaxGhenis
force-pushed
the
w6/results-pr-tests-live-newest
branch
from
October 21, 2026 18:55
5c10b3f to
00afa36
Compare
Review of 3ddb331 (review_194b), the non-blocking notes on the test pins: - propose pin: shell_residue lexes the whole propose body left to right, carrying quote state across lines and nesting quotes, $(...), (...) and ${...} as bash does. Only a comment line, or a message line (an echo of a literal ::error::/::notice::/::warning:: string, alone on its line), that starts outside all of them is set aside. Heredocs, backticks, $'...', case inside parentheses and open quotes are refused, and the residue may not run text as code (a shell, eval, exec, source or .). Each self-check that bash should run does run `builder check` in bash 3.2 (bash 5.3 for the ${ cmd; } forms). - ImportScan: imports in the __main__ block and imports of names a function declares global bind module-wide; the entry module's __main__ block runs; exec and eval count as dynamic attributes; a skipped command branch's elif and else are followed, and a test other than args.command == "x" runs both ways. - UV_RUN: allows the standard library, the specs' closure and modules that load from the checkout, and refuses everything else, so a module no distribution owns (_virtualenv via its .pth) is refused, loaded or not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The adversarial pass on 10fc1c0 found the residue check narrower than its comment: `\. file`, `if . file`, `| "$BASH"` and a trap of a file's contents ran echoed messages unflagged. SHELL now matches a shell by name or as $BASH, $SHELL or $0, eval, exec, source, trap, and the . command escaped or after any word, and each of those four cases is a self-check that bash 3.2 runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
force-pushed
the
w6/results-pr-test-pins
branch
from
October 21, 2026 23:33
2443472 to
f378a01
Compare
MaxGhenis
changed the base branch from
w6/results-pr-tests-live-newest
to
main
October 21, 2026 23:33
MaxGhenis
marked this pull request as ready for review
October 21, 2026 23:33
Contributor
Author
|
#201 merged as Local checkouts of 🤖 Generated with Claude Code |
This was referenced Oct 21, 2026
Contributor
Author
|
Merged by squash at head
The fix stack (#199, #196, #201, #202) is now on main. Next: close #206 and rebuild the 6.9.0 results PR from request 🤖 Generated with Claude Code |
This was referenced Oct 22, 2026
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.
Closes the non-blocking notes that the second hard-tier review of #194 (review of 3ddb331,
review_194b.md) left on the test pins intests/test_uk_replay_results_pr.py. Test-only: no script, workflow or pipeline module changes. Stacked on #201 (and #196 under it), which rewrote the same file; it will be rebased onto main once they merge.Draft until the hard-tier review agrees. An in-session adversarial pass (Opus) found no way past the lexer, ImportScan or the uv emulation, and one overclaim. The comment said the residue may not run text as code, but
\. file,if . file,| "$BASH"andtrap "$(cat file)"got through. The second commit widens the check to match, and those four cases are now self-checks.1. Propose pin: a lexer, not a per-line regex
shell_residuereads the wholeproposebody left to right, as bash does:"…",'…',$(…),(…)and${…}nest as bash nests them, and escapes are honoured.#line inside a multi-line string or substitution stays in the residue (review 3).echo "::error|notice|warning::…"alone on its line, optionally>&2. Its text holds no quote, backslash, backtick or newline, and its only$expansions are plain names. That rules out$(,${,$((and bash 5.3's${ cmd; }and${|cmd;}. Bash reads such a line as an inert literal echoed to the log.$'…',caseinside parentheses, or a quote left open.#,pipelineor the wordbuilder, or if it names something that can run text as code: a shell by name or as$BASH,$SHELLor$0,eval,exec,source,trap, or the.command (escaped or not).The self-checks cover each of the review's cases:
echo " "::error::; builder check; echo " "echo x"::error::a "::error::; builder check; echo " z"#$(builder check)inside a multi-line string${ builder check; }and${|builder check;}They also include one exploit for each construct the lexer tracks or refuses, built on a "quote flip" template. Every case in the
runslist runsbuilder checkunder/bin/bash3.2 whenbuilderis defined. The two${ …; }forms need bash 5.3, which this host does not have. Therefusedlist holds the rule-only cases: an inline comment, acase, an open quote, and a message that is piped or sits in parentheses.2. ImportScan
__main__block, or an import of a name the function declaresglobal, binds that name module-wide.__main__block is walked. An imported module's block is not.execandevalare added toDYNAMIC_ATTRIBUTES, sobuiltins.exec(…)is recorded.entry()follows theelifandelseof a skippedif args.command == "x". It walks any other test ofargs.command(!=,in, chained) in full, and that test does not count as the command's branch. A taken branch skips its ownelifandelse.SCAN_FIXTUREorSCAN_CONSERVATIVE. The real scan is unchanged: the same four modules, third-party imports {jsonschema, rfc8785} (CONTROL as Read CI's replay-engine matrix from the variant index; drop the results bot's workflows permission #196 left it), and no dynamic imports. The real entry points' command branches have noelse, and their__main__blocks areraise SystemExit(main()).3. The test uv
UV_RUNnow allows only these:--withclosureIt refuses everything else, so a module that no distribution owns is refused, whether or not it is already loaded.
_virtualenv, which_virtualenv.pthloads at startup, is one example. The probe test adds astraymodule outside the checkout that asitecustomizeloads at startup, and asserts it is refused. It also asserts_virtualenvis refused wherever that module exists, and that a checkout module is imported.Mutation check
Each pin's checks were weakened one at a time, and the pin's test was run against each mutant. 36 of 37 mutants fail, as they should. The one that survives lets a
'appear inside a message. That mutant is equivalent: bash reads'literally inside double quotes, and single quotes are tracked, so no input tells the two apart. The rule stays because the brief asks for it. The mutation script and the bash run of every self-check are in~/PolicyEngine/_drafts/continuous-budget-ci/w6-lanes/pins/.Not addressed (beyond the brief)
The review also lists these ImportScan gaps, and this PR does not touch them:
__getattr__globals(),sys.modulesand__dict__lookupsgetattrwith a string namepkgutil.resolve_nameandEntryPoint.load__init__.pyfilesA text pin also cannot see words split by quotes (
bui""lder). End-to-end runs back that up:proposeruns as its own process, wherebuilder()is not defined, because it is defined only insidebuildandrebuild.Checks
pytest tests/test_uk_replay_results_pr.py: 83 passed locally.ruff format --check: clean.axiom: n/a: test-only change
🤖 Generated with Claude Code