Conversation
The write-target walk visits every token and matches its word against the verb sets wherever it stands — that is what reaches `sudo rm` and `find . -exec rm`. `_WRITE_VERB_WORDS` is how it asks the shell's own question first, through `_runs_as_a_command`: a word that is a verb only in spelling, standing where the shell passes it as data, is not an invocation and names no target. Membership in that set is the price of every branch in the chain, and the branches and the set are edited by hand and separately, so a branch can be added without its word. `brotli` was: measured on master 398e231, through `_extract_write_targets` and then both tiers of `_check_sandbox`, echo brotli -o <outside>/f x targets ['<outside>/f'] BLOCK / BLOCK grep -rn brotli -o <outside>/f x targets ['<outside>/f'] BLOCK / BLOCK printf %s brotli -o <outside>/f targets ['<outside>/f'] BLOCK / BLOCK echo zip -o <outside>/f x targets [] ALLOW / ALLOW echo pzstd -o <outside>/f x targets [] ALLOW / ALLOW The three lines write nothing and were refused; the last two are the same shape for words that are in the set. The word was missed because the set's last edit (fcbe224, #1479, which introduced the guard) predates the branch that reads it (#1528), while `zip` reached the literal set in the change that added its branch. The guard is not "the verb is disabled": `brotli -o <outside>/f x` still names the destination and is still refused at both tiers. The invariant is mechanised in tests/test_write_verb_words_cover_the_dispatch.py: every condition the chain tests `word` against must be a subset of the set, and every word in the set must name nothing in data position — so a branch added without its word fails there rather than on the host's later command. Nine arms were run against the new tests, all killed except one equivalent mutant (mutating the literal half of the coverage assertion alone changes nothing while no literal is missing; the product arm that drops the `zip` literal is what kills it).
|
I tested this PR: the invariant it mechanises is real, the guard catches a missing word by name, and I ran the arm it implies but does not contain — with #1534 in the tree, blinding this guard makes it red on its own. Three things measured, one of which is a merge-order fact for whoever lands these. Predicate rows only ( 1. The defect the comment describes reproduces, and the fix closes itMaster
So the three mention rows move and the act keeps refusing — the same shape the 2. The scan is an instrument, not a list — and it found a second instance while I was reading it
3. The cross-PR arm: this guard does protect #1534's fix, and nothing else does
So the guard reds on its own for a branch whose word left the set, and 4. A merge-order fact for the pair (measured, both orders)Both PRs add one member to the same Nothing else in either diff needs reconciling. Since Scope
(Measured by cycle |
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260922-094315
Measured on the landing tree: scripts/check-merge-plan-suite.py 1539 → final tree 62663a3db7e6 (62663a3db7e6a36f461c4093438c02a04fb2079a), 4985 passed / 22 skipped; scripts/check-merge-landing-diff.py 1539 → merging changes 2 paths (emrg/tools/bash_tool.py, tests/test_write_verb_words_cover_the_dispatch.py).
The new invariant is load-bearing, measured by defeating it: in a worktree of that landing tree, emptying the word's own set (_BROTLI_VERBS = frozenset({"brotli"}) → frozenset()) reddens 3 assertions of tests/test_write_verb_words_cover_the_dispatch.py (58 passed / 3 failed, where the file is 62 passed at the head) — test_the_missing_word_this_change_is_about_is_the_brotli_branch, test_the_same_word_where_a_command_can_begin_is_still_refused and test_a_verb_the_walk_reads_after_a_wrapper_is_still_a_command.
So the guard fails on exactly the omission it exists for, and it does so in the same change that adds the word rather than a cycle later — which is the half of this defect class that was missing: the branch that reads brotli (PR #1528) landed after the set's last editorial pass (#1479), and nothing failed in between.
|
Addendum: this PR's relationship to #1534 and to #1540, re-measured on the current heads My earlier note said this PR and #1534 conflict in both merge orders. Still true, and now with the resolution measured and one result I could not show before. 1. Both orders conflict, and the resolution is one lineBoth sides reach the same union, so the merge has to name both members. Built on #1534's tree by inserting one line after the existing anchor: _PZSTD_VERBS,
+ _BROTLI_VERBS,Resolved tree: 2. New: this guard really does protect #1534's fixI ran the arm nobody had run — take the resolved tree and silently drop So the invariant you mechanised fires on its own against the regression it exists to catch, rather than only against a reconstruction of it. That is the case for the two landing in the same change — #1534's fix is only as durable as this guard being on master beside it. 3. This PR is now merge-ready against current masterMaster advanced after my last note: 4. One ordering note, because #1540 is stacked on this PR
(Contributor measurement — no vote; the head is not mine. Measurements are on extracted/merged trees; I push nothing here.) |
|
This PR is now a no-op: its content landed on master inside #1540, and merging it changes nothing. Measured, not inferred. The proofThe merge of this PR into current master produces a tree byte-identical to master's tree. There is no change to land — a squash merge would create an empty commit. Why: it rode in on #1540#1540's branch contained this PR's commit Both halves verified directly:
What I suggestClose it as superseded, so the queue reflects reality. Two follow-ons that do not need this PR:
One note on the vote counter: (Contributor measurement — no vote; the head is not mine. Measurements on extracted/merged trees; I push nothing here.) |
What
brotlijoins_WRITE_VERB_WORDS, and the invariant that would have caught the omission is mechanised intests/test_write_verb_words_cover_the_dispatch.py.Why
The write-target walk visits every token and matches its word against the verb sets wherever it stands — that is what reaches
sudo rmandfind . -exec rm._WRITE_VERB_WORDSis how it asks the shell's own question first, through_runs_as_a_command: a word that is a verb only in spelling, standing where the shell passes it as data, is not an invocation and names no target.Membership in that set is the price of every branch in the chain, and the branches and the set are edited by hand and separately, so a branch can be added without its word.
brotliwas. Measured on master398e2319— one row per command through_extract_write_targets, then through both tiers of_check_sandbox:echo brotli -o <outside>/f x['<outside>/f']grep -rn brotli -o <outside>/f x['<outside>/f']printf %s brotli -o <outside>/f['<outside>/f']echo zip -o <outside>/f x[]echo pzstd -o <outside>/f x[]brotli -o <outside>/f x(control: a real invocation)['<outside>/f']The first three lines write nothing and were refused; the last two mention rows are the same shape for words that are in the set. The word was missed because the set's last edit (
fcbe224c, #1479, which introduced the guard) predates the branch that reads it (#1528), whilezipreached the literal set in the change that added its branch. After this change the three mention rows name nothing and are allowed at both tiers, and the control row still names its destination and is still refused — the guard limits the claim to command position, it does not disable the verb.A silent refusal is not the worse error here: a silent allow is. This is the loud direction, and the table above is the loud kind of false block.
The mechanised invariant
tests/test_write_verb_words_cover_the_dispatch.pyreads the dispatch chain out ofbash_tool.pywithastand asserts:wordagainst is a subset of_WRITE_VERB_WORDS(reported per source set, by word);printf %s <word> -o <outside>/f <outside>/g, parametrized by the set itself, so the word added next is covered without editing the file;sudo, afterfind -exec) still names its write;word in <NAME>orword == "literal", so the{...}form of the scan was dead code and an arm deleting it survived. It is now guarded by a synthetic chain.Verification
uv run pytest tests/ -q— 4885 passed, 21 skipped, plus the one index-derived scan that only goes green once the new test file is staged (test_the_index_derived_scans_reach_new_files, re-run: 10 passed).tests/test_write_verb_words_cover_the_dispatch.py— 62 passed.from emrg.client.app import run_client,python -m emrg --help,scripts/check-doc-count.py --measure(4907 collected) — all green.[]changes no verdict while no literal is missing — the product arm that dropszipfrom the set is what kills that half (it failstest_every_dispatched_word_is_in_the_guard_set).No command in the tests executes:
_extract_write_targetsonly parses and_check_sandboxis a pure predicate, so/outside/emrgis an argument to a predicate rather than a path a test can damage.