gates empty: say whether a passing gate could reach a tree at all - #3058
Merged
Conversation
Closes #3057 `tri gates empty` reported 5 invocations that passed over an empty tree. Going through them by hand found ZERO defects: three never touch a tree, and the two that do print their scope or their population -- `Scope: this tests the two shell forms, not the live workflow`, and `tracked files read 7741` here against `tracked files read 0` in an empty tree built to check. The discriminator is not "did it pass over nothing" but "can this reach a tree", and the output did not say it. One column, decided from the script's source, with the marker list in a named constant so it can be argued with. Two states, plus "source not read" for a command with no script in it -- never false, because a file nobody opened cannot be reported as one that touches nothing. A THIRD STATE WAS TRIED AND REMOVED, and that is the part worth keeping. "Reads one and builds one" was meant for pack_index_consistency_gate.py --selftest, whose os.listdir is aimed at a mkdtemp of its own. It also swallowed check_conflict_markers.py, which reads 7741 tracked files and merely uses a TemporaryDirectory inside its --self-check at line 141. The bucket held two members and neither belonged in it, while the count of the category worth reading went to zero. A file-level marker cannot answer an invocation-level question; the limitation is stated in the doc comment with --selftest named in it, and the removal has its own test so its absence is a decision. Three mutants. Emptying the marker list kills all three tests. Restoring the third state kills exactly the test written for it, 2 passed 1 failed. The first attempt at that round used `cargo test ... reach`, which matched sixteen tests in leanreach and modreach and none of mine -- the filter is a substring, the mutant read as surviving, and what caught it was expecting 3 and reading 16.
Refs #3057 `tri skill renumber` is on an unmerged branch, so this worktree's `tri` does not have it and the previous commit shipped the literal placeholder. `tri skill check` passed on it: 999 is unique and it is larger than every other number, so both properties the check tests were satisfied by a number that is obviously wrong. A placeholder that survives the check is a placeholder that needs the check to know it is one.
gHashTag
enabled auto-merge (squash)
September 3, 2026 20:30
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
This was referenced Sep 3, 2026
Contributor
PR DashboardGenerated at: 2026-09-03 21:05:55 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
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 #3057 · follows #3049
I went through the five
tri gates emptyreports 5 invocations that PASSED against a tree with nothing in it. That is a shape, and the command says so. Nobody had gone through them.test_untrusted_javascript_payloads.pyScope: JavaScript source in actions/github-scripttest_untrusted_payloads.pyScope: this tests the two shell forms, not the live workflowgft_backprop_microcode.pypack_index_consistency_gate.py --selftestos.listdirat :164mkdtemp; endsselftest OK: the gate is falsifiablecheck_conflict_markers.pytracked files read 7741here, and0against an empty tree I built to checkDefects among the five: 0. The discriminator is not did it pass over nothing — it is can this reach a tree, and does it say what it read. The first half is what a command can do, and it was missing.
The column
Markers live in a named constant so the list can be argued with. Two states, plus source not read for a command with no script in it — never
false, because a file nobody opened cannot be reported as one that touches nothing.A third state was tried and removed, and that is the part worth reading
The column printed 2 where my hand pass said 1. The extra is
pack_index_consistency_gate.py --selftest, whoseos.listdiris aimed at atempfile.mkdtempof its own. Both readings are right about different subjects: the file reads a directory, the invocation reads its own.So I added a third state — reads one and builds one, keyed on
mkdtemp/TemporaryDirectory. It captured the selftest. It also capturedcheck_conflict_markers.py, which really does read 7741 tracked files and merely uses aTemporaryDirectoryinside its--self-checkat line 141.The new bucket held two members and neither belonged in it, while the count of the category actually worth reading went from 2 to zero. The output looked richer and said less.
A file-level marker cannot answer an invocation-level question. A second heuristic stacked on the first to cover its false positive does not narrow the error, it moves it somewhere with no name. Two states and a stated limitation beat three states and a hidden one — the limitation is a sentence in the doc comment with
--selftestnamed in it, and the removal has its own test so its absence is a decision rather than an omission.Evidence
cargo test -p tri --bins→ 545 passed, 0 failed, 0 filtered.The first attempt at that mutation round was wrong and the guard caught it. It ran under
cargo test … reach, which matched sixteen tests inleanreachandmodreachand none of mine — the filter is a substring, so the mutant read as surviving. What caught it was expecting 3 and reading 16, which is why every row above is a per-test run withpassed + failed = 3asserted.Skill §473. The commit before last shipped it as the literal
## 999.placeholder —tri skill renumberlives on an unmerged branch, so this worktree'stridoes not have it — andtri skill checkpassed: 999 is unique and larger than every other number, which is both properties it tests. Fixed in the following commit, and worth knowing that the check cannot see a placeholder.