Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .claude/board/AGENT_LOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 2026-07-29 — #867 merged + ZC-2a meta_basin lens migration (main thread only, no subagents)

- **#867 closed the loop on a post-merge review.** CodeRabbit's #866 review finished after #866 had merged; its three real findings shipped as #867 and CodeRabbit re-reviewed #867 with **no blocking findings**, independently confirming all three points I asked it to re-check (bypass scope now accurate rather than overstated; concept-blindness sweep clean incl. docs and tests; `Resolution.axes` non-vacuously divergent at bundle=3/winner=2). It stated explicitly that it ran no Cargo commands — the test/clippy/fmt results are mine, which is the honest split. Merged `5373b00` after all 5 checks went green.
- **ZC-2a: 7 gathered `window:` parameters migrated IN PLACE** in `planner/nars/meta_basin.rs` — no twins, no deprecation window, because the family has zero callers outside its own file. Verified structurally rather than by grep alone: the lib compiled clean while only the in-file test module broke (21 call sites).
- **The finding is about the proof, not the migration** (EPIPHANIES `E-THE-EQUALITY-PASSED-WHILE-AN-AXIS-WAS-CONSTANT-1`): the equivalence test PASSED on two successive fixtures while the run still failed, both times on the per-axis anti-vacuity clause — every row graded `quorum = 0`, first because a sparse window has no quorum by construction, then because `quorum_mantissa` rounds `agreed*15/(peers*14)` DOWN and one agreeing locus floors to zero. An equality assert is satisfied by a constant axis; only the vacuity clause can see that the question was never posed.
- **Corrected a readiness label I inherited.** The ZC-2 tag file called these 7 "migratable NOW" on the strength of the lens twins existing. True, and it measured the callee: the fixtures use SPARSE positions and `resolve_chain` hops by absolute stream position, so every fixture had to be rebuilt around a dense row array + `visible`, not merely re-called.
- **Revert-tested, not argued:** deleting the `visible` filter fails 3 tests incl. `sparse: row count diverged at max_hops=0`.
- **Cross-repo:** OGAR pulled (18 commits, adds `ogar-fma` + `ogar-cpic` public reference surfaces); tesseract-rs local checkout noted 56 commits behind `origin/master` and deliberately NOT moved — another session may hold that branch.
- **Gates (central):** `cargo test -p lance-graph-planner` **324 + 4 passed / 0 failed**; `clippy -p lance-graph-planner --all-targets -- -D warnings` clean; `cargo fmt --check` clean. Scoped `-p` throughout.


## 2026-07-29 — medcare-rs reasoning seam: `lance_graph::reasoning` (main thread only, no subagents)

- **Checked before designing, and that was the whole value.** Five of medcare's six asks already existed (`TruthValue`'s five NAL ops, `BeliefArena`, `rcr_abduce`, counterfactual substitution). The real finding was reachability: `lance-graph` declares `lance-graph-planner` optional behind `planner`, uses it internally in `lance_native_planner.rs`, and **never `pub use`s it** — medcare had the feature enabled and could reach nothing. A feature that pulls a crate in while exposing no path looks exactly like a working dependency until the first `use`.
Expand Down
21 changes: 20 additions & 1 deletion .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
## 2026-07-29 — E-THE-EQUALITY-PASSED-WHILE-AN-AXIS-WAS-CONSTANT-1 — the anti-vacuity clause found what the equivalence assert structurally could not

**Status:** IN PR. **Confidence:** High — the vacuity was caught twice, by the guard, on two different fixtures, and the revert-test proves the equality assert bites when the behaviour actually diverges.

**The ZC-2 `meta_basin` migration** moved 7 gathered `window: &[(usize, CausalWitnessFacet)]` parameters onto `(&WitnessLens, &impl Fn(usize) -> bool)`, reading registers through a cast into each row's own bytes. It migrated IN PLACE — no twins, no deprecation window — because the family has **zero callers outside its own file**, and the lens-migration card is explicit that a migration is finished only when the materializing path is *gone*, not merely unused.

**The finding is about the proof, not the migration.** The equivalence test compares the pre-migration body (retained verbatim as a `#[cfg(test)]` oracle) against the lens form, field-by-field, across six hop budgets. It passed on the first fixture. It passed on the second. **Both times the run still failed — on the anti-vacuity clause**, which asserts that the compared gradings actually vary along each axis they claim to cover:

1. **First fixture (sparse only).** Every row graded `quorum = 0`. A sparse window has no quorum *by construction* — no two rows are close enough to converge on an absolute target — so the quorum half of every comparison was `0 == 0`. The equality assert cannot notice this: constant-vs-constant is the most reliably passing comparison there is.
2. **Second fixture (dense, one agreeing locus).** Still all zeros. `quorum_mantissa` scales `agreed * 15 / (peers * 14)` and rounds **down**, so a single agreeing locus floors to 0. The fix was four agreeing loci — a number derived from the formula, not chosen until the formula was read.

**Generalization: an equivalence test proves two implementations agree, never that they were asked anything.** Its assert is satisfied by an axis that is constant across the entire fixture space, and that is precisely the axis nobody checked. Every equality-style test therefore needs a companion clause per axis — *this comparison observed more than one value here* — or it certifies agreement on a question that was never posed. This is the `E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1` family, but the mechanism is sharper: **the vacuity is not in the assert, it is in the fixture**, so reading the assert can never reveal it.

**Second finding: "migratable NOW" was a statement about the twins, not about the work.** The ZC-2 tag file listed these 7 as unblocked because `quorum_mantissa_lens` / `trajectory_of_lens` had landed. True, and it understated the job — the fixtures use **sparse, non-contiguous positions** (`[0,1,2, 10,11,12, 20,21,22,23]`), and `resolve_chain` walks hops by absolute stream POSITION, so the gathered form could name positions with no rows between them. A lens indexes a dense row array, so the gaps have to *exist as rows* and be excluded by `visible`. Same result, different mechanism — and it means every fixture had to be rebuilt, not re-called. **A readiness label that measures the callee says nothing about the caller's shape.**

**What the revert-test proved (the claim would otherwise be an argument).** Deleting the `visible` filter from `grade_rows` fails 3 tests, including the equivalence test with `sparse: row count diverged at max_hops=0` — so the equality assert does bite on real divergence, and the gap-exclusion test (`an_invisible_gap_is_excluded_even_though_the_row_exists`, which pins that row 1 EXISTS and is addressable while being invisible) fails independently.

Cross-ref: `.claude/knowledge/zero-copy-lens-law.md`, `.claude/board/exec-runs/lens-migration-zc2.md` (outstanding table updated), `CLAUDE.md` § falsifiability rule.

## 2026-07-29 — E-A-GUARANTEE-WITH-A-RE-EXPORTED-BYPASS-IS-NOT-A-GUARANTEE-1 — CodeRabbit's #866 review landed AFTER the merge; three of its five findings were real and one of them broke my headline claim

**Status:** IN PR (#867). **Confidence:** High — all five findings were checked against the code; the two declined are demonstrably false positives, the three accepted are fixed with tests still green.
**Status:** SHIPPED (#867, merged `5373b00`; CodeRabbit re-reviewed and approved with no blocking findings — it independently confirmed the rescoped bypass claim, the clean concept-blindness sweep, and the non-vacuous `Resolution.axes` divergence). **Confidence:** High — all five findings were checked against the code; the two declined are demonstrably false positives, the three accepted are fixed with tests still green.

**Process finding first: a review that arrives after the merge still has to be worked.** CodeRabbit's #866 review (Run ID `16a75898`) was still processing when the operator merged, so the findings landed against code that was already on `main`. Nothing in the webhook stream says "you merged before the review finished" — the subscription simply ends. **When a PR merges with a review in flight, the review must be pulled explicitly**; otherwise findings against shipped code are silently dropped. Two of the three real ones here were rated Major.

Expand Down
107 changes: 107 additions & 0 deletions .claude/board/TECH_DEBT.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,112 @@
# Technical Debt Log — Open + Paid (double-entry, append-only)

## TD-LENS-QUORUM-SCANS-THE-WHOLE-LENS (2026-07-29)

**Codex P2 on #868, verified and MEASURED.** The lens migration changes the
complexity of grading, and Codex was right about the direction that regresses.

`quorum_mantissa_lens(focal, lens, visible)` scans `0..lens.len()`, where the
gathered `quorum_mantissa(idx, window)` scanned the `k`-entry window. Grading
`k` visible rows therefore goes **Θ(k²) → Θ(N·k)** in peer work. Measured with a
counting `visible` closure (deterministic, unlike a wall-clock assert):

| | N=512, k=8 sparse |
|---|---|
| lens: `visible` probes | **4608** |
| gathered: peer comparisons | **64** |

**The half Codex did not mention — the trade is genuinely two-sided.** Gathered
`resolve_chain` resolved each hop with `window.iter().position(..)`, a linear
O(k) scan **per hop**; `resolve_chain_lens` uses `lens.at(pos)`, which is O(1).
So hop work goes **Θ(hops·k) → Θ(hops)**.

Net per graded row: gathered `k·(1 + hops)` vs lens `N + hops`. The lens **wins**
whenever `N < k·(1 + hops) − hops` — dense windows and deep chains — and **loses**
when a small window is viewed through a large row array. That second case is
real: the zero-copy law says the row array IS the projection, so a full-table
lens with a handful of visible rows is a natural, not pathological, usage.

> **⊘ OPERATOR CORRECTION (2026-07-29): the framing below is wrong, and so was
> the "needs a lifetime parameter" verdict on the BLOCKED `WitnessWindow.rows`.**
> Operator: *"lifetime parameter is the wrong lens — you have a corpus, you have
> hard facts, you just need to avoid circular reasoning."*
>
> The circularity: I assumed a window must HOLD facets, so getting off a gathered
> copy means holding a BORROW, so a lifetime propagates into `PlanContext`. Both
> horns are the same bad premise. **A window carries ADDRESSES, not data.** The
> corpus is the durable thing and already exists; positions are the hard facts;
> facets are resolved from them at read time. No copy, no borrow, no lifetime,
> nothing propagates — `WitnessWindow { rows: Vec<(usize, CausalWitnessFacet)> }`
> becomes a position list, and `PlanContext` is untouched.
>
> **This dissolves the P2 too, and the two were never separate problems.** The
> Θ(N·k) scan exists only because the selection is expressed as a PREDICATE over
> the whole corpus (`0..lens.len()` filtered by `visible`) instead of as the
> addresses already in hand. Iterate the position list and peer work is Θ(k) —
> bounded by the window, not the corpus — which is exactly the "bounded/visible
> position view" Codex asked for. The measured 4608-vs-64 figure stands as the
> cost of the predicate form; it is not a cost of lensing.
>
> Both items therefore collapse into one follow-up: **addresses-not-data**.
> Superseded reasoning retained below per append-only.

**Not fixed in #868, deliberately.** The scan lives in `quorum_mantissa_lens`,
which is **shipped `lance-graph-contract` API** landed by the previous ZC-2 run
and already consumed by `dispatch_guard` — so meta_basin inherited the cost
rather than introducing it. Fixing it means either a new bounded-position-view
variant on that contract surface (additive, but a design call about what the
peer domain *is*) or having callers narrow the lens, which absolute positioning
makes non-trivial. Neither belongs inside a behaviour-preserving refactor.

**Guarded meanwhile:** `grading_cost_scales_with_lens_length_not_window_size`
pins the shape — it asserts the Θ(N·k) sweep happens AND that the cost is not
superlinear in N. If someone lands the bounded view, that test fails and gets
updated deliberately rather than the improvement passing unnoticed.
Comment on lines +61 to +64

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Retire the obsolete cost-scaling test contract.

The PR objectives explicitly retract grading_cost_scales_with_lens_length_not_window_size; keeping it as an active guard preserves the known Θ(N·k) predicate behavior and conflicts with the required address-based follow-up. Mark this test as historical and replace it with bounded address-list and sparse absolute-position coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/board/TECH_DEBT.md around lines 61 - 64, Update the TECH_DEBT entry
for grading_cost_scales_with_lens_length_not_window_size to mark it as
historical rather than an active guard. Remove its requirement to preserve the
Θ(N·k) sweep, and document replacement coverage for bounded address lists and
sparse absolute-position behavior.


**AGENTS.md compliance:** the repo requires timing notes for performance-
sensitive changes. The counted-probe figures above are that note; no `cargo
bench` harness exists for this crate, and a wall-clock number on a shared runner
would have been less informative than the invariant count.


## TD-PLANNER-DEPENDENTS-NO-CI-BUILD (2026-07-29)

**Two crates depend on `lance-graph-planner` by path and are built by NO CI job.**
Found while verifying ZC-2a's "zero external callers" claim (#868) — the claim
held, but the *gate* I first cited could not have caught a violation.

| dependent | why CI misses it |
|---|---|
| `crates/lance-graph-osint` | **workspace-`exclude`d** — no workspace command reaches it, and no workflow names it via `--manifest-path` |
| `crates/cognitive-shader-driver` | workspace member, but its planner dep is `optional = true` behind `with-planner`, a feature **no** workflow enables |

The other dependents are covered: `lance-graph` deps the planner through its
default `planner` feature and IS built (`build.yml` / `rust-test.yml` via
`--manifest-path crates/lance-graph/Cargo.toml`).

**Why this is debt, not a one-off.** CI here is deliberately per-crate
(`--manifest-path`), not `--workspace` — a reasonable choice for build time. The
cost is that adding a crate, or gating a dep behind a feature, silently removes
it from coverage with no signal. A breaking change to a planner API can go green
through every gate and break `lance-graph-osint` on someone's next local build.

**Verified manually for #868** (both clean, exit 0):
`cargo check -p cognitive-shader-driver --features with-planner` ·
`cargo check --manifest-path crates/lance-graph-osint/Cargo.toml`.
Doing that by hand is exactly the thing that does not survive contact with the
next session, which is why this is filed rather than considered handled.

**Options, cheapest first:** (a) add both to `style.yml`/`rust-test.yml` as two
more `--manifest-path` / `--features` steps; (b) a single
`cargo check --workspace --all-features` job accepting the build-time cost;
(c) leave as-is and accept that excluded crates are consumer-maintained — but
then say so in `CLAUDE.md`, because today nothing does.

**Not scheduled** — needs a call on which option, and the shader-driver
`serve.rs`-in-two-bin-targets warning shows up in the same area and may want
fixing together.


## TD-LANCE-GRAPH-ALL-FEATURES-DELTA-BREAK (2026-07-29)

`cargo clippy -p lance-graph --lib --all-features` fails:
Expand Down
Loading
Loading