ogar-r2il: borrow CallMask's active words (PR2a, mask-ABI half) - #305
Conversation
`CallMask` carried a Boolean algebra (and/or/xor/and_not/not/count) over inline words with no way to read them, so a consumer could only reach the population through `contains`/`set_indices` — per-slot, and the wrong shape for a plane-shaped evaluator. `words()` borrows them, sliced to `len.div_ceil(64)` rather than the full `MASK_WORDS` array. Only `Pairs` (180 calls) fills three words; `Triples` (120) and `Quads` (90) fill two, and their third inline word is a phantom the body never had. Handing it out would give a consumer a word count that disagrees with `len()` — and a consumer clearing its own complement tail against that different count would disagree on the phantom's bits while agreeing on every real one. Wrong-answer shape, not wasted-word shape. Population identity stays outside the words: the bits alone do not say what they index. These are CALL SLOTS WITHIN ONE BODY, at most 180, never row ordinals of a table — a row-population consumer that shares this carrier's algebra shares the algebra, not the index space. Three tests, each two-sided: the slice width is derived from `len` and at least one shape is provably narrower than the carrier (anti-vacuity — with no narrow shape the two readings agree by accident); `words()` matches `contains` bit for bit across a seeded scatter plus every word edge the shape can express; and no bit at or past `len` is ever exposed. No behaviour change to any existing caller. 16/16 lib tests, clippy clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
The tail test derived the straddling word width arithmetically (`len - (words-1)*64`), which underflows the moment the slice is wider than `len` implies -- i.e. exactly the case under test. It went red under the slice disable by PANIC, not by its assertion: detection for the wrong reason, and a false positive for the claim it appeared to prove. Rewritten to read every physically-spanned bit past the population directly. It then stays GREEN under the slice disable -- correctly, since `not` already clears the phantom words per-word, so a wider slice exposes zeros. So it guards `not`, never `words`, and now says so. The agreement test is labelled the same way: it reads only indices below `len`, which sit in the same words under either width, so it falsifies a wrong word index or bit order and nothing about the slice. One claim per test, each with the disable that reddens it named in its own doc comment. Slicing is falsified by the first test alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
`words_exposes_no_bit_at_or_past_len` looped over every bit the slice physically spans past `len` and asserted each was clear. That assertion can never be the one that fires. `count()` reads `self.words` WHOLE (no slice, lib.rs:468), so it already counts phantom bits. Any bit set in 180..192 therefore moves `count`, and the test's own precondition -- `!empty` must have `count == len` -- fails first. Measured against a `not()` disable (tail clearing removed): the test goes red at the precondition, never at the loop. That makes the loop decoration, and the precondition a restatement of the pre-existing `a_complement_never_invents_call_slots`, which catches the same disable. Deleted rather than reworded. What survives carries one disable-verified claim each: `words_is_sliced_to_the_population_not_the_carrier` falsifies the slice width (red when `words()` hands out the full carrier), and `words_agrees_with_contains_bit_for_bit` falsifies word index and bit order. `not()`'s tail discipline stays where it already was. Left standing as a NOTE, not fixed here: `count()` spanning the full carrier means it is not derivable from `words()`. The two agree only because the phantoms are always zero -- which the agreement test pins, and which no caller should assume beyond that. 15/15 lib tests, clippy clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (2)
Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. 📝 WalkthroughWalkthroughThe PR updates repository evidence guidance and adds ChangesEvidence policy
CallMask word access
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Feature Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
A rabbit checks each bit in line Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_4239c725-0b1a-4d92-80af-8e8238469437) |
The probe is workspace-excluded, so every `cargo test` step in this workflow steps past it -- and this repo's own discipline is that an excluded crate without a CI line rots invisibly (measured elsewhere in the fleet: a floating branch dep broken for weeks because no CI built the pair). It is runnable here and nowhere else in CI today: `rust-test.yml` already checks out BOTH siblings the probe needs as siblings of `lance-graph` (`path: ndarray`, `path: OGAR`, `working-directory: lance-graph`), which is exactly the layout `../../../ndarray` and `../../../OGAR/crates/ogar-r2il` resolve against. Placed beside the lance-graph-ogar step, the other OGAR-sibling-armed excluded tier. ORDERING, stated rather than hidden: this step is RED until AdaWorldAPI/OGAR#305 (`CallMask::words()`) merges, because it compiles against the OGAR sibling's default branch. That is a stacked dependency the PR body already names, not a defect in the probe -- and a red step whose cause is on the record beats a green workflow that never ran the test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
The non-negotiable read "grep/sed/tail/head/awk via Bash are prohibited --
use the Grep/Read/Glob tools." It policed which Unix command is typed, not
the failure it was written for, and the failure kept happening through the
sanctioned tools:
SEARCH HIT -> snippet -> meaning assumed -> architecture asserted
SEARCH = 0 -> "it does not exist"
Replaced in place (append-only canon: the old text is quoted under a
supersession marker, not deleted) by the epistemic rule. Search may establish
only "candidates are X, Y, Z" -- never what a type means, what a function
guarantees, that a consumer does not exist, who owns something, or which way
a dependency runs. 0 hits proves nothing; a global negative needs a CLOSED,
explicitly named search space; a partial Read is not evidence for a
whole-file claim; and a search must never be the last tool result before an
architectural conclusion.
sed/head/tail/awk stay prohibited for SOURCE INSPECTION specifically -- a
numeric slice has no semantic boundary -- while limiting a non-search
command's output stays fine, which the old blanket wording forbade and which
the fleet's own guarded-executor contract requires.
Full law + auto-deepen triggers + paging rule + delegation/escalation levels:
lance-graph .claude/knowledge/FIRST-HAND-SOURCE-LAW.md, enforced there by a
PreToolUse guard with a committed two-sided test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_fce17bd8-457b-431d-a4f8-ba384a86ab7a) |
What
One read-only accessor on
CallMask:Plus two tests. No behaviour change to any existing caller.
Why the slice, not the carrier
MASK_WORDSis 3 becausePairsneeds three words. The other shapes do not:PairsTriplesQuadsTriples/Quadshave a third inline word that is a phantom the body never had. Handing it out would give a consumer a word count that disagrees withlen()— and a consumer clearing its own complement tail against that different count would disagree on the phantom's bits while agreeing on every real one. That is a wrong-answer shape, not a wasted-word shape.Population identity stays outside the words
The bits alone do not say what they index: a consumer needs
len()(bit count) andshape()(index space) to read them at all. In particular these are call slots within one body, at most 180 — never row ordinals of a table. A row-population consumer that shares this carrier's Boolean algebra shares the algebra, not the index space.Tests, and one deleted
Two survive, one claim each, each with the disable that reddens it named in its own doc comment:
words_is_sliced_to_the_population_not_the_carrier— width derived fromlen, plus an anti-vacuity assertion that some shape is provably narrower than the carrier (without one, the two readings agree by accident). Red whenwords()returns&self.words.words_agrees_with_contains_bit_for_bit— seeded scatter plus every word seam the shape can express. Labelled an agreement test: it reads only indices belowlen, so it falsifies a wrong word index or bit order and nothing about the width.A third was written and deleted in the same branch.
words_exposes_no_bit_at_or_past_lenlooped over the spanned-but-out-of-range bits — an assertion that can never fire, becausecount()readsself.wordswhole (lib.rs:468, no slice) and so already counts phantoms; any such bit movescountand the test's own precondition fails first. Measured against anot()disable: red at the precondition, never at the loop. Its surviving content restates the pre-existinga_complement_never_invents_call_slots. Deleted rather than reworded.Its first draft also failed for the wrong reason — it derived the straddling word's width as
len - (words-1)*64, which underflows exactly in the case under test, so it went red by panic rather than by assertion. That false positive is what prompted reading the claim properly.Left standing as a note, not fixed here
count()spanning the full carrier means it is not derivable fromwords(). The two agree only because the phantoms are always zero — which the agreement test pins, and which no caller should assume beyond that.Context
The consuming half is the W0B mask-ABI differential in AdaWorldAPI/lance-graph, which proves this carrier's Boolean algebra and
lance-graph-mask-risc's agree bit-identically over these borrowed words. Nothing here delegates and no dependency direction is decided —CallMaskis the oracle in that probe and stays it.That differential cannot live in this repo:
lance-graph-mask-riscpath-depsndarrayat../../../ndarray, a path that leaves its own workspace and can never resolve through a cargo git checkout, and OGAR has no../../..path deps.Gates
15/15
ogar-r2illib tests,cargo clippy --no-deps -- -D warningsclean,cargo fmtclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01GXUahz73MZxtxWcfpHp9dG
Generated by Claude Code
Summary by CodeRabbit
New Features
Documentation