Skip to content

v0.82 R14NARROW follow-up (#1484): the rule written to stop conjunction defects was one - #1488

Merged
avrabe merged 1 commit into
mainfrom
lane/v0.82-r14narrow
Oct 8, 2026
Merged

avrabe merged 1 commit into
mainfrom
lane/v0.82-r14narrow

Conversation

@avrabe

@avrabe avrabe commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

The rule written to stop conjunction defects was one

R14 shipped in #1486 keying on the whole INCOMPLETE set, which made it looser than its
sibling by six of seven tokens
. verdict_prose_check reds an incomplete prose verdict beside
a claiming status with no disposition: for every token except LEGAL_BESIDE_CLAIMING, which
has exactly one member, REFUTED. R11 forbids the disposition: that would satisfy
verdict_prose beside a claiming status. So for those six tokens there is no legal claiming shape
at all, and R14 firing there told authors to add a declaration when the only correct answer is
to stop claiming.

Measured, not argued: INCOMPLETE has 7 members, LEGAL_BESIDE_CLAIMING has 1, so the two
gates disagreed on 6 — and this release pushed PARTIAL + implemented + issue-scope: outlives,
which satisfied R14 and reddened Claim Check, a required context, on #1487.

Narrowed to the carve-out, imported as the same object

R14 now fires only where verdict_prose is SILENT and a claiming status AUTHORISES closure —
exactly v0.81's near-miss shape, REFUTED beside implemented with no declaration. The
vocabulary is imported, and a test asserts object identity (assertIs) rather than equality,
so a second copy cannot drift in.

And the safer shape is now pinned by a test

Nothing in the repo pointed at it:

status: proposed   disposition: partial   landed: <names the delivering PR>   issue-scope: OMITTED

Under that shape the issue is never placed in the authorised close set at all, where the
claiming shape authorises retirement and then takes it back with a second field.

Three mutants, each killed by the test that owns it

mutant result
R14 disabled the two red-first tests fail
R14 widened back to INCOMPLETE the carve-out test and the identity test fail
as shipped 128 tests OK

Gates on this branch: status_evidence rc=0, verdict_prose 0 disagree over 67, claim_check
75/75, test_status_evidence_check 128 OK. Squash simulation pre-checked off origin/main:
rc=0, 0 FAIL lines.

Refs #1484

🤖 Generated with Claude Code

https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L

…on defects was one

R14 shipped keying on the whole INCOMPLETE set and was therefore LOOSER THAN ITS SIBLING BY
SIX OF SEVEN TOKENS. `verdict_prose_check` reds an incomplete prose verdict beside a claiming
status with no `disposition:` for every token EXCEPT `LEGAL_BESIDE_CLAIMING`, which has exactly
ONE member, REFUTED. R11 FORBIDS the `disposition:` that would satisfy verdict_prose beside a
claiming status. So for those six tokens there is no legal claiming shape at all, and R14
firing there told authors to ADD A DECLARATION when the only correct answer is TO STOP
CLAIMING. A rule written to catch "two rules whose conjunction is false" was one.

Measured, not argued: INCOMPLETE has 7 members, LEGAL_BESIDE_CLAIMING has 1, so the two gates
disagreed on 6 — and this release pushed `PARTIAL` + `implemented` + `issue-scope: outlives`,
which satisfied R14 and reddened `Claim Check`, a REQUIRED context, on #1487.

NARROWED to the carve-out, IMPORTED as the same object (asserted by identity, not equality):
R14 now fires only where `verdict_prose` is SILENT and a claiming status AUTHORISES closure —
which is exactly v0.81's near-miss shape, REFUTED beside implemented with no declaration.

AND THE SAFER SHAPE IS NOW PINNED BY A TEST, because nothing in the repo pointed at it:

  status: proposed   disposition: partial   landed: <names the delivering PR>   issue-scope: OMITTED

  R4-lane      satisfied by `landed:` — its message is a DISJUNCTION, "flip the status OR
               record the increment" — provided the text names the PR `_acknowledge` derives,
               which is `PR_NUMBER.findall(subject)[-1]`, the number the SQUASH appends
  R11          a `disposition` IS present beside a NON-claiming status
  R12          `outlives` beside non-claiming would RED, so `issue-scope` is omitted
  verdict_prose incomplete + non-claiming passes; no carve-out needed
  R14          out of population
  R3           cannot fire on a `manual:` done-when

Under that shape the issue is NEVER placed in the authorised close set, where the claiming
shape authorises retirement and then takes it back with a second field.

THREE MUTANTS, each killed by the test that owns it:
  * R14 disabled            -> the two red-first tests fail
  * R14 WIDENED back to INCOMPLETE -> the carve-out test AND the identity test fail
  * as shipped              -> 128 tests OK

Refs #1484

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
@avrabe
avrabe merged commit 39fd822 into main Oct 8, 2026
72 of 73 checks passed
@avrabe
avrabe deleted the lane/v0.82-r14narrow branch October 8, 2026 08:49
@codecov

codecov Bot commented Oct 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

avrabe added a commit that referenced this pull request Oct 8, 2026
…s a guard that could not fail (#1493)

Round 1 ran against a pinned detached worktree and found SIX false statements and nine
imprecisions across the release's artifacts, re-deriving ~175 numbers. Every finding acted on
here was RE-VERIFIED independently rather than taken on report, and two of round 1's own
citations were wrong and are corrected to what the source says.

F6 IS THE ONE THAT MATTERED, because it is a safeguard that could not fire. compliance.yml's
externals-sync step reported `synced N of N` with rc=0 while every external directory was
EMPTY -- the single condition it was written to refuse. Two independent causes:

  - `dest.exists()` treated directory EXISTENCE as a synced external, so an empty or partial
    `.rivet/repos/<prefix>` counted;
  - the non-vacuity check compared `len(cloned)` against `len(ext)`, and `cloned` was APPENDED
    TO BY THE LOOP IT GUARDED. A counter the loop increments can only ever equal the
    population, so the refusal was UNREACHABLE BY CONSTRUCTION.

The fix re-derives the count by READING THE FILESYSTEM BACK after the loop, giving the check a
source independent of the thing it checks, and `resolved()` now requires a git dir AND an
artifact-bearing file. Gated by `scripts/test_compliance_sync.py`, which extracts the SHIPPED
heredoc from the workflow rather than a copy: red-first 2/4, green 5/5, and POTENCY-CONTROLLED
against the pre-fix script from git (2 cases flip). Wired into `claim-check`, a REQUIRED
context -- a check in no workflow is not a gate.

MY FIRST GREEN ON THAT ORACLE WAS TRUE ABOUT THE WRONG SUBJECT and is recorded because it
nearly certified the fix vacuously: the red-first case passed because `example.invalid` failed
DNS, not because the resolution check fired. Rewritten with LOCAL git repos so clone outcomes
are deterministic and the two refusals are DISTINGUISHABLE.

THE OTHER FIVE.

F1 WIDEFILE5 carried a sibling lane's instrument error as its own. The truncated-grep anecdote
about `9.81f`/`0xf5c3` is #1436's gravity constant; `0xf5c3` occurs in exactly three files and
#1439's own fixture contains ZERO of either string.

F2 CLOSEARM described a rule WIDER than the one it shipped: it said R14 reds an INCOMPLETE
verdict beside a claiming status, but R14's `LEGAL_BESIDE_CLAIMING` has ONE member, `REFUTED`
-- narrowed by #1488 IN THIS RELEASE, with this artifact not updated alongside. The other six
INCOMPLETE tokens are still red, by verdict_prose and R11 rather than by R14. The correction
is to the attribution, not the outcome.

F3 FIRSTTOKEN's "THIRTEEN artifacts out of population" does not reproduce, and the lane's
REFUTED verdict rested on it. Re-derived with the gate's own `artifacts()`/`classify()`: it
drops TWENTY-SEVEN of 78. SIX of the thirteen named cannot be dropped by any negator rule --
their first sentence is a bare verdict word. The refusal is UNCHANGED AND STRONGER: losing 27
to close a hole on 3 is a worse trade than the one originally described, so the wrong number
understated the case. The same false claim was ALSO in verdict_prose_check.py's own comment
block; corrected there too, because the fact matters and not the cited site.

F4 BAZELPOTENCY said 73 job keys; loading ci.yml and counting `jobs` gives 71.

F5 DEPS claimed v0.40.0 exposed an `offline` input 0.39.0 did not. The two action.yml files are
BYTE-IDENTICAL -- 14745 bytes, same sha256 -- and `offline` appears four times in v0.39.0. That
claim was already absent from the withdrawal rewrite; recorded in #1492's body because a commit
message cannot be amended without discarding a completed CI run.

AND A STALE FIGURE OF MY OWN, which is a class worth naming: this artifact said "50 of 54
completed jobs failed" about run 37790630310. That run KEPT GOING after I measured it. A count
of a LIVE object is true only at an instant. The final figures, frozen by cancelling the run to
free a starved runner pool: 63 of 68 non-cancelled jobs failed across FOUR labels, including 13
`rust-cpu`. Five jobs survived and NOT ONE COMPILES synth -- Format, Version Pin Sweep, Claim
Check, Rivet Validation and Advisories are all metadata-level, and two of them are `rust-cpu`,
so the discriminator is what a job DOES, not which pool it runs on. Checking that nearly cost
the diagnosis: a grep for `cargo` reported build steps in all five, matching "Cache Cargo
dependencies" and "Install cargo-deny". Reading the step names settled it. UNIVERSAL holds.

NINE IMPRECISIONS, the load-bearing ones: PAGESIZE4's memory.size enumeration was wrong in both
directions -- two of its four sites are a comment line and an immediate-load rather than a shift
of R10, and the class is not ARM-only. A FIRST correction here claimed "9 files / 18 sites" from
a grep that swept in MOVT high-halfword extraction, which converts nothing -- the exact
mischaracterisation the row exists to fix. Corrected by READING each site: arm_encoder.rs:1758
and :3830 are the only runtime LSR #16 on R10; RV32 selector.rs:3312 and AArch64
selector.rs:2557/:2596 carry their own compile-time conversions. VALUELESSKEY's tripwire covers
TWO gates, not the four it converted, and `Claim Check` -- a required context -- holds the fix
with neither a test nor tripwire coverage; named rather than closed, because widening that
population owes its own red-first evidence. Plus FIRSTTOKEN's counts now stated WITH their
commit, `wat` corrected to 1.261.0, and PAGESIZE4's carried family at six releases not five.

ONE ADJACENCY BROKEN DEFENSIVELY: CLOSEARM's theme prose read "entitled the tag to clos{e}
#1436" and now reads RETIRE. A full sweep found EIGHTEEN such adjacencies in tracked files
dating to v0.64, and they are harmless -- `test_verdict_prose_check.py` carries one naming
#1476, which is on main and still OPEN, proving committed file content is not a closure vector.
The other seventeen are left alone deliberately. The obligation is forward-only, on prose that
gets quoted into messages and bodies, where it would become one.

Gates at this tree: cargo fmt rc=0, status_evidence rc=0, verdict_prose rc=0 (78 artifacts, 0
disagree), claim_check 75/75, check_version_pins rc=0, test_compliance_sync 5/5.

Refs #1453 #1458 #1476 #1484 #1439 #1441 #1456 #965


Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L

Co-authored-by: Claude Opus 5 <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