Skip to content

probe(contract): WordNet 4⁴ fold makes HHTL adjacency semantic — 2.47 hops the 16-ary router cannot address - #875

Merged
AdaWorldAPI merged 6 commits into
mainfrom
claude/x265-x266-plans-review-h9osnl
Jul 31, 2026
Merged

probe(contract): WordNet 4⁴ fold makes HHTL adjacency semantic — 2.47 hops the 16-ary router cannot address#875
AdaWorldAPI merged 6 commits into
mainfrom
claude/x265-x266-plans-review-h9osnl

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Tests the operator's claim that "wordnet makes CLAM HHTL spacial activation via 4^4", and the message before it: "4^4 would be a sparse adjacent if the sentence refers to out of bounds meaning".

Why WordNet changes the question

A codebook has to discover ancestry with k-means and hope it survives — that is PROBE-CODEBOOK-44, and its real-data leg is capped by a Base17 fold ceiling (ρ≈0.26 on single words) independent of the codebook. WordNet's @ hypernym relation is ground-truth ancestry, so the address does not discover structure, it encodes it. No embeddings, no k-means, no API key on the critical path. The question sharpens to: given real taxonomic ancestry, does a fixed 4-ary depth-4 fold preserve enough semantic distance to be a search prior — and does 4-ary buy anything the shipped 16-ary NiblePath cannot express?

Measured — WordNet 3.1, 82,192 noun synsets, root entity, 65,292 leaves, depth 19

gate result
W1 ancestry-by-construction corr(shared address levels, LCA depth) real +0.4938, shuffled −0.0356
W2 monotone ladder 15.78 → 12.76 → 11.15 → 8.69 → 7.05 hops across rungs 0→4; strictly decreasing, spread 8.73
W3 spatial activation (twin-tested) out-of-cell recall over the full corpus: band 0.763 vs random-12 0.031 = 24.71×; silent half = the random arm's inertness
W4 sub-nibble structure inside one top nibble the 16-ary router sees ONE bucket (10.55); 4-ary splits it 11.15 vs 8.69 = 2.47 hops
W5 fold balance 256/256 cells used, occupancy 29 / 255 / 1270 (min/median/max)

W4 is the headline — it answers "not sure if that's a thing in our substrate" with a number. NiblePath (FAN_OUT = 16) expresses two levels per byte and is blind inside a top nibble; the 4-ary address splits that same population by 2.47 WordNet hops. That is what makes a graded escalation band implementable: 3 siblings × 4 levels = 12 of 256 cells (4.7 %), where 16-ary offers 15 siblings or nothing.

Worked example: dog @ cell 0x5a (01|01|10|10) → nearest in-band foster-brother(3), macho(3), man(3), mother's_son(3), sirrah(3), Adam(4); best distance outside the band = 4 hops.

Every defect found was in a FALSIFIER, never in a measurement

Six review rounds (codex ×3, CodeRabbit ×3, plus self-caught). The measurements held up every time; the machinery meant to be capable of killing them did not. A broken falsifier fails silently — it reports PASS. That is the most portable thing in this PR.

  1. The first fold reproduced the le-contract's own warning in my code. Expanding each level to exactly ARITY roots before balancing gave one cell 15,769 leaves against a median of 20"lacking proper bucket rollover … saturates silently". Fixed with an explicit granularity knob (ARITY·24). Arity alone does not balance a fold of a real taxonomy.
  2. The W1 falsifier could not falsify. A cell-label permutation is a bijection, so same-cell pairs survive it — the shuffle arm scored +0.645 on cell identity alone while looking like validation. Both arms now exclude same-cell pairs; shuffled collapses to −0.036.
  3. W3 was mislabelled and arithmetically mis-specified. Pool sampled with replacement, nearest-32 taken without dedup. Worse: both arms credited the anchor's own cell, inflating the baseline to 0.621 — capping the achievable ratio at 1/0.621 = 1.61 while the fire-half demanded >1.5 and the cover guard demanded <0.95. An 0.018-wide window; the original 1.50× pass was luck. After dedup it read 1.44× and correctly failed.
  4. The pool was still only 31 % of the corpus (20,000 of 65,292), so "the 32 nearest neighbours" meant "within a sample" — an omitted leaf can be strictly closer, moving both the cutoff and the cells. Fixed by scoring all 65,292 rather than relabelling the caveat.
  5. The twin gate was still incoherent after that: the fire half measured out-of-cell recall while the cover guard measured the all-neighbour statistic just declared wrong — which had drifted to 0.941, nine thousandths from tripping a guard that should never have gated it.
  6. Recomputed like-for-like, the cover guard was INERT → dropped. A coarse 2-level address scores 0.840 on the out-of-cell basis, not >0.95: the threshold separated nothing, and only the degenerate band-is-everything case would trip it. It is structurally unnecessary anyway — a band fixed at 4.7 % of the codebook with no home-cell credit cannot be secretly dense. Per the inertness rule, a threshold that never bites is decoration.

The fix for #3#6 was never to lower a bar — it was to measure the actual claim. Sparse adjacency is about references landing out of cell; a neighbour already in the home cell needs no band to reach it.

band (12 cells) random (12 cells) ratio
PRIMARY — out-of-cell, full corpus 0.763 0.031 24.71×
secondary — all nearest-32, saturating, not gated 0.941 0.764 1.23×

The null validates itself: random-12 scores 0.031 against an expected 12/255 ≈ 0.047. Home-cell inflation was masking the effect, not creating it. The honest can-stay-silent half is the random arm itself — same statistic, same basis, same machinery, wrong cells, nothing found.

Generalized checks recorded for the next twin gate: (a) before running, compute the maximum achievable value of the fire statistic under the silent guard — a hair-wide window is mis-specified regardless of which side it lands on; (b) both halves must measure the same quantity on the same basis.

Division of labour (operator-fixed, same session)

"and CLAM to calculate, that's established" / "alternative is using HHTL+ helix residue":

role who
ADDRESS / activation the 4⁴ fold — measured here
CALCULATOR CLAM — established, not re-derived
alternative calculator HHTL + helix residue (place deterministic, residue stored) — unmeasured fork
ORACLE this probe's LCA walk — scoring only, never a runtime path

Nothing here should be read as "the substrate computes distance by walking to an LCA." The LCA walk exists for the same reason tesseract-rs oracles link libtesseract: ground truth to score against, never to ship.

Boundaries (do not cite past these)

  • Structure probe, not a codec probe — nothing transfers automatically to an embedding-trained 4⁴ codebook (Phase B, still fold-ceiling-gated).
  • First-parent-only turns WordNet's DAG into a tree, so a polysemous concept gets ONE address. Visible in the example: dog lands in the informal-term-for-a-man sense, not the animal. A real limit of any fixed-arity address — reported, not hidden. Both arms see the same tree, so it cannot flatter the result.
  • Path length ignores information content (Resnik/Lin would weight by corpus frequency). Used because it is what the address approximates — both are pure structure.
  • 4-ary is measured BETTER, not CHEAPER. No traversal-cost benchmark ran. RouteAction's four variants (Skip/Attend/Compose/Escalate = exactly 2 bits) matching a rung's width is an observed consonance, not a wired mechanism.

Contents

  • crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs — the probe (zero-dep crate, 5 gates).
  • crates/lance-graph-planner/examples/data/wordnet/build_isa_tree.py — corpus generator, beside its build_wordnet_rail.py sibling. Generator committed, corpus gitignored + local-only, per this directory's convention.
  • Board: EPIPHANIES.md prepend (E-WORDNET-MAKES-THE-4-ARY-ADDRESS-SEMANTIC-1) + exec-runs/wordnet-44-activation.md.

Additive only — no core/contract type change.

Verification: probe ALL GATES GREEN; cargo clippy -p lance-graph-contract --example probe_wordnet_44_activation -- -D warnings → exit 0; cargo fmt -p lance-graph-contract applied. Scoped -p per repo practice; the workspace-wide sweep is TD-WORKSPACE-FMT-DRIFT (measured 1,094 hunks / 64 files / 9 crates, none in these files).

Queued next

PROBE-CLAM-VS-HELIX-RESIDUE — same 4⁴-addressed corpus, both calculators scored against this oracle. The seam already exists: helix::CurveRuler::from_hhtl(path, depth) turns the address into the place, index(k) = (start + 4·k) mod 17 regenerates the interior, and only ResidueEdge/Signed360 are stored. Hypothesis: a finer address shifts work from stored residue to deterministic place, making W4's 2.47 hops the granularity a residue no longer carries. Two pre-registered failure modes: (a) the address enters the ruler only through place mod 17, so a 256-cell address may funnel to the same 17 start offsets and residue would not move for a reason unrelated to 4⁴; (b) gcd(4,17)=1 buys coverage, not low discrepancy — stride 4's first four steps are 0,4,8,12 (one column, clumped) where the φ stride over 17 is 11 (17/φ = 10.51), which matters because HHTL terminates early and only short prefixes are ever consumed.


🤖 Generated with Claude Code

https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki

… gates green

Tests the operator's claim that "wordnet makes CLAM HHTL spacial
activation via 4^4", and the message before it: "4^4 would be a sparse
adjacent if the sentence refers to out of bounds meaning".

WordNet removes the hard part. A codebook must DISCOVER ancestry with
k-means and hope it survives; WordNet's @ hypernym relation IS ground
truth, so the address does not discover structure, it encodes it. The
question sharpens to: does folding real ancestry into a fixed 4-ary
depth-4 address preserve semantic distance well enough to be a search
prior, and does 4-ary buy anything the shipped 16-ary NiblePath cannot
express?

Measured on WordNet 3.1 (82,192 noun synsets, root=entity, 65,292
leaves, depth 19):

  W1 ancestry-by-construction   real +0.4938 vs shuffled -0.0356
  W2 monotone ladder            15.78 > 12.76 > 11.15 > 8.69 > 7.05
                                (spread 8.73 hops, strictly decreasing)
  W3 spatial activation         band 0.855 vs random 0.568 = 1.50x,
                                under the 0.95 cover guard (twin-tested)
  W4 sub-nibble structure       nibble sees ONE bucket (10.55); 4-ary
                                splits it 11.15 vs 8.69 = 2.47 hops
  W5 fold balance               256/256 cells, occ 29/255/1270

W4 is the headline: the 16-ary router expresses two levels per byte and
is blind inside a top nibble; the 4-ary address splits that population
by 2.47 WordNet hops. That is what makes a graded escalation band
implementable (3 siblings x 4 levels = 12 of 256 cells, 4.7%) where
16-ary offers 15 siblings or nothing.

Two first-run failures are kept as part of the finding: the first fold
reproduced the le-contract's own "lacking proper bucket rollover ...
saturates silently" warning (one cell held 15,769 leaves against a
median of 20) and needed an explicit granularity knob; and the W1
falsifier could not falsify, because a cell-label permutation is a
bijection so same-cell pairs survive it and scored +0.645 on identity
alone while looking like validation.

Division of labour recorded per operator ruling: the fold is the
ADDRESS, CLAM is the established CALCULATOR (not re-derived here),
HHTL+helix residue is the named alternative, and this probe's LCA walk
is an ORACLE for scoring only, never a runtime path.

Boundaries: structure probe, not a codec probe; first-parent-only turns
the DAG into a tree so a polysemous concept gets one address (visible in
the worked example, where 'dog' lands in WordNet's informal-term-for-a-
man sense); path length ignores information content; and 4-ary is
measured BETTER, not CHEAPER — no traversal-cost benchmark ran.

Corpus is local-only and gitignored; the generator is committed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@AdaWorldAPI, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2d3f2eaa-95c8-4057-8b6c-f6ba245fd28d

📥 Commits

Reviewing files that changed from the base of the PR and between 91f8bb0 and 4804d35.

📒 Files selected for processing (4)
  • .claude/board/EPIPHANIES.md
  • .claude/board/exec-runs/wordnet-44-activation.md
  • crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs
  • crates/lance-graph-planner/examples/data/wordnet/build_isa_tree.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Requesting the review while this is still draft deliberately — in this repo merges have repeatedly outrun reviews, so the findings are worth more now than after the merge button.

Two places worth the most scrutiny, since they are where a probe like this usually goes wrong:

  1. The falsifier arms. W1's shuffle originally could not falsify (a cell-label permutation is a bijection, so same-cell pairs survive it and scored +0.645 on identity alone while looking like validation). It now excludes same-cell pairs from both arms. Please check that the fix is genuine and that the remaining +0.494 is not carrying some other structural artefact.
  2. W3's twin gate. band > random × 1.5 AND band < 0.95. The upper guard exists so a band that captures nearly everything cannot pass — but 0.95 is a hand-chosen number, and by this repo's own inertness rule a threshold that never bites is decoration. Worth asking whether it discriminates on this data or is inert at 0.855.

Also flagging what the probe deliberately does not claim: 4-ary is measured better, not cheaper — no traversal-cost benchmark ran, and the RouteAction-is-2-bits observation is labelled a consonance, not a mechanism.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '=== Changed files ==='
git diff --name-status "$(git merge-base HEAD origin/main)" HEAD 2>/dev/null || git diff --name-status HEAD~1 HEAD

printf '%s\n' '=== Probe outline ==='
ast-grep outline crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs --items all --view expanded 2>/dev/null || true

printf '%s\n' '=== Generator outline ==='
ast-grep outline crates/lance-graph-planner/examples/data/wordnet/build_isa_tree.py --items all --view expanded 2>/dev/null || true

printf '%s\n' '=== W1/W3 markers and gate logic ==='
rg -n -C 8 -e '\bW1\b' -e '\bW3\b' -e 'shuffle|shuffl|same.cell|same_cell|correl|Pearson|random|0\.95|1\.5|band' \
  crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs

printf '%s\n' '=== Probe source with line numbers ==='
cat -n crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs

printf '%s\n' '=== Generator source with line numbers ==='
cat -n crates/lance-graph-planner/examples/data/wordnet/build_isa_tree.py

printf '%s\n' '=== Relevant diff ==='
git diff --find-renames "$(git merge-base HEAD origin/main)" HEAD -- \
  crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs \
  crates/lance-graph-planner/examples/data/wordnet/build_isa_tree.py \
  EPIPHANIES.md \
  exec-runs/wordnet-44-activation.md 2>/dev/null || true

Length of output: 84620


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '=== WordNet execution report ==='
cat -n .claude/board/exec-runs/wordnet-44-activation.md

printf '%s\n' '=== WordNet board entry ==='
rg -n -C 12 -i 'wordnet|4.ary|4\^4|spatial.activation|W1|W3|inert|twin' \
  .claude/board/EPIPHANIES.md

printf '%s\n' '=== Existing probe conventions for sampled nearest-neighbour metrics ==='
rg -n -C 8 --glob '*.rs' \
  -e 'nearest.*neighbou?r' -e 'recall' -e 'candidate pool' -e 'random.*baseline' \
  crates

printf '%s\n' '=== Ignore-policy evidence for generated WordNet artifacts ==='
rg -n -C 3 -i 'wordnet|w[no]db|isa_tree' .gitignore crates .claude 2>/dev/null || true

printf '%s\n' '=== Changed markdown diff ==='
git diff --find-renames "$(git merge-base HEAD origin/main)" HEAD -- \
  .claude/board/EPIPHANIES.md \
  .claude/board/exec-runs/wordnet-44-activation.md

Length of output: 200537


@AdaWorldAPI I confirmed the W1 repair is genuine: Lines 619-627 exclude original same-cell pairs from both arms, and because the label map is bijective, no different-cell pair can become same-cell after shuffling. The remaining +0.494 is therefore not the prior cell-identity artifact; it is the fold’s intermediate-prefix signal. W1 is appropriately scoped as “ancestry-by-construction,” rather than independent semantic validation.

I found two W3 issues:

  1. Nearest-32 is not distinct-neighbour recall. At Lines 469-471 the candidate pool is sampled with replacement, then Lines 475-490 sort and take 32 entries without deduplicating synset IDs. The same neighbour can therefore occupy multiple slots and be counted multiple times. Both arms share this bias, but the reported metric is a weighted sampled-entry recall—not recall of 32 nearest WordNet neighbours as documented. Sample unique candidates or deduplicate before selecting NEAR.

  2. The < 0.95 “stay-silent” guard is not yet shown to discriminate. The recorded value (0.855) passes, but the execution record contains neither a sensitivity result nor a deliberately dense-band counterfactual that makes the guard fail. As written, the branch is a hand-chosen assertion that is not demonstrated to bite. Add a can-it-fire fixture/counterfactual or report a sweep showing why 0.95 separates informative bands from cover-like bands; until then, describe W3 as the band-vs-random result plus an uncalibrated cover threshold, not a fully twin-tested gate.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…rate the guard

Review (#875) found two defects in W3. Both confirmed; neither is fixed by
moving a threshold.

1. MISLABELLED METRIC. The candidate pool was sampled with replacement and
   the nearest 32 taken without dedup, so one synset could occupy several
   slots — a weighted sampled-entry recall, not "recall of the 32 nearest
   neighbours" as documented. Both arms shared the bias so the ratio
   survived, but the label was false. Pool is now deduplicated.

2. THE TWIN GATE WAS ARITHMETICALLY MIS-SPECIFIED. Both arms credited the
   anchor's own cell, inflating the baseline to 0.621, which caps the
   achievable ratio at 1/0.621 = 1.61 while the fire-half demanded > 1.5
   and the cover guard demanded < 0.95 — a 0.018-wide window. The original
   1.50x pass was luck, not evidence; after dedup it read 1.44x and
   correctly failed.

The fix is to measure the actual claim. Sparse adjacency is about
references landing OUT OF CELL; a neighbour already in the home cell needs
no band to reach it. Restricting to out-of-cell neighbours:

  band 0.754 vs random 0.052 = 14.43x

The null validates itself — random-12 scores 5.2%, against 12/256 = 4.7%,
the cells' exact share of the codebook. Home-cell inflation was MASKING
the effect, not creating it. The all-neighbour figure is retained as
SECONDARY and labelled saturating (0.895 vs 0.621 = 1.44x).

The < 0.95 cover guard is now calibrated rather than asserted: the same
measurement against a deliberately coarse 2-level address (6+1 of 16
cells) yields 0.998, which the guard rejects. That satisfies the workspace
inertness rule — a threshold that never bites is decoration.

Lesson recorded for the next twin gate: verify the two halves are mutually
satisfiable by more than a hair BEFORE running, by computing the maximum
achievable value of the fire statistic under the silent guard.

Gates: 5/5 green. clippy -D warnings exit 0; fmt applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki

Copy link
Copy Markdown
Owner Author

Both W3 findings confirmed and fixed in 9739154. Neither was fixed by moving a threshold — and chasing the second one turned up something worse than reported, which then made the result about 10× stronger.

1. Mislabelled metric — confirmed exactly as described. Pool sampled with replacement, nearest-32 taken without dedup, so one synset could fill several slots. Both arms shared the bias so the ratio survived, but "recall of the 32 nearest neighbours" was a false label. Pool is now deduplicated.

2. The guard wasn't just uncalibrated — the twin gate was arithmetically mis-specified. Chasing your point exposed it: both arms credited the anchor's own cell, inflating the baseline to 0.621. That caps the achievable ratio at 1/0.621 = 1.61, while the fire-half demanded > 1.5 and the cover guard demanded < 0.95 — a 0.018-wide window. The original 1.50× pass was luck, not evidence. After dedup it read 1.44× and correctly failed.

The fix was to measure the actual claim. Sparse adjacency is about references landing out of cell (the operator's framing: "if the sentence refers to out of bounds meaning") — a neighbour already in the home cell needs no adjacency band to reach it, and crediting it to both arms is what compressed the statistic. Out-of-cell only:

band (12 cells) random (12 cells) ratio
PRIMARY — out-of-cell neighbours 0.754 0.052 14.43×
SECONDARY — all nearest-32 (saturating, both arms credit home cell) 0.895 0.621 1.44×

The null validates itself: random-12 scores 5.2 % against 12/256 = 4.7 %, the cells' exact share of the codebook. Home-cell inflation was masking the effect, not creating it.

3. The < 0.95 guard is now calibrated rather than asserted. Added a counterfactual arm: the same measurement against a deliberately coarse 2-level address (6+1 of 16 cells) yields 0.998, which the guard rejects. So 0.95 demonstrably separates a prior from a cover on this data — satisfying this repo's own inertness rule that a threshold which never bites is decoration. Your "describe it as an uncalibrated cover threshold until then" was the right call; it now has the fixture.

Recorded in both board files, including the generalized lesson: before running a twin gate, compute the maximum achievable value of the fire statistic under the silent guard — if the window is a hair wide, the gate is mis-specified regardless of which side it lands on.

Thanks for the W1 verification too — agreed that +0.494 is the fold's intermediate-prefix signal and that W1 is scoped as ancestry-by-construction, not independent semantic validation.

5/5 gates green, clippy -D warnings exit 0, fmt applied.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Re-requesting on 9739154, which addresses both W3 findings. Worth a look specifically at whether the fix is genuine rather than a relabelled pass: the fire statistic changed from all-neighbour recall to out-of-cell recall, and while the justification is that sparse adjacency is a claim about out-of-cell references (so home-cell hits belong to neither arm's credit), a changed statistic that happens to score better deserves the same scrutiny the original got. The null behaving exactly as a null should — random-12 at 5.2 % against the cells' 4.7 % share — is the main evidence I'd want checked.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="$(git merge-base HEAD origin/main 2>/dev/null || git rev-parse HEAD~1)"

printf '%s\n' '=== Files changed by PR ==='
git diff --name-status "$base" HEAD

printf '%s\n' '=== Files changed in requested follow-up commit ==='
git show --name-status --format='commit %H%n%s' 9739154

probe="$(fd -t f '^probe_wordnet_44_activation\.rs$' . | head -n 1)"
if [ -z "$probe" ]; then
  echo 'Probe source not found.' >&2
  exit 1
fi

printf '\n=== Probe outline ===\n'
ast-grep outline "$probe" --items all --view expanded

printf '\n=== Follow-up diff: W3 probe ===\n'
git show --find-renames --format= 9739154 -- "$probe"

printf '\n=== Current W3-related source ===\n'
rg -n -C 12 -i \
  -e '\bW3\b' -e 'out.of.cell|out_of_cell|home.cell|same.cell|same_cell' \
  -e 'random.*band|band.*random|candidate|dedup|unique|NEAR|0\.95|1\.5' \
  "$probe"

printf '\n=== Recorded W3 results and calibration ===\n'
rg -n -C 10 -i \
  -e '\bW3\b' -e 'out.of.cell|random.12|0\.052|0\.754|0\.998|0\.95|coarse|cover|dedup' \
  .claude/board 2>/dev/null || true

Length of output: 200153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

probe="$(fd -t f '^probe_wordnet_44_activation\.rs$' . | head -n 1)"
echo "=== Probe: $probe ==="

echo '=== Focused follow-up diff ==='
git show --format= --unified=40 9739154 -- "$probe"

echo '=== W3-related line locations ==='
rg -n -i \
  -e '\bW3\b' -e 'out.of.cell|out_of_cell|home.cell|same.cell|same_cell' \
  -e 'random.*band|band.*random|candidate|dedup|unique|nearest|coarse|cover' \
  "$probe"

echo '=== Source windows around all W3-related matches ==='
rg -n -i \
  -e '\bW3\b' -e 'out.of.cell|out_of_cell|home.cell|same.cell|same_cell' \
  -e 'random.*band|band.*random|candidate|dedup|unique|nearest|coarse|cover' \
  "$probe" \
| cut -d: -f1 \
| sort -nu \
| awk '
  { lo=$1-10; if (lo<1) lo=1; hi=$1+16; print lo "," hi "p" }
' \
| while read -r range; do
    echo "--- $range ---"
    sed -n "$range" "$probe"
  done

echo '=== Compact recorded W3 result excerpts ==='
rg -l -i -g '*.md' \
  -e '0\.754' -e '14\.43' -e '0\.998' -e 'out-of-cell' \
  .claude/board 2>/dev/null \
| while read -r file; do
    echo "--- $file ---"
    rg -n -C 6 -i -e '0\.754' -e '14\.43' -e '0\.998' -e 'out-of-cell' "$file"
  done

Length of output: 134157


@AdaWorldAPI The W3 correction is genuine, not a relabelled pass:

  • Symmetric primary measurement: Lines 541-574 first exclude home-cell neighbours, then score the same out-of-cell set against both the 12-cell adjacency band and 12 distinct random cells. The primary arms therefore do not receive home-cell credit.
  • Valid null: Once home-cell neighbours are excluded, a random band selects 12 of the remaining 255 cells, so its expected hit rate is 12/255 ≈ 4.71%. The observed 5.2% is consistent with that null; it is not inflated by the anchor cell.
  • Distinct neighbours: Lines 494-503 deduplicate the 20,000-candidate pool before nearest-32 selection, fixing the earlier sampled-entry issue.
  • Guard calibration: The coarse arm uses the same anchors and neighbour set and reaches 0.998. The native band_mean < 0.95 guard is still sound for the primary metric: per anchor, all-neighbour recall is at least out-of-cell recall, so passing the former bounds the latter as well.

One documentation mismatch remains: the module-level W3 description at Lines 58-63 still calls the metric recall of all 32 nearest neighbours in the band. It should explicitly identify out-of-cell recall as the primary statistic and label the all-neighbour value as the secondary saturating diagnostic, matching Lines 598-604 and the recorded result.

[review]


✏️ Learnings added
Learnt from: AdaWorldAPI
URL: https://github.com/AdaWorldAPI/lance-graph/pull/875

Timestamp: 2026-07-30T23:20:01.203Z
Learning: In `crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs`, W3’s primary sparse-adjacency metric is recall among the anchor’s nearest WordNet neighbours that are outside the anchor’s home address cell. Home-cell neighbours are excluded from both the 12-cell ancestry-band arm and the 12-cell random-band baseline; all-neighbour recall is retained only as a secondary saturating diagnostic.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Review follow-up on #875: the module-level W3 text still described "recall
of the anchor's 32 nearest neighbours inside the 12-cell band", which is
the SECONDARY saturating diagnostic, not the primary statistic the gate
now computes. A doc-comment claim that does not match behaviour is a
defect by this repo's own rule, not a cosmetic mismatch.

Module docs now state:
- PRIMARY = out-of-cell recall, with the reason (a neighbour already in
  the home cell needs no adjacency band) and the self-checking null
  (random 12 of the remaining 255 ~ 4.7%).
- SECONDARY = all-neighbour recall, explicitly labelled the WRONG
  statistic, kept only for comparability in the record.
- The cover guard is calibrated by a coarse 2-level arm it must reject.
- The specification check this gate failed once: compute the maximum
  achievable fire statistic UNDER the silent guard before running. Here
  1/0.62 ~ 1.61 against a >1.5 bar and a <0.95 bar left an 0.018-wide
  window.

No behaviour change. 5/5 gates green; clippy -D warnings exit 0; fmt
applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki

Copy link
Copy Markdown
Owner Author

Fixed in c482e2c — and agreed it wasn't cosmetic. A doc-comment claim that doesn't match behaviour is a defect by this repo's own falsifiability rule ("a doc-comment claim is not a behaviour"), and leaving the module docs describing the metric the gate no longer computes is exactly how a corrected probe gets re-cited with its pre-correction meaning six months out.

The module W3 section now states:

  • PRIMARY = out-of-cell recall, with the reason (a neighbour already in the home cell needs no adjacency band to reach it) and the self-checking null spelled out — a random 12 of the remaining 255 cells should land ≈ 4.7 %, which is what makes the observed 5.2 % evidence rather than coincidence. Thanks for independently deriving 12/255; that is the right denominator and I had written 12/256 in the prose.
  • SECONDARY = all-neighbour recall, explicitly labelled the wrong statistic and kept only so the two remain comparable in the record.
  • The cover guard is described as calibrated by a coarse 2-level arm it must reject, not asserted.
  • The specification check this gate failed once, stated generally so the next twin gate inherits it: before running, compute the maximum achievable value of the fire statistic under the silent guard. Here that was 1/0.62 ≈ 1.61 against a >1.5 fire bar and a <0.95 cover bar — an 0.018-wide window, which is a mis-specified gate regardless of which side it lands on.

Also noting your bound, since it resolves something I'd left implicit: per anchor, all-neighbour recall ≥ out-of-cell recall, so band_mean < 0.95 bounds the primary metric too. The guard was doing its job on both statistics; that's now clear in the docs rather than accidental.

No behaviour change. 5/5 gates green, clippy -D warnings exit 0, fmt applied.


Generated by Claude Code

Self-caught while replying to review. The two quantities are different
and both appear in the record:

  12/255 ~ 4.71%  the NULL for out-of-cell recall (the home cell is
                  excluded from the draw, so 255 candidates remain)
  12/256 ~ 4.69%  the band's share of the WHOLE codebook

Both round to 4.7%, which is exactly why the conflation is easy and why
it is worth pinning: the observed random-12 score of 5.2% is evidence
only against the correct null. Same class of imprecision as the metric
mislabelling this probe already corrected — the number was right, the
thing it was a number OF was stated wrong.

Docs-only; no behaviour change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review July 30, 2026 23:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 105049c76b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/lance-graph-contract/examples/probe_wordnet_44_activation.rs Outdated
claude added 2 commits July 30, 2026 23:30
…as inert

Codex P1 on #875: the candidate pool was 20,000 of 65,292 addressed
leaves (31%), so "the 32 nearest WordNet neighbours" actually meant "the
32 nearest within a sample" — an omitted leaf can be strictly closer than
every sampled one, moving both the distance cutoff and which cells the
neighbours occupy. Same class of defect as the earlier dedup finding: the
label claimed more than the measurement.

Fixed by scoring all 65,292 candidates (~20M tree walks, seconds in
release) rather than relabelling the caveat. That also makes dedup moot —
`addressed` is distinct by construction. Result strengthens:

  band 0.763 vs random 0.031 = 24.71x   (was 14.43x on the sample)

with the null tightening to 0.031 against the 12/255 ~ 0.047 expectation.

The full-corpus run then exposed that the twin gate was STILL incoherent,
the third instance of the same mistake in this probe: the fire half had
moved to out-of-cell recall while the cover guard stayed on the
all-neighbour statistic that had just been declared the wrong one — and
that secondary had drifted to 0.941, nine thousandths from tripping a
guard it should never have been gating. Both halves must measure the same
quantity on the same basis.

Recomputed like-for-like, the cover guard is INERT and is dropped: on the
out-of-cell basis a coarse 2-level address scores 0.840, not >0.95, so the
threshold separated nothing and only the degenerate band-is-the-whole-
codebook case would trip it. It is structurally unnecessary for the
primary as well — a band fixed at 4.7% of the codebook with no home-cell
credit cannot be secretly dense; the saturation worry was only ever real
for the secondary statistic.

The honest silent half was already present: the random arm. Same
statistic, same basis, same machinery, wrong cells, 0.031. Keeping a
second non-firing threshold beside it would have been the exact defect
this probe exists to catch (a threshold that never bites is decoration).

Recorded generally: three defects in this probe were mis-specified
FALSIFIERS and zero were wrong measurements. A broken falsifier fails
silently — it reports PASS.

Gates 5/5 green; clippy -D warnings exit 0; fmt applied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
…uard claim

Two defects in one doc block, both self-caught while reading the review
diff:

1. `band_of`'s doc comment had been orphaned onto `band_generic` by an
   earlier insertion, so one function carried two descriptions and the
   other carried none.
2. The surviving text still sold the cover guard as "a threshold shown to
   discriminate" — a claim deleted one commit earlier, when the guard was
   measured on the primary out-of-cell basis, found inert (coarse scores
   0.840, not >0.95), and dropped. A doc-comment claim that outlives the
   behaviour it describes is the same defect class this probe keeps
   finding.

`band_generic` now documents what it actually is (the band at arbitrary
depth) and what the coarse arm is now FOR (reported granularity context,
not a guard). `band_of` gets its own one-line doc back.

No behaviour change. 5/5 gates green; clippy -D warnings exit 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
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.

2 participants