Repository navigation
compass(spec): a saved document merged again does not claim the transfer was asked - #333
Conversation
…fer was asked Issue #331. A merge whose fragments disagree on a method writes `method: mixed` and keeps a transfer's source pin out of the document. So when that saved document is merged again, the new `Merge` has no transfer to check, and `_reach` counted `TRANSFERS` as asked because `merged.transfers` was empty. The same spec that its first merge refused `PINNED_STACK` came back clear with `not_asked == ()`. `_reach` now reports `TRANSFERS` as not asked when a fragment of the `Merge` states `mixed`. When other fragments state a transfer that was asked, it reports `TRANSFERS` as asked in part instead. A re-merged document built from one method, such as all `probed`, still reports the condition as asked. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…not asked, once This covers the branch in `_reach` that defers to `reached` when no stack pin resolved. Without that branch, the condition would be listed as both not asked and asked in part. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| # out of the document. Where none of the pins resolved, `reached` has | ||
| # already reported the condition as not asked. | ||
| hidden = [repr(f.source) for f in merged.fragments if f.method == "mixed"] | ||
| if hidden and not any(c.startswith(TRANSFERS) for c in unasked): |
There was a problem hiding this comment.
Agent-authored (reviewer, cycle 1). F1, blocking. Principle 8, "Every claim carries its measurement": asked_in_part now claims the transfer condition twice.
This guard reads only unasked. When some stack pins resolve, reached(TRANSFERS, STACK_PINS) has already put TRANSFERS into partial. The mixed arm then appends a second TRANSFERS entry to partial.
Measured on node 18 (xiaobizh_n18_cpu). The saved document from the issue table has device.software_pinned_to.rccl deleted, and the transfer fragment sits beside it. Subject: merge([thin, transfer]), with tp_widths=(1, 2, 4, 8) and observed_stack=STACK.
| tree | asked_in_part heads |
|---|---|
tip 91ef04c22 |
[STACK, TRANSFERS] |
head d216950a1 |
[STACK, TRANSFERS, TRANSFERS] |
head, control: an all-probed document in place of the mixed one |
[STACK, TRANSFERS] |
The result is the same whether the transfer is pinned to 7.0.2 or to this stack. The two entries at the head read:
asked_in_part: whether a transferred constant came from a spec pinned to this stack -- `device.software_pinned_to.rccl` did not resolve, so it was asked of the rest and not of those
asked_in_part: whether a transferred constant came from a spec pinned to this stack -- method `mixed` in 'machine.yaml' does not say whether a transfer went into it, ...; it was asked of the transfers stated
This is the same defect the guard exists to prevent, one list over. The test's own comment calls that "says so once". Every existing reader of asked_in_part treats it as one entry per condition, for example (in_part,) = checked.asked_in_part at test_spec_verbs.py:696 and :717. The module's count of reach is per condition too. At the tip this input gave one entry; the diff made it two. The verdict is not affected, because the missing required pin already refuses the document with SHAPE.
Fix, in a new commit, with a test line that is red without it: keep one entry per condition. Either guard on both lists, not any(c.startswith(TRANSFERS) for c in (*unasked, *partial)), which drops the mixed reason in this case, or fold the mixed reason into the partial entry reached already wrote. Which one is the developer's call.
There was a problem hiding this comment.
Agent-authored (developer, round 2). F1: fixed in db0fedba7.
The guard now checks both lists, as you suggested: not any(c.startswith(TRANSFERS) for c in unasked + partial). When reached has already filed TRANSFERS under asked_in_part, the mixed arm adds nothing, so its reason is dropped in that case.
Test. I added one assertion to the existing test, using your input: the saved document with device.software_pinned_to.rccl deleted, and the transfer beside it.
assert sum(c.startswith(TRANSFERS_ASKED) for c in partly.asked_in_part) == 1Measured on node 18 (xiaobizh_n18_cpu), spec suite tests/compass/test_spec_*.py:
| tree | result | where it fails |
|---|---|---|
d216950a1 plus the new test (427f81912, commit-tree) |
1 failed, 292 passed | test_spec_verbs.py:654, assert 2 == 1 |
new head 7c6ded432 with the guard reverted to unasked (ac6431786, 433 lines, one line changed) |
1 failed, 292 passed | :654, assert 2 == 1 |
new head 7c6ded432 |
293 passed |
A direct probe with tp_widths=(1, 2, 4, 8) and observed_stack=STACK gives these asked_in_part heads for this input: tip [STACK, TRANSFERS], d216950a1 [STACK, TRANSFERS, TRANSFERS], 7c6ded432 [STACK, TRANSFERS].
| to it is one no result can report on. | ||
| ask it. Merging the document again does not recover the pin: a merge whose | ||
| fragments disagree on a method states `mixed`, so a `Merge` holding the saved | ||
| document reports the transfer as not asked too. A `validate` verb over a |
There was a problem hiding this comment.
Agent-authored (reviewer, cycle 1). F2, blocking. Principle 8, "Every claim carries its measurement": this new sentence is contradicted by the PR's own test.
The sentence is "so a Merge holding the saved document reports the transfer as not asked too". That holds only when no other fragment of the Merge states a transfer. When one does, the diff deliberately files the condition under asked_in_part, and the new test asserts exactly that (beside, test_spec_verbs.py:645-647).
Measured on node 18 at head d216950a1. merge([saved, transfer]) gives not_asked=[] and asked_in_part=[TRANSFERS], and is refused PINNED_STACK.
The fix is one clause, for example: "...reports the transfer as not asked too, or as asked only in part when another fragment states a transfer."
There was a problem hiding this comment.
Agent-authored (developer, round 2). F2: fixed in db0fedba7, then made exact in 7c6ded432.
The sentence now reads: "...so a Merge holding the saved document reports the transfer as not asked too, or as asked only in part when another fragment states a transfer and a stack pin resolved."
The "and a stack pin resolved" part came from a probe on node 18. With a transfer beside the saved document and no stack pin, the condition is reported as not_asked, not asked_in_part. Your one-clause wording would have been false in that case. The heads at 7c6ded432:
| saved document | alone | transfer beside it |
|---|---|---|
| all pins | not_asked=[TRANSFERS] |
asked_in_part=[TRANSFERS] |
rccl deleted |
not_asked=[TRANSFERS] |
asked_in_part=[STACK, TRANSFERS] |
| no pins | not_asked=[STACK, TRANSFERS] |
not_asked=[STACK, TRANSFERS] |
Each cell in the "transfer beside it" column is asserted in the test: beside, partly and nowhere.
| # one, so a saved document merged again does not say whether a | ||
| # transfer went into it, and the merge kept that transfer's source pin | ||
| # out of the document. Where none of the pins resolved, `reached` has | ||
| # already reported the condition as not asked. |
There was a problem hiding this comment.
Agent-authored (reviewer, cycle 1). F3, non-blocking. Principle 8. "Where none of the pins resolved, reached has already reported the condition as not asked" is true only when merged.transfers is non-empty. That is the only case in which reached is called.
With no transfer and no pins, reached never ran. The mixed arm is then the one that reports the condition, which is the right behaviour. The sentence reads as unconditional, and it says nothing about the partial-pin case in F1. Suggested wording: "Where a transfer is stated and none of the pins resolved, ...".
There was a problem hiding this comment.
Agent-authored (developer, round 2). F3: fixed in db0fedba7.
The comment now reads: "Where a transfer is stated and a pin did not resolve, reached has already reported the condition once."
That is the only case in which reached(TRANSFERS, ...) runs and reports anything. With no pins it reports not_asked, and with some pins it reports asked_in_part. The new guard defers to either. This comment also replaces the three lines the ponytail shrink: flagged, so the comment block goes from 5 lines to 2.
|
|
||
|
|
||
| def test_a_saved_document_merged_again_does_not_claim_to_have_asked_the_transfer(): | ||
| # Issue #331. The first merge is refused and writes `method: mixed`, which |
There was a problem hiding this comment.
Agent-authored (reviewer, cycle 1). F4, non-blocking. Two problems with this comment.
-
Principle 8, wording. "The first merge is refused" is not accurate.
merge()succeeds and returns aMerge, and it isvalidateof thatMergethat is refusedPINNED_STACK. "Writesmethod: mixed, which drops the transfer" also runs two separate mechanisms together:merge.py:285keeps the transfer's source pin out of the document;mixeddrops the record that a transfer went in at all.
Suggested wording: "Validating the first
Mergeis refused. Its document keeps the transfer's source pin out and says onlymethod: mixed, so ...". -
AI_DEV_RULES, "No design-doc references in code ... Say what the code does." "Issue compass(spec): a saved document merged again reports the transfer condition as asked #331." is the only
#NNNcitation in the spec file set:atom/compass/spec/*.py,tests/compass/test_spec_schema.pyandtests/compass/test_spec_verbs.py. At the tip, after compass(spec): say what the code does, not which task or design wrote it #325's clean-up ("say what the code does, not which task or design wrote it"), that file set had none. The rule's list does not name issue numbers explicitly, so this is non-blocking. Dropping the two words costs nothing.
There was a problem hiding this comment.
Agent-authored (developer, round 2). F4: fixed in db0fedba7.
I used your wording, and "Issue #331." is gone. The comment now reads:
Validating the first
Mergeis refused. Its document keeps the transfer's source pin out and says onlymethod: mixed, so aMergeof the saved document has no transfer to ask the condition of. A re-merged all-probeddocument is the control.
git grep -nE "#[0-9]{3}" 7c6ded432 over atom/compass/spec/*.py, tests/compass/test_spec_schema.py and tests/compass/test_spec_verbs.py finds no match (rc 1).
|
Agent-authored (reviewer, cycle 1). Principles read first: Verdict: REQUEST_CHANGES on head
The inline findings are F1 at Everything below was run on node 18 in 1. The named result reproduces
The table's rows. Each was probed directly with
2. Ruling on the fix shape (principle 6, "Refuse rather than fall back")Keying on
Measured at tip and head:
No path a merge writes hides a transfer under another method string. The residue is a hand-edited method, and the PR body already states it. The known cost is acceptable. Re-merging a Option (a) is outside the file set as claimed. Asking the condition needs the transfer's source pin. The provenance fields are Out of scope, recorded here and not caused by this PR. A saved 3. No existing refusal or
|
| sentence | measured |
|---|---|
PR body: validate.py +27/−7, code +19/−2; tests +33 |
true. diff --stat gives 27/7 and 33. Code is :270-288 (19 lines) against the tip's 2-line elif. |
PR body: merge.py:285 keeps the source pin out |
true |
| PR body: (b) as worded turns the null control red | true (mutant above) |
PR body: no existing test validates a Merge holding a mixed fragment |
consistent with the byte-identical validate record |
docstring :55-57: "a Merge holding the saved document reports the transfer as not asked too" |
false when a transfer is beside it. That case gives asked_in_part, which the PR's own beside assertion checks. F2 |
comment :273-276: mixed is what a merge writes on disagreement, and the pin is kept out |
true |
comment :276-277: "Where none of the pins resolved, reached has already reported…" |
true only when a transfer is stated. F3 |
test comment :627: "The first merge is refused and writes method: mixed, which drops the transfer" |
imprecise: merge() is not refused, and mixed is not what drops the pin. F4 |
test comments :644 and :649 |
true (rows above) |
F1 is inline on validate.py:279. Some pins resolved, plus a transfer beside a mixed document: tip asked_in_part=[STACK, TRANSFERS], head [STACK, TRANSFERS, TRANSFERS], control [STACK, TRANSFERS].
5. ponytail-review
atom/compass/spec/validate.py L273-275: shrink: the comment restates the docstring sentence the diff added at L55-57 (mixed = fragments disagree; the merge keeps the pin out). Keep only the guard sentence at L276-277.
tests/compass/test_spec_verbs.py: lean; four scenarios plus a control, each asserted once.
net: -3 lines possible.
6. Gate on the merged tree
- Tip, read again:
fork/feature/atomcompass_newwas91ef04c22558ba44b21806c262798aec790cccb0, unmoved. - Merged tree:
git merge-tree --write-tree 91ef04c22 d216950a1gives6aa5fa86ad4100087a1bce8e0eeb67d1294dee39, which equalsd216950a1^{tree}. - Stamp:
git commit-treeproduced9258b14aa28d5e8c61ee6702bd70d95b618ca03e, with parents the tip and the head. Its tree is6aa5fa86a..compass-changedholds the two PR files. - Gate scripts: the tree's own
scripts/compass/gate_cpu.sh.scripts/compassisba78568c8at both tip and merged. - Printed stamps: the gate printed
commit: 9258b14aa (stamp)andatom: /tmp/pr333r1/stage/merged/ATOM/atom/__init__.py. - Run: one gate, bounded by
timeout -k 10 2400, unpiped, with the load average at 16.
| tree | passed | skipped | xfailed | junit cases | GATE_CPU_RC |
|---|---|---|---|---|---|
merged 9258b14aa (tree 6aa5fa86a) |
5238 | 155 | 3 | 5396 | 0 |
This matches the developer's head numbers: 5238/155/3 and 5396 cases, against a tip of 5237 and 5395. The new node id is present in the junit. No timing-class test failed, so none needed a re-run.
What the next task in this area should watch
- The re-read transfer refusal wording in section 2.
- A future
compass spec validate machine.yamlverb will hit exactly thismixedpath. Its test should assertnot_asked, not onlyok.
🤖 Generated with Claude Code
When some stack pins resolve, `reached` has already filed `TRANSFERS` under `asked_in_part`. The `mixed` arm checked only `unasked`, so it added a second `TRANSFERS` entry to `asked_in_part`. The guard now checks both lists, and the test asserts one entry for a saved document with one stack pin deleted and a transfer beside it. The module docstring now also covers the case where another fragment states a transfer: the condition is then asked only in part. The comment above the guard no longer repeats the docstring, and it says `reached` has reported the condition only when a transfer is stated. The test comment says it is `validate` of the first `Merge` that is refused, not the merge itself, and it no longer cites the issue number. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n part With another fragment stating a transfer, a `Merge` holding the saved `mixed` document reports the transfer condition as asked in part only when a stack pin resolved. With no stack pin, it reports the condition as not asked at all. The `nowhere` assertion in the test already checks that case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Agent-authored (developer, round 2). Principles read first: Developer round 2: new head
Findings
Named result (node 18,
|
| tree | commit | spec suite | fails at |
|---|---|---|---|
d216950a1 plus the new test file |
427f81912 |
1 failed, 292 passed | :654, the F1 assertion: assert 2 == 1 |
| new head | 7c6ded432 |
293 passed | |
new head, F1 guard reverted to unasked |
ac6431786 |
1 failed, 292 passed | :654, assert 2 == 1 |
new head with the tip's validate.py |
4960c4b1a |
1 failed, 292 passed | :643, assert [] == ['whether a t...o this stack'] (the row-3 again.not_asked) |
new head without the no-pin guard (if hidden:) |
ff65207d0 |
1 failed, 292 passed | :654, assert 2 == 1. This now fails on the new F1 line, which runs before nowhere. At d216950a1 it failed on nowhere.asked_in_part == (). |
new head with the partial arm sent to unasked (the mixed arm's if merged.transfers: becomes if False:) |
d637df726 |
1 failed, 292 passed | :648, the beside asked_in_part assertion: assert [] == [...] |
new head keyed on "provenance.fragments" in f.values |
5450ad5da |
1 failed, 292 passed | :663, the null control: assert ('whether a t... a document',) == () |
Every cycle-1 mutant keeps its verdict.
Spec-suite outcome diff, -rA. The tip b63f1a711 has 292 node ids, all passed. The merged tree has 293, all passed. The diff is one line:
> PASSED tests/compass/test_spec_verbs.py::test_a_saved_document_merged_again_does_not_claim_to_have_asked_the_transfer
F1 added an assertion, not a new node id.
Gate on the merged tree
- Tip, read again:
fork/feature/atomcompass_newis nowb63f1a711469007dfba903bfba90c50236bf1dd2. It moved by compass(tests): refuse any reply-scan root set but REPLY_SURFACE, and read relative engine imports #326, which changes onlytests/compass/test_runner_rpc_surface.pyand does not touchscripts/compass. - Merged tree:
git merge-tree --write-tree b63f1a711 7c6ded432gives170da7165c126432587547267584986209e98b5a, with no conflict. It differs from7c6ded432^{tree}(6cb437ccb) by compass(tests): refuse any reply-scan root set but REPLY_SURFACE, and read relative engine imports #326's file. - Stamp:
git commit-treeproduced4789afd51d37a7ecd16e720b01183a8b16652025, with parents the tip and the head..compass-changedholds the two PR files. - Gate script: the tree's own
scripts/compass/gate_cpu.sh. It printedcommit: 4789afd51 (stamp)andatom: /tmp/i331r2/merged/ATOM/atom/__init__.py. - Runs: one at a time, each bounded by
timeout -k 10 2400, unpiped.
| tree | passed | skipped | xfailed | junit cases | GATE_CPU_RC |
|---|---|---|---|---|---|
tip b63f1a711 (control) |
5238 | 155 | 3 | 5396 | 0 |
merged 4789afd51 (tree 170da7165) |
5239 | 155 | 3 | 5397 | 0 |
Node-id delta from junit: one line, + tests.compass.test_spec_verbs::test_a_saved_document_merged_again_does_not_claim_to_have_asked_the_transfer passed. Every timing-class test passed on the merged tree, so none needed a re-run: TestTheRegionIsNotCopiedPerChunk (4), TestNoSizeAtWhichACallStopsBeingOne::…[minimax] (2) and test_freezing_twice_is_additive_and_harmless.
Lines this round (d216950a1..7c6ded432)
| added | removed | |
|---|---|---|
production (validate.py) |
10 (7 docstring, 2 comment, 1 code) | 12 (6 docstring, 5 comment, 1 code) |
tests (test_spec_verbs.py) |
10 (4 comment for F4, 6 for the F1 assertion) | 3 (F4 comment) |
That is 20 added and 15 removed. The brief estimated 10–20, so this is under 2x.
🤖 Generated with Claude Code
|
Agent-authored (reviewer, cycle 2). Principles read first: Verdict: APPROVE on head
Everything below ran on node 18 in
1. Reproduction (principle 8, "Every claim carries its measurement")Each mutant is a copy of the head tree with one line of
All four cycle-1 mutants are still red. The lines match the developer's table. M2 now fails first at the F1 line ( 2. The 3×2 pin-state probe, and the docstring clauseEvery call used
The first two columns match the developer's inline reply cell for cell. At The docstring clause is true in both directions. The clause is: "a
That is 96 cases. The expected placement follows from the fields alone:
On top of that, no condition head may appear twice across the two lists.
That includes 0 mismatches of the docstring predicate over the 32 single- 3. The one-line change cannot drop a condition
I tried to make it drop one. Every case where
This is the sweep above, 0 violations. The all- Accepted with reservation (non-blocking, no action; principle 8, "Every claim carries its measurement"). When pins partly resolve and a transfer is stated beside a 4. Truth checks on every reworded sentence (principle 8)
No design-doc or issue references. Ruff. 5. ponytail-review over
|
| tree | passed | skipped | xfailed | junit tests | GATE_CPU_RC |
|---|---|---|---|---|---|
merged 9924f2433 (tree 170da7165) |
5239 | 155 | 3 | 5397 (0 failures, 0 errors) | 0 |
- Against the developer's numbers: this matches their merged run (5239/155/3, 5397 cases, rc 0). Their tip control was 5238, so the difference is +1, the new node id, which is present in my junit.
- Timing classes: every one passed, so none needed a re-run:
TestTheRegionIsNotCopiedPerChunk(4 cases),TestNoSizeAtWhichACallStopsBeingOne(12 cases, both[minimax]cases included) andtests/test_gc_utils.py::test_freezing_twice_is_additive_and_harmless.
What the next task in this area should watch
- Section 3's reservation: the surviving
asked_in_partentry names the pin reason and not themixedone. - Cycle 1's two notes still stand:
- the wording of the refusal on a re-read transfer;
- a future
compass spec validate machine.yamlverb should assertnot_asked, not onlyok.
🤖 Generated with Claude Code
…held by tests (#493) Adds two behaviour tests to tests/compass/test_spec_schema.py. One asserts that spec/machine.py::_walk raises the first refusal it meets: any later refusal fails it. The other asks MachineSpec.runtime_constant for a width table a fragment lacks, reaching the second read site, and asserts SpecRefusal with Rule.TOTALITY instead of a bare KeyError. The reached(STACK, ...) and reached(TRANSFERS, ...) calls in spec/validate.py needed nothing: tests from #183 and #333 already go red when either is deleted. Each reinstated defect goes red on its named test (1 failed / 297 passed against 298). CPU gate on node 18 over the combined tree with c0f6419: 5209 passed, rc 0. Closes #243 Closes #249 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Closes #331
What changes
When a saved document is merged again,
validateno longer says it asked the transfer condition if it had nothing to ask it of._reachinatom/compass/spec/validate.pynow treats aMergefragment whoseprovenance.methodismixedas one that may hide a transfer:TRANSFERSgoes innot_asked, and the reason names the fragment.TRANSFERSgoes inasked_in_part. That transfer is still checked by_transfersand can still be refused.reachedhas already listedTRANSFERSonce. That is undernot_askedwhen no pin resolved, and underasked_in_partwhen some did. Themixedarm adds nothing, so no condition is listed twice.merge.pyis not touched.Fix shape: (b), narrowed to
method: mixedWhy not (a). A merge keeps a transfer's source pin out of the document on purpose (
merge.py:285). So a re-merge has nothing to check the transfer against. Recording transfers in provenance would mean recording each source pin, and that needs a new schema field infields.py. That file is outside the file set, and the change would be well past 40 lines. With the pin gone, the honest result is "not asked, and here is why", not a check against a stand-in. That is refuse-rather-than-fall-back.Why narrow (b). (b) as the issue words it keys on
provenance.fragments. Every merged document states that field, including a re-merge of an all-probeddocument that holds no transfer. I measured it as a mutant,a8186d6a3: the head with only thehiddenpredicate changed to"provenance.fragments" in f.values. The null control goes red:Only a
mixedfragment can hide a transfer:probedmeans nothing was transferred.transferred-from:Xmakes the re-merged fragment a transfer in its own right, andMerge.transfersalready asks it.mixedabsorbs later merges, so the ambiguity survives any number of re-merges.Keying on the method is also the simpler predicate.
Known cost, measured below. A
mixeddocument with no transfer, such as datasheet plus probed, now reportsTRANSFERSas not asked when it is merged again. That is true: nothing in such a document says a transfer did not go into it.Named result (node 18,
xiaobizh_n18_cpu)The new test is
tests/compass/test_spec_verbs.py::test_a_saved_document_merged_again_does_not_claim_to_have_asked_the_transfer. Measured at head7c6ded432(round 2). Each mutant is the head with onlyvalidate.pychanged, built withcommit-tree.7c6ded432d216950a1plus the new test file427f81912:654,sum(… partly.asked_in_part) == 1:assert 2 == 1unasked + partialtounaskedac6431786:654:assert 2 == 1validate.py(git show 91ef04c22:…, 415 lines)4960c4b1a:643,again.not_asked:assert [] == ['whether a transferred constant came from a spec pinned to this stack']if hidden:)ff65207d0:654:assert 2 == 1unasked(if False:)d637df726:648,beside.asked_in_part5450ad5da:663, the null control, shown aboveThe rows below were probed at round 1. At
7c6ded432, with a transfer beside the saved document,asked_in_partis[TRANSFERS]with all pins,[STACK, TRANSFERS]withrccldeleted (d216950a1gave[STACK, TRANSFERS, TRANSFERS]), andnot_askedis[STACK, TRANSFERS]with no pins.The rows, probed directly with
tp_widths=(1, 2, 4, 8)andobserved_stack=STACK. Theatom.__file__printed under each staged root.91ef04c22d216950a1MergePINNED_STACK,not_asked=[]combination.documentnot_asked=[TRANSFERS]merge([Fragment.from_mapping(combination.document, "machine.yaml")])not_asked=[]not_asked=[TRANSFERS]PINNED_STACK,asked_in_part=[]PINNED_STACK,asked_in_part=[TRANSFERS]probedmerged().documentnot_asked=[]not_asked=[]mixeddocument with no transfer (datasheet plus probed)not_asked=[]not_asked=[TRANSFERS](the known cost above)The spec-test outcome diff,
tests/compass/test_spec_*.py, tip to headWith
-rA, 292 node ids at the tip and 293 at the head. Every one passed.No existing test's refusal or
not_askedtext changes. Every node id present at the tip has the same outcome at the head, and no existing test was edited. No existing test validates aMergethat holds amixedfragment.Gate 1:
scripts/compass/gate_cpu.sh, the tree's own copy, stampedThe trees were staged by
git archiveanddocker exec -i … tar -xinto/tmp/i331/{tip,head}/ATOM. The md5 matched on both ends, and.compass-commitand.compass-changedcame from the samerev-parse. Each side ran twice. The second run added--junitxmlto get per-node outcomes.GATE_CPU_RC91ef04c22(control)d216950a1Node-id delta from junit: 5395 cases at the tip, 5396 at the head. The only difference is
+ tests.compass.test_spec_verbs::test_a_saved_document_merged_again_does_not_claim_to_have_asked_the_transfer passed. No timing-class test moved.git merge-tree --write-tree 91ef04c22 d216950a1gives6aa5fa86ad4100087a1bce8e0eeb67d1294dee39, which equalsd216950a1^{tree}.Round 2, on the merged tree. The tip moved to
b63f1a711(#326, one test file outside this PR).git merge-tree --write-tree b63f1a711 7c6ded432gives170da7165c126432587547267584986209e98b5a, stamped as4789afd51withcommit-tree.GATE_CPU_RCb63f1a711(control)4789afd51The node-id delta is the new test only.
Lines
validate.py), whole PRtest_spec_verbs.py), whole PRRound 1 was +53 against an estimate of 20–40. Round 2 was +20/−15 against 10–20. Neither is over 2x, so neither is an escalation.
Dev record
provenance.fragments. I narrowed it tomethod: mixed, and the mutant above records why.mixedfragment is reported as asked in part, not unasked. The transfer that was asked can already have earned a refusal, and the module's docstring forbids filing that under "not asked".asked_in_partlistedTRANSFERStwice. The guard now reads both lists. F2: the docstring clause says "and a stack pin resolved", because with no stack pin a transfer beside the saved document is reported as not asked, not as asked in part.method: mixedis treated the same way. A free-text method such asdatasheet+probeis not recognised as possibly hiding a transfer. No merge writes that form.🤖 Generated with Claude Code