Skip to content

compass(gates): join the README's exclude-list counts to the list - #310

Merged
jgong5 merged 1 commit into
feature/atomcompass_newfrom
compass/issue-213
Sep 23, 2026
Merged

jgong5 merged 1 commit into
feature/atomcompass_newfrom
compass/issue-213

Conversation

@jgong5

@jgong5 jgong5 commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Closes #213

What changed

tests/compass/test_cpu_gate_exclude.py gets one test, test_the_readme_states_the_counts_the_list_holds, parametrised as [total], [generated] and [manual]. Each case reads its number from the cpu_gate_exclude.txt row of scripts/compass/README.md and asserts that it equals the count derived from the list. On a disagreement the message names the README, the stated number, the list and the entries it holds.

A missing row or a reworded number also fails by name. It does not pass vacuously.

Nothing under scripts/compass/ changes. The directory's tree object is ba78568c8 at both the tip and the head, so the gate below is the same instrument on both sides.

Lines: 0 production, 28 test (+28/-0). The estimate was ~35.

Staleness check at f84b4d778

The choice: assert the README against the list, rather than stop restating

gate_gpu.sh:111-122 settles the shape. It keeps BASE_FAILED=5 as a stated number, counts gpu_gate_known_failures.txt, and on a disagreement refuses, naming both. The README's own row for that file describes the same shape: "two statements of one fact; gate_gpu.sh refuses to run if they disagree". This PR copies that shape instead of inventing a second one.

On simplicity: dropping the numbers from the README would be fewer lines. But the row's 29 is the size of the CPU tier's blind spot, and that figure is the reason a reader opens the row. That is also why BASE_FAILED is kept beside its list rather than removed.

The join also costs nothing the gate executes. The alternative, editing the README, would have moved the scripts/compass tree object, and that object is the instrument every open gate delta is measured with.

The existing MANUAL pin (== 1) is kept as it is. It is the in-file statement that separates a chosen empty section from one that arrived, and the join does not replace it.

Named result: node 18, xiaobizh_n18_cpu, one module per tree

Each mutation is a line-count-preserving edit built with git commit-tree, so every run names a commit. atom.__file__ resolved under each staged root in every run.

tree edit result
tip f84b4d778 (null control) none 70 passed, rc=0
head 3fb992d2c (null control) none 73 passed, rc=0; the 3 new ids pass
678c85a2a = tip + manual entry cpu_gate_exclude.txt:49, a comment line becomes tests/test_gc_utils.py 1 failed: test_the_manual_section_holds_the_entries_it_is_pinned_to_hold. The README stays wrong in silence.
c17909d47 = head + the same entry same 3 failed: the pin, test_the_readme_states_the_counts_the_list_holds[total] and test_the_readme_states_the_counts_the_list_holds[manual]
197c307ec = tip + README says 2 MANUAL README.md:20, **1 MANUAL** becomes **2 MANUAL** 70 passed, rc=0. Silent.
038cee2c3 = head + README says 2 MANUAL same 1 failed: test_the_readme_states_the_counts_the_list_holds[manual]

The join's assertion text at c17909d47, [manual]:

AssertionError: README.md states **1 MANUAL** but cpu_gate_exclude.txt holds 2: ['tests/test_gc_utils.py', 'tests/test_lmcache_offload_disk_integration.py']. Update the README row to match the list.

The added entry was chosen to break nothing else. tests/test_gc_utils.py exists, sorts before the existing entry, keeps a comment line directly above it, and is not in the GENERATED section. Only the counts move.

I also fired the two refusal paths on the head tree, both with line-count-preserving README edits:

  • **29** excluded reworded to 29 excluded: 1 failed, [total], with "README.md's cpu_gate_exclude.txt row no longer states /…/".
  • The row indented so it no longer starts with the list's cell: 3 failed, all three ids, each with "README.md has 0 rows for cpu_gate_exclude.txt".

One note from the brief, stated rather than left to happen quietly: this PR does not raise the MANUAL count, so test_the_manual_section_is_sorted_and_unique is still trivially true at n=1. At n=2 in the mutation above it had signal and passed, because the added entry was placed in sorted order.

Gate 1: ATOM's suite, unmodified, as a delta against a measured control

Node 18, xiaobizh_n18_cpu. Each tree was staged with git archive and docker exec -i … tar -x into /tmp/i213gates/<side>/ATOM, with .compass-commit / .compass-changed written from the same sha. Content digests matched on both ends. Each tree ran its own scripts/compass/gate_cpu.sh, unpiped, under timeout -k 10, one at a time.

side commit stamp result GATE_CPU_RC
control f84b4d778 f84b4d778 (stamp), gpu: not required 5214 passed, 155 skipped, 3 xfailed 0
head 3fb992d2c 3fb992d2c (stamp), gpu: not required 5217 passed, 155 skipped, 3 xfailed 0

Node-id delta (from --junitxml): 0 ids only in the control, and 3 only in the head, all passed:

  • tests/compass/test_cpu_gate_exclude.py::test_the_readme_states_the_counts_the_list_holds[total]
  • …[generated]
  • …[manual]

No flake-listed test moved.

git merge-tree --write-tree f84b4d778 3fb992d2c gives 65f9f1fedbcd067c9f7d375cabc8820f3aa8434a, which equals 3fb992d2c^{tree}.

Gate 2: CPU-only tests

The three ids above run in the CPU tier. They exercise scripts/compass/README.md and scripts/compass/cpu_gate_exclude.txt, neither of which this PR adds or edits. ruff check and ruff format --check on the file: clean.

Not done, and left for a successor (filed as #311)

  • scripts/compass/README.md restates other counts with no join: 30 trigger paths on line 21 (still right at the tip), and 4779 passed / 5 failed plus "five" known failures on lines 15 and 22.
    • These are outside this brief's file set, so they are not joined here.
    • The trigger count carries the same risk as this issue: regen_gpu_gate_triggers.sh rewrites the file wholesale, and the README would not follow.
  • atom/compass/design/16_execution_plan.md:171 also says "29 entries are 28 GENERATED + 1 MANUAL". It is a dated record of what one commit produced ("From this commit…"), not a live statement, so it is not joined.

🤖 Generated with Claude Code

scripts/compass/README.md states cpu_gate_exclude.txt's counts (29 total,
28 GENERATED, 1 MANUAL), and nothing checked them. An entry added to the
MANUAL section reddened the in-file pin and left the README wrong in
silence.

Add test_the_readme_states_the_counts_the_list_holds, parametrised over
the three numbers in the README row. Each one is compared with the count
derived from the list, the same shape gate_gpu.sh uses for BASE_FAILED
against gpu_gate_known_failures.txt. A disagreement names the README, the
stated number, the list and the entries it holds. A missing or reworded
row fails by name rather than passing vacuously.

Nothing under scripts/compass/ changes.

Closes #213

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ids=["total", "generated", "manual"],
)
def test_the_readme_states_the_counts_the_list_holds(stated, derive):
# README.md restates this file's counts, and the pin above holds the MANUAL

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Non-blocking (principles 3 and 8). The PR body says the MANUAL pin (test_the_manual_section_holds_the_entries_it_is_pinned_to_hold, L147-168) is kept because "the join does not replace it". I measured that claim, and it does not hold. The pin's stated job is to stop an emptied MANUAL section from passing silently, with its parametrisation collecting nothing. This join does that job already.

tree edit (line count preserved) result, tests/compass/test_cpu_gate_exclude.py only
a821914ad = head + MANUAL emptied cpu_gate_exclude.txt:51 commented out 3 failed, 68 passed, 1 skipped: the pin, [total], [manual]
a833627b9 = the same + pin neutralised also assert len(entries) == 1 -> >= 0 2 failed, 69 passed, 1 skipped: test_the_readme_states_the_counts_the_list_holds[total] and [manual] (states **1 MANUAL** but ... holds 0: [])

After this PR, the MANUAL count is stated twice by hand: **1 MANUAL** in the README and == 1 in the pin. Both are joined to the list, and every edit that fails one fails the other. Reaching zero on purpose now takes two edits instead of one.

Either choice is fine:

  • Delete the pin (about -24 lines). Then point the control test's docstring (L172) and the module docstring (L28-30) at this join.
  • Keep the pin with a reason that holds. The only real difference is locality: the pin's number sits in the file the list is tested from. The PR body's sentence should then say that, not that the join cannot replace it.

entries = derive()
assert int(found[1]) == len(entries), (
f"{README.name} states {found[0]} but {EXCLUDE.name} holds {len(entries)}: "
f"{entries}. Update the README row to match the list."

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Non-blocking (principle 6). This sentence picks a side, which the comment at L206 says the join does not do ("a disagreement names both rather than picking one"). gate_gpu.sh's message is the model this test copies, and it only states the two numbers: BASE_FAILED=%s but %s names %s node-id(s).

The side it picks is wrong in exactly the case the MANUAL pin exists for. Emptying the MANUAL section by accident (mutation a821914ad: cpu_gate_exclude.txt:51 commented out) fails [manual] with README.md states **1 MANUAL** but cpu_gate_exclude.txt holds 0: []. Update the README row to match the list. Here the list is the wrong side, and the message tells the reader to make the README agree with it. For GENERATED the list usually is right, because a regenerator wrote it. For MANUAL it is a hand edit, and either side can be the mistake.

Suggested fix: end the message at {entries}., or replace the last sentence with a neutral one such as One of the two is wrong; fix that one. This matters more if the pin goes (see the comment on L202), because the pin's "Add or remove one deliberately" wording is then no longer printed beside it.

@jgong5

jgong5 commented Sep 23, 2026

Copy link
Copy Markdown
Owner Author

This review is agent-authored. I read the eight design principles in atom/compass/design/README.md and atom/compass/AI_DEV_RULES.md before reading the diff.

Verdict: APPROVE 3fb992d2ce15c7cb78f2a3972c54ea4de18dad16. There are no blocking issues.

  • The named result reproduces by node id.
  • Every refusal path fires.
  • Two mechanisms of my own also redden the join. One of them, a stray entry outside the markers, is caught only by [total].
  • The tree that will land gates green on node 18.

There are two inline comments, both non-blocking:

  • L202: the MANUAL pin is now redundant, measured. The PR body's claim that "the join does not replace it" does not hold.
  • L214: the message's last sentence picks the list's side, so it points the wrong way when a MANUAL entry is lost by accident.

Rulings

1. Assert rather than remove (principle 3): keeping the numbers and pinning them is the right call.

  • The brief allowed either option and said to match gate_gpu.sh's shape. That shape keeps the stated number and refuses on a disagreement (gate_gpu.sh:111-122).
  • The numbers are why a reader opens the row: 29 files the CPU tier cannot see, split by provenance.
  • The cost is 28 test lines and no new statement of the fact. The test reads the README's number; it adds no literal of its own.
  • The join does more than restate the pin:
    • [generated] reddens on a regenerator shrinking the list (f9ec8f500). Nothing else in the tree catches that.
    • [total] catches entries outside both markers (60fbd4cdf). Nothing else in the tree catches those either.
  • So "stop restating" would have been fewer lines, and it would have given up the only check on two of the three numbers.
  • The developer's second reason is secondary but true: a README edit moves scripts/compass off tree ba78568c8.

3. Parser robustness (principle 6): it refuses on every format change I tried, and never falls back.

format change result
number reworded [total] fails: "no longer states /…/"
row indented (no longer found) all three fail: "has 0 rows"
row duplicated all three fail: "has 2 rows"
  • A spelled-out number cannot match \d+, so it refuses too.
  • The one soft spot is not worth a fix: re.search takes the first match within the row. That only matters if the row ever carries two **N MANUAL** phrases.
  • The row key is the table cell's exact prefix. The other rows that mention the file do not start with it.

Named result and mutations

Node 18, xiaobizh_n18_cpu. Each tree is a git commit-tree object built from a line-count-preserving edit (git diff --numstat 1/1 on each file). Each was staged with git archive + docker exec -i … tar -x into /tmp/pr310rv/<name>/ATOM, and the tarball md5 matched on both ends. atom.__file__ resolved under each staged root.

Each run covered tests/compass/test_cpu_gate_exclude.py only, under timeout -k 10 600. Node ids are under that file; [x] is short for test_the_readme_states_the_counts_the_list_holds[x].

# tree edit result
N1 head 3fb992d2c (null) none 73 passed, rc=0
N2 tip fbfc37ef8 (null) none 70 passed, rc=0
A 5f37da4ca = tip + manual entry cpu_gate_exclude.txt:49 becomes tests/test_gc_utils.py 1 failed: test_the_manual_section_holds_the_entries_it_is_pinned_to_hold. The README stays silently stale.
A′ 1b5ec0937 = head + the same edit same 3 failed: the pin, [total] (states **29** excluded test files but … holds 30) and [manual] (states **1 MANUAL** but … holds 2: ['tests/test_gc_utils.py', 'tests/test_lmcache_offload_disk_integration.py'])
B 6d4f571ba = tip + README "2 MANUAL" README.md:20 70 passed. Silent.
B′ 60f00f51c = head + the same edit same 1 failed: [manual] (states **2 MANUAL** but … holds 1)
R1 deee19dc1 = head, **29** excluded becomes 29 excluded README.md:20 1 failed: [total], README.md's cpu_gate_exclude.txt row no longer states /\*\*(\d+)\*\* excluded test files/
R2 b76e7f897 = head, row indented two spaces README.md:20 3 failed: [total], [generated], [manual], each README.md has 0 rows for cpu_gate_exclude.txt
M1 652a62b23 = head, row duplicated over the triggers row README.md:21 3 failed, each has 2 rows
M2 39550dd98 = tip, first GENERATED entry commented out (a regenerator shrinking the list) cpu_gate_exclude.txt:18 69 passed. Silent.
M2′ f9ec8f500 = head, the same edit same 2 failed: [total] (29 vs 28) and [generated] (**28 GENERATED** vs 27). The pin does not move.
M3 f14ac226e = tip, stray entry outside both markers cpu_gate_exclude.txt:16 (a header comment) becomes tests/test_gc_utils.py 71 passed. Silent. gate_cpu.sh would exclude a 30th file that nothing documents.
M3′ 60fbd4cdf = head, the same edit same 1 failed: [total] alone. So [total] is not the sum of the other two cases. It is the only guard on the file-wide count that gate_cpu.sh actually reads (principle 7).
M4 a821914ad = head, MANUAL emptied cpu_gate_exclude.txt:51 commented out 3 failed, 68 passed, 1 skipped: the pin, [total], [manual]
M4′ a833627b9 = M4 + the pin neutralised (== 1 becomes >= 0) also test_cpu_gate_exclude.py:164 2 failed: [total] and [manual]. The join alone catches the emptied section; see the inline comment at L202.

M1-M4 are my own. The developer's table reproduces exactly, with my own commit objects.

Gate: the tree that will land

  • The tip moved from f84b4d778 to fbfc37ef8 (compass(tests): hold four refusals the artifact store states and nothing reached #306, which touches only tests/compass/test_artifact_invalidation.py).
  • git merge-tree --write-tree fbfc37ef8 3fb992d2c gives 150a2a0e5cf544601997ee511f02296eadd6b797. That is no longer 3fb992d2c^{tree} (65f9f1fed), so the developer's gate does not stand, and I gated this tree once.
  • Stamp commit: git commit-tree 150a2a0e5 -p fbfc37ef8 -p 3fb992d2c = 8b8eca71d8bd476fd328ab99e01bb5fb0ebba82e.
  • .compass-changed is tests/compass/test_cpu_gate_exclude.py (diff against the tip).
  • scripts/compass is tree ba78568c8 at the tip, the head and the merge, so the gate is the same instrument on every side.
tree atom.__file__ gate_cpu.sh (the tree's own, unpiped, timeout -k 10 1800) verdict
merged 8b8eca71d /tmp/pr310rv/merged/ATOM/atom/__init__.py commit: 8b8eca71d (stamp), gpu: not required, 5225 passed, 155 skipped, 3 xfailed (190 s) GATE_CPU_RC=0 PASSED

5225 is the number the history predicts:

The three new ids are in the merged run's --junitxml. No flake-listed test failed, so no re-run was needed.

ruff check and ruff format --check on the file, in the merged tree on node 18 (ruff 0.16.7): RUFF_RC=0, FMT_RC=0.

Other checks

ponytail-review

tests/compass/test_cpu_gate_exclude.py:L147-168: delete: the MANUAL `== 1` pin; `[manual]` now reddens every edit it does (M4′: 2 failed with the pin neutralised). Point the control's docstring (L172) and the module docstring (L28-30) at the README join instead.

The added 28 lines themselves are the minimum: one parametrised test, a row lookup, a regex, and an assert. The three cases are worth their node ids, since M2′ and M3′ each redden a different subset.

net: -24 lines possible.

@jgong5
jgong5 marked this pull request as ready for review September 23, 2026 14:53
@jgong5
jgong5 merged commit 2565b5f into feature/atomcompass_new Sep 23, 2026
jgong5 added a commit that referenced this pull request Sep 23, 2026
…peats

Each count that scripts/compass/ restated away from its source is now
either held to that source by a test, or no longer restated.

Joined, in the shape #310 used for the exclusion list's counts:
- the README's trigger-path count, against gpu_gate_triggers.txt, as a
  `triggers` case of test_the_readme_states_the_counts_the_list_holds;
- the README's GPU baseline (passed, failed, commit), against gate_gpu.sh's
  BASE_PASSED / BASE_FAILED / BASE_COMMIT, in
  test_the_readme_states_the_baseline_the_gate_holds;
- gate_gpu.sh's worked `4779 + 0 - 49 = 4730`, which a test pinned as the
  literal "4730". It is now derived from BASE_PASSED and BASE_COMPASS_TESTS,
  so a rebaseline that leaves the comment behind reddens.

No longer restated. These either moved with most tasks, were already
wrong at the tip, or repeated a figure that is now joined:
- "130 of 189 test files" in the README and gate_cpu.sh. At 2565b5f it
  is 166 of 225; 130/189 was fada742's census;
- gate_cpu.sh's 30 plugin files and 29 / 28 / 1 exclusions;
- "(130 files)" on two Baselines rows. At 186d128 the tier was 144 files;
- the README's second "30 source paths", the two "five failing node-ids",
  and the numbers in "What the GPU gate expects", now given as constant
  names;
- "190 of this tree's indented imports", in the README and in
  regen_gpu_gate_triggers.sh. It is 205 at the tip, so it is now pinned to
  fada742, where it was measured;
- "removes no path from this tree: 30 triggers with it, 30 without", in
  the regenerator's header template and in the file it wrote. That was
  measured at 236abfd, yet every regeneration stamped it as "this tree".
  It is now pinned to 236abfd;
- "All five" in two gate_gpu.sh comments, and "All five callers" in _lib.sh.

Every scripts/compass/ edit is to a comment or the README. The one change
to gpu_gate_triggers.txt is to a `#` line, which gate_cpu.sh skips.

Closes #311

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
jgong5 added a commit that referenced this pull request Sep 23, 2026
…peats (#327)

* compass(gates): join or stop restating the counts scripts/compass/ repeats

Each count that scripts/compass/ restated away from its source is now
either held to that source by a test, or no longer restated.

Joined, in the shape #310 used for the exclusion list's counts:
- the README's trigger-path count, against gpu_gate_triggers.txt, as a
  `triggers` case of test_the_readme_states_the_counts_the_list_holds;
- the README's GPU baseline (passed, failed, commit), against gate_gpu.sh's
  BASE_PASSED / BASE_FAILED / BASE_COMMIT, in
  test_the_readme_states_the_baseline_the_gate_holds;
- gate_gpu.sh's worked `4779 + 0 - 49 = 4730`, which a test pinned as the
  literal "4730". It is now derived from BASE_PASSED and BASE_COMPASS_TESTS,
  so a rebaseline that leaves the comment behind reddens.

No longer restated. These either moved with most tasks, were already
wrong at the tip, or repeated a figure that is now joined:
- "130 of 189 test files" in the README and gate_cpu.sh. At 2565b5f it
  is 166 of 225; 130/189 was fada742's census;
- gate_cpu.sh's 30 plugin files and 29 / 28 / 1 exclusions;
- "(130 files)" on two Baselines rows. At 186d128 the tier was 144 files;
- the README's second "30 source paths", the two "five failing node-ids",
  and the numbers in "What the GPU gate expects", now given as constant
  names;
- "190 of this tree's indented imports", in the README and in
  regen_gpu_gate_triggers.sh. It is 205 at the tip, so it is now pinned to
  fada742, where it was measured;
- "removes no path from this tree: 30 triggers with it, 30 without", in
  the regenerator's header template and in the file it wrote. That was
  measured at 236abfd, yet every regeneration stamped it as "this tree".
  It is now pinned to 236abfd;
- "All five" in two gate_gpu.sh comments, and "All five callers" in _lib.sh.

Every scripts/compass/ edit is to a comment or the README. The one change
to gpu_gate_triggers.txt is to a `#` line, which gate_cpu.sh skips.

Closes #311

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* compass(gates): drop the undated gate timings and pin what "this tree" meant

Answers review cycle 1 on #327. Comments, README and one test only; no
executable line of any script changes.

- gate_cpu.sh and the README's gate_cpu.sh row drop "~30 s" / "~31 s". Nothing
  reads either figure, and the merged tree's gate took 183.82 s of pytest.
  _lib.sh drops "~1 s beside the superset's 72 s" for the same reason.
- gate_gpu.sh's 4779 + 0 - 49 = 4730 is now about "such a tree", not the
  integration branch, which has carried tests/compass/ since 4c16792. The
  README, _lib.sh and the surplus test's docstring said the same false thing.
- The regenerator's comment on the header no longer claims every number came
  from this run: it names which counts do, and the template's line citations
  now name 236abfd, where they were measured.
- "The collection probe removes no path" is pinned to 236abfd in the README
  and the regenerator's header instead of "currently" and "this tree".
- The README's 186d128 row is labelled by its commit, not "current".
- The undated "106-file" subtree count is dropped from both places.
- test_the_readme_states_the_baseline_the_gate_holds reads the README row with
  one named-group regex. The three node ids are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <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.

1 participant