diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 66f64fc64..2343a2e92 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,8 @@ +## 2026-11-11 — D-CODEGRAPH-EXPAND-1: what the Codegraph still needs, and who supplies it → `.claude/plans/codegraph-expansion-v1.md` + +**Status:** PLAN. Eight slices CG-1..CG-8 on Linear `P-EXO-18` (EXO-233..EXO-239, EXO-241; channel EXO-232; handover EXO-240). **Board:** [STATUS_BOARD](STATUS_BOARD.md) D-CODEGRAPH-EXPAND. Follows #1999, #2000, #2001; supplies inputs to D-CODEGRAPH-0, D-CODEGRAPH-0-BIN and D-CGMM-0. +**Confidence:** every gap is measured in #2000 / #2001; the egglog, DialEgg and Kythe parts are hypotheses, unread. + ## 2026-11-10 — D-FOUNDRY-PARITY-1: DR × DT64 as an operational ontology → `.claude/plans/foundry-parity-v1.md` **Status:** ACTIVE; Level R lab landed (#1991) and P1a arm C per-store cost (#1995); P1b (min/argmin) open. Evidence matrix over 18 Foundry capability rows, missing-contract register G1–G6, roadmap P0–P5. [entry](entries/2026-11-10-foundry-parity-1-lab.md) · [P1a](entries/2026-11-10-foundry-parity-1-arm-c.md) · STATUS_BOARD D-FOUNDRY-* · Linear EXO-223. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index c8959c117..be312e78a 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -360,6 +360,23 @@ Plan: `.claude/plans/d-soc-fence-v1.md`. Plan only; nothing runs yet. **Evidence boundaries:** D-SAG-6 #1760 merged docs; Math Foundry #1693/#1694 E1 lab merged; D-NFC #1753 native-first; #1775 D-DRAV draft / AV1–AV12 NOT RUN; MORK oracle with unresolved production licence/allocator; EXO-148 stable durable types unresolved. No complete distributed reasoning implementation or measured AI/data-center scaling claim. +## D-CODEGRAPH-EXPAND — measured gaps after #2001, and their suppliers (2026-11-11) + +Plan: `.claude/plans/codegraph-expansion-v1.md`. Coordination: Linear `P-EXO-18`. + +| D-id | Deliverable | Status | +|---|---|---| +| **D-CODEGRAPH-RECON-2-A** | coverage-aware `impact_report`, `cg_query impact-report` | In PR: #2001 | +| **D-CRAI-REPORT-1** | read-only review report generator, ndarray #422 admission case | In PR: #2001 | +| **CG-1** | closure-ownership edge, graded POSSIBLE | Queued (decision needed): EXO-233 | +| **CG-2** | extraction driver from `cargo metadata` (targets, dependents, tests) | Queued: EXO-234 | +| **CG-3** | store provenance: extraction revision, relative generated paths | Queued (format decision needed): EXO-235 | +| **CG-4** | edge vocabulary mapped to Kythe names (document) | Queued: EXO-236 | +| **CG-5** | co-research: body semantics through R2IL and egglog | Queued (needs go-ahead): EXO-237 | +| **CG-6** | review report follow-ups (mask-risc extraction, re-grade, placement, advisory CI) | Queued: EXO-238 | +| **CG-7** | report-rs #33 transfer case | Other session: EXO-239 / EXO-185 | +| **CG-8** | effects, target kind and cfg as Codegraph rows | Queued: EXO-241 | + ## D-CODEGRAPH-0 — resident Codegraph: Charon → ruff → lance-graph + crai-rs (2026-11-02) Plan: [d-codegraph-0-resident-codegraph-v1.md](../plans/d-codegraph-0-resident-codegraph-v1.md). Entry: [gap map](entries/2026-11-02-d-codegraph-0-gap-map.md). diff --git a/.claude/plans/codegraph-expansion-v1.md b/.claude/plans/codegraph-expansion-v1.md new file mode 100644 index 000000000..899feb5ff --- /dev/null +++ b/.claude/plans/codegraph-expansion-v1.md @@ -0,0 +1,116 @@ +# D-CODEGRAPH-EXPAND-1: what the Codegraph still needs, and who supplies it (plan v1) + +> **2026-11-11 · PLAN.** Coordination: Linear project **Codegraph · Collaboration Board** (`P-EXO-18`), +> channel EXO-232. GitHub is canonical; Linear records owners, evidence links and open decisions. +> Follows #1999, #2000 and #2001. Every gap below was measured there; every statement about +> egglog, DialEgg and Kythe is a hypothesis until its slice has read the source. + +## 1. Question + +After #2001 the Codegraph answers callers, callees and impact over real Charon stores, and says what +it could not see. Which gaps remain, which can be closed by hand-written edges, and where do R2IL, +egglog (mlir-egglog, eggcc, DialEgg) and Kythe fit? + +## 2. Answer in one table + +| gap | measured | kind of fix | supplier | slice | +|---|---|---|---|---| +| closure bodies have no edge from their parent | 96 in foundry-parity-lab; caused a missed division | derived edge, graded POSSIBLE | Codegraph crate | CG-1 | +| consumer crates not in the store | 13 of 14 consumers of `admit` | extract dependents | extraction driver | CG-2 | +| test targets and examples not extracted | 48 test sites for `LaneBinding::check`, none resolved | extract those targets | extraction driver | CG-2 | +| wrong Cargo target extracted | `bench` binary instead of the library | name the target; residuals are a refusal | extraction driver | CG-2 | +| dependents list built by hand | a wrong-column list removed a real gap | take it from `cargo metadata` | extraction driver | CG-2 | +| store does not record its revision | witnesses stamped with the wrong revision | provenance in the store | ruff_charon | CG-3 | +| absolute paths in the store | same input, different digest at another target dir | paths relative to `OUT_DIR` | ruff_charon | CG-3 | +| Charon error inside a crate | r2il is PARTIAL on a `dyn Fn` type alias | minimal case, upstream or typed gap | Charon | CG-3 | +| effects are extracted but not queryable | 213 effect rows in the foundry store; the Codegraph reads none | reader in the Codegraph | Codegraph crate | CG-8 | +| target kind, cfg and feature are not rows | "example-only" was read from `Cargo.toml` by hand; 32 inactive regions skipped | hand-rolled rows | `cargo metadata`; cfg source undecided | CG-8 | +| no def-use, no loop multiplicity | "the divisor is `per_staff`" was read by eye | new row kind from LLBC | ruff_charon | CG-5 | +| edge names are local | no shared vocabulary with other tools | mapping to Kythe edge kinds | document | CG-4 | +| what a body means | divisions classified by a source-span regex | rules over a lowered body | R2IL + egglog, unproven | CG-5 | +| review evidence is partial | mask-risc read as source; corrected review not re-graded | extract, test, re-grade | review report | CG-6 | +| one repository only | no held-out manual review yet | second repository | report-rs #33 | CG-7 | + +**The split that decides everything else:** extraction gaps (CG-1 to CG-3) are closed by extractors +and drivers. An e-graph proves that two expressions are equivalent; it cannot supply a call edge that +was never emitted. So egglog is a candidate for body semantics (CG-5) only. + +## 3. Slices + +| slice | Linear | owner repo | depends on | gate | +|---|---|---|---|---| +| CG-1 closure-ownership edge | EXO-233 | lance-graph | #2001; a decision on mask vs separate relation | `can_cook_guard` impact includes `methods` as POSSIBLE; closure-free twin gains nothing; disable run red | +| CG-2 extraction driver | EXO-234 | lance-graph, uses ruff_charon | #2001 | `admit` reports no `ConsumersNotInStore`; residuals or a non-COMPLETE crate give PARTIAL, never empty success | +| CG-3 store provenance | EXO-235 | ruff, checked in lance-graph | a format decision | two extractions at different target dirs are byte-identical; a store at another revision is refused | +| CG-4 Kythe edge vocabulary | EXO-236 | lance-graph, document | CG-1 | every row cites the Kythe schema and a Codegraph source line | +| CG-5 body semantics, co-research | EXO-237 | research | operator go-ahead | one rule classifies the two ceiling divisions and the oracle quotient of #422; disable run red | +| CG-6 review report follow-ups | EXO-238 | lance-graph; crai-rs owns semantics | #2001 | mask-risc store exists; builder has negative controls; two operator decisions recorded | +| CG-7 report-rs #33 transfer | EXO-239 (record: EXO-185) | report-rs session | #2001; CG-2 if needed | strict grading against the held-out manual review | +| CG-8 effects, target kind, cfg as rows | EXO-241 | lance-graph | #2001; shares `cargo metadata` with CG-2 | "which divisions does `max_quantities` reach" is answered inside the Codegraph crate; a missing effects file is a gap | + +Handover prompt for the CG-7 session: EXO-240. + +**Order.** CG-1, CG-2 and CG-8 first; they are small, measured and independent. CG-7 can start now from the +#2001 branch. CG-3 waits for a format decision. CG-4 is a document and can run beside anything. CG-5 +needs a go-ahead and is research before it is a build. + +## 3a. The CG-5 probe (proposed by the report-rs session, checked 2026-11-11) + +Recover the ndarray #422 answer with no manual reading: + +1. target-kind and cfg rows (CG-8); +2. def-use rows from LLBC through ruff_charon (a new row kind, so it needs the CG-3 format decision); +3. a small egglog rule pack: reachable from the entry point, contains a division, divisor traces to + `per_staff`. + +**Pass:** it reports `arm_b.rs:245` and `method.rs:58`, each with a proof. +**Fail:** removing the division in a scratch copy leaves the answer unchanged. + +Checked against source before adoption: +- **Confirmed.** `mlir-egglog` here is a Python toy compiler for NumPy expressions; DialEgg is not + checked out; `egglog` and `eggcc` are. `crates/egglog-r2il-probe` exists. `KYTHE.md` records 24 + agreeing symbols and no `ref/call` edges. The divisor is `per_staff: 4 + (m as i32 % 5)` + (`fixture.rs:105`). +- **Corrected.** The store has ten predicate codes, not six. Division sites needed no token scan: + ruff_charon already emits them as `ASSERT DivisionByZero` effects, and what is missing is a reader + (CG-8). Charon is built on this machine but is not on `PATH`. +- **Agreed.** No MLIR in the path: Rust does not lower to it, so it would be a third representation. + What transfers from DialEgg is the pattern, one egglog term per IR operation, applied to LLBC. + egglog derives and proves; it is a cold oracle arm, never a per-query path, because the Codegraph + already computes closure over masks. + +## 4. Mapping to plans and issues that already exist + +This plan adds no second Codegraph programme. It supplies measured inputs to these: + +| existing | what it already owns | relation to this plan | +|---|---|---| +| D-CODEGRAPH-0 (`d-codegraph-0-resident-codegraph-v1.md`, EXO-229) | Charon → ruff → resident rows, queries | CG-1 and CG-2 are its next increments | +| D-CODEGRAPH-0-BIN (`d-codegraph-0-binary-lanes-v1.md`) | binary lanes, a provenance header, per-row `(artifact, FunDeclId)` | CG-3 is the text-store half of the same provenance question; decide them together | +| D-CODEGRAPH-0-D | a local stdio MCP over the queries | not in this plan; `cg_query` is its CLI precursor | +| D-CGMM-0 (`d-cgmm-*.md`, EXO-155) | Kythe-shaped immutable evidence, lazy demand, FieldViewDef, DT64 binding | CG-4 feeds D-CGMM-1 (source facts); CG-1 feeds D-CGMM-8 (evidence and call graph) | +| EXO-85, EXO-84 | MeTTa / Datalog assimilation, native polyfill | CG-5 must not duplicate these; it asks one narrower question | +| EXO-73, EXO-101 | recursion driver, datafrog parity | unaffected; the Codegraph closure is not a new recursion driver | +| D-CMR-8 (`d-cmr-concept-chain-normalization-v1.md`) | equality-saturation probe, `egg` / `egglog` as references only | CG-5 reuses its stance: reference and probe, not a runtime | +| `ascent-byods-dr-fold-polyfill-v1.md`, entry 2026-10-21 | earlier evaluation of egglog, datafrog and Ascent | CG-5 starts from that evaluation | +| D-FOUNDRY-PARITY-1 (EXO-227) | G1 to G6 | CG-6 carries the open #422 verification | +| EXO-230 | navigation and the review evidence packet | CG-6 | +| EXO-185 | report-rs #33 | CG-7 | + +## 5. Constraints + +- No new graph database, no second Rust parser, no blocking CI reviewer. +- These change only by a decision issue in `P-EXO-11`: the Charon and ruff_charon artifact formats, + the lance-graph-contract / ClassView API, DT64 admission, Quack / mask-RISC execution, XLOG + semantics, crai-rs review semantics. +- A name-derived edge is POSSIBLE, never CONFIRMED. +- Nothing from CG-5 enters a per-query path. Cold costs are reported in microseconds and are not gates. +- Every guard has a test that fails when the guard is disabled. + +## 6. Open decisions + +1. May a name-derived closure edge enter `impact`'s masks, or is it a separate relation (CG-1)? +2. May the ruff_charon store format gain a revision and relative paths, and is that decided together + with D-CODEGRAPH-0-BIN's provenance header (CG-3)? +3. Go-ahead for the CG-5 co-research pass. +4. Where the review report generator lives, and whether the advisory CI job is built (CG-6). diff --git a/.claude/probes/2026-11-11-codegraph-recon-1/REPORT.md b/.claude/probes/2026-11-11-codegraph-recon-1/REPORT.md index eebc08d9c..63b69cbd0 100644 --- a/.claude/probes/2026-11-11-codegraph-recon-1/REPORT.md +++ b/.claude/probes/2026-11-11-codegraph-recon-1/REPORT.md @@ -241,3 +241,31 @@ GRAPH=1 crates/sag-ra-probe/target/release/sag-ra-probe "$PWD" > ra_graph.tsv cargo run --release --manifest-path crates/lance-graph-codegraph/Cargo.toml --example cg_query -- $STORE . sweep python3 .claude/probes/2026-11-11-codegraph-recon-1/recon.py score --store $STORE --src . --corpus corpus.tsv --ra ra_graph.tsv ``` + +## Reproduction check (before merge) + +The documented commands were re-run from scratch into a fresh directory at `90fc5a7`: Charon and +`ruff_charon import` on the four crates, then rust-analyzer `GRAPH=1`. The results were compared with +the artifacts this report was built from. + +- `machine-recovered.mmd`, `reconciled.mmd` and `score.tsv` regenerate **byte-identical**, and + `cg_query sweep` gives the same 9,138 positions / 9,569 answered / 8,707 empty. +- **Text rows:** byte-identical for dt64, quack and r2il. Contract's rows and `files.tsv` differ only + in the absolute path of two build-script outputs (`manifest_metadata.rs`, `ogit_namespace.rs` under + `CARGO_TARGET_DIR/…/build/lance-graph-contract//out/`). Their content hashes are identical, + and after normalising that path the rows are identical. +- **LLBC:** byte-identical except for one embedded `--dest-file` path. +- **`rows.bin`:** differs only in its provenance block (the LLBC digest and the Charon config string, + which both carry that path) and in the header digest that covers it. +- **rust-analyzer graph:** identical apart from its `*_ms` timing rows (0 of about 820k rows differ). + +**Finding:** the store is reproducible in content but not location-independent. Paths of generated +files and the LLBC location are recorded verbatim, so the same input at a different `CARGO_TARGET_DIR` +gives a different digest. Two consumers are affected differently: +- **Refresh** compares store digests, so it treats the two stores as different. +- **The freshness check** (`impact_report`) does not compare digests. It hashes each file listed in + `files.tsv`. A recorded path that no longer exists is reported as `MissingSource`; a path that still + exists with the same content gives no gap, whatever the store digest. + +Owner: EXO-229 (ruff_charon could record generated files relative to +`OUT_DIR`). diff --git a/.claude/probes/2026-11-11-crai-report-1/REPORT.md b/.claude/probes/2026-11-11-crai-report-1/REPORT.md new file mode 100644 index 000000000..9f97beacf --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/REPORT.md @@ -0,0 +1,225 @@ +# D-CRAI-REPORT-1 and D-CODEGRAPH-RECON-2 (Gate A): Codegraph evidence as review reports + +**Status:** probe, advisory only. Board: EXO-229 (intake), EXO-230 (navigation). report-rs #33 / +EXO-185 (RECON-2 Gate B) moved to another session; this one covers #2000's follow-up, coverage-aware +impact, the report generator, and the ndarray #422 admission case. + +Nothing here posts PR comments, applies fixes, uploads anything or blocks CI. + +## 1. What landed + +| piece | where | what it does | +|---|---|---| +| coverage-aware impact | `crates/lance-graph-codegraph/src/impact_report.rs` | `Codegraph::impact_report(symbol, &ExtractionScope)` → `ImpactAnswer`: the unchanged `Codegraph::impact` mask plus typed `CoverageGap`s | +| CLI | `cg_query … impact-report SYMBOL [--deps a,b] [--with-tests] [--no-freshness]` | the same, for agents | +| report generator | `crai_report.py` | review input → `review.md` + `review.ndjson` | +| #422 evidence builder | `build_q8_evidence.py` | git + Cargo + Charon store → review input | +| examples | `examples/lance-graph-2000/`, `examples/ndarray-422/` | inputs and rendered reports | + +### Coverage-aware impact (RECON-2 Gate A) + +`Codegraph::impact` keeps its position-mask semantics (Decision 1). A caller in an unloaded crate has +no position, so it is reported as missing coverage and never as an entry in `Graded::unknown`. Facts the +rows cannot carry are declared by the caller in `ExtractionScope`: +- which targets were extracted; +- which crates depend on the symbol's crate; +- where the source is, for freshness. + +Anything the caller leaves undeclared becomes a gap. What the caller does declare is trusted: if a +real consumer is left out of the dependents list, the report cannot notice. + +| case | test (`tests/impact_coverage.rs`, on real `rev1` Charon facts) | disable run | +|---|---|---| +| no callers in a fully observed scope → no gap | `no_callers_inside_a_fully_observed_scope_has_no_gap` | — (silence twin) | +| public symbol, consumers not in store / not declared | `a_public_symbol_with_unobserved_consumers_reports_missing_coverage` | red (both gaps) | +| library-only extraction → test callers unobserved | `library_only_extraction_reports_unobserved_test_callers` | red | +| callers only through dispatch | `dispatch_only_callers_report_unresolved_dispatch` | red | +| changed source / freshness unchecked | `a_changed_source_file_reports_stale_coverage` | red (both) | +| symbol absent from the store | `a_symbol_absent_from_the_store_is_not_an_empty_impact` | red | +| consumer crate added: gap → CONFIRMED | `adding_the_consumer_crate_upgrades_missing_coverage_to_confirmed` | red | +| extraction residuals in a `COMPLETE` crate | `extraction_residuals_are_a_coverage_gap` | red | +| crate read without a residuals file | `a_missing_residuals_file_is_a_coverage_gap` | red | +| crate read without a CRATE row | `a_crate_without_a_crate_row_is_partial_not_absent` | red | +| symbol whose rows a refresh removed | `a_symbol_removed_by_a_refresh_is_not_found` | red | +| file-list row without a hash | `a_malformed_file_list_row_is_a_freshness_gap` | red | + +`ImpactReport::no_known_gap()` is documented as "no known gap within the declared scope", never as +completeness. That matches `diag::Coverage::no_known_gap`. + +One test premise was wrong and was corrected, not the code: `util::double` is not dispatch-free. It is +called by `Square::area`, which `area_of` reaches through dispatch, so `area_of` is a legitimate possible +impact of `double`. The silence twin uses `util::triple`. + +### The report generator (Gates 1 and 3) + +Records keep CodeRabbit's public `--agent` fields (`fileName`, `comment`, `severity`, `suggestions`, +`codegenInstructions`; crai-rs CR-SRC-01) and add crai-rs's five separate axes. + +**The generator computes, and never accepts from its input:** +- the evidence class: the highest grade among witnesses current at their own repository's head; +- the finding status (`stale` when a witness is old); +- whether the review is clean. + +`TEST_OBSERVED` needs a falsifier recorded as red under a disable run and then green. + +| Gate 3 control (and crai-rs id) | test | disable run | +|---|---|---| +| missing consumer crates → UNKNOWN, never "unaffected" | `test_missing_consumer_crates_yield_unknown_not_unaffected` | red | +| stale packet → no current-head finding (RS-F04) | `test_stale_packet_cannot_produce_a_current_head_finding` | red | +| evidence current only at its own repo's head | `test_cross_repo_evidence_is_current_only_at_its_own_head` | red | +| PARTIAL / SKIPPED / NOT_RUN / FAILED with 0 findings never clean (RS-F03) | `test_partial_or_skipped_with_zero_findings_is_never_clean` | red | +| named test without an executed falsifier stays NOT_RUN (RS-F05) | `test_a_named_test_without_an_executed_falsifier_stays_not_run` | red | +| compiler evidence vs reviewer hypothesis keep their grades; confidence never from severity (RS-F01/F02) | `test_compiler_evidence_and_reviewer_hypotheses_keep_separate_grades` | red | +| irrelevant benchmark does not become a defect | `test_an_irrelevant_benchmark_does_not_become_a_defect` | red | +| repeated input → byte-identical reports | `test_repeated_input_regenerates_byte_identical_reports` | red | +| POSSIBLE never a confirmed caller (RS-F07) | `test_possible_dispatch_is_never_a_confirmed_caller` | red | +| repetition is not a second witness (RS-F08) | `test_repetition_is_not_a_second_witness` | red | +| a stale finding blocks a clean verdict (RS-F04) | `test_a_stale_finding_blocks_a_clean_verdict` | red | +| a resolved record never absorbs an open one (RS-F08) | `test_a_resolved_record_does_not_absorb_an_open_one` | red | +| a different line span is a separate site (RS-F08) | `test_a_different_line_span_is_a_separate_site` | red | +| a run on another head is named in the verdict (RS-F04) | `test_a_run_on_another_head_is_named_in_the_verdict` | red | +| header fields are data, never structure (RS-F09) | `test_header_fields_are_data_never_structure` | red | +| agent text is quoted, never structure (RS-F09) | `test_agent_text_is_quoted_never_structure` | red | +| withdrawn keeps its record (RS-F10) | `test_withdrawn_keeps_its_record` | red | + +On real data: +- **#2000:** the packet regenerated at the merged head gives F1 `open`/COMPILER_DERIVED and F2 + `open`/SOURCE_STRUCTURE. The packet committed from an older head gives both `stale`/ASSERTED, with no + coverage claim. +- **Reproducibility:** both examples regenerate byte-identical from their inputs. + +Placement: the generator lives beside the packet in lance-graph, not in crai-rs, although crai-rs owns +the review semantics (its §7 owner table). crai-rs declares itself CR-H0 "documentation and +preregistered falsification only … not a … checker, runtime, PR reviewer". Moving executable code there +changes that phase, so it is the owner's decision. + +## 2. ndarray #422 (Gate 2): does the quotient optimisation reach the Foundry consumer? + +**Generated finding, from tools only:** not in shipped code. +- **The change:** #422's Rust changes are confined to the `u64x64` example target + (`[[example]] name = "u64x64"`). No library Rust file changed, and no crate can depend on an example. +- **G1 (`max_quantities`, `network_capacity`):** reaches a single division, the scalar ceiling + `(q + per_staff - 1) / per_staff` in `cook_ops`. It is the threshold operand of a mask predicate and + names no lane. +- **G6 (`execute_can_cook`, `PreparedMethod::{prepare, run}`):** reaches no division. Its guard is built at + registration (`method::methods` → `can_cook_guard`), which compares stock against `d * q` (`method.rs:55`) and + has the same scalar ceiling division for staff (`method.rs:58`). +- **How the threshold is evaluated:** mask-risc `Pred::GeI32 { lane, t: i32 }` (`ir.rs:133`) is passed to + `ndarray::simd::ge_i32_to_mask` unchanged (`exec.rs:588`), which is a compare against the splatted + threshold. Read as source; mask-risc is not in the Charon store, and its other predicate kinds were not read. +- **Not covered:** G1's per-store min/argmin step is not shipped (EXO-227 P1b), so the finding is about + shipped code only. +- **The stock quotient `stock / d`:** appears only in the oracle (`oracle.rs:62`) and the materialised + null model (`arm_a.rs:75`). Both reference arms reach it through a closure + body that Charon links to its parent by name only, so the edge is graded POSSIBLE. +- **A narrower point the PR's own spec gets wrong:** "No quotient is evaluated on the executable path" + is too strong, because a scalar ceiling division builds the staff threshold. It should say "no + per-row stock quotient". + +How the evidence was made trustworthy: +- **Charon first translated the wrong target.** `foundry-parity-lab` has a library and a `bench` + binary, and `charon cargo` picked the binary. The library came through as opaque dependency items: + 47 `BODY_NOT_STRUCTURED` residuals and zero calls. Read naively, that store says "the consumer calls + nothing, so nothing is reached", which is the false negative this work exists to prevent. The + residuals flagged it. Re-run with `-- --lib`: 1,636 facts, 928 resolved calls, 0 residuals. +- **Divisions come from Charon's assertions.** Each integer division carries a `DivisionByZero` and an + `Overflow:Div` effect at its exact span, so "which divisions does this path reach" is a compiler + fact, not a text search. +- **The threshold check is mechanical.** The builder reads the `t:` operands inside `cook_ops`'s + definition span (SOURCE_STRUCTURE) and checks that each executable division sits in one that names + no lane. + +Grading against the held-out manual review: §5. + +## 3. Corrections to RECON-1 (#2000) + +- **r2il was not clean.** `lance_graph_r2il`'s CRATE row is `PARTIAL`: Charon reported an error on + `pub type Select<'s> = dyn Fn(…)`. The RECON-1 report and the EXO-229 comment said the four crates ran + clean with one residual. The residual count was right, and the crate status was not. `impact_report` + now reports it as `PartialCrate`. +- **The reproduction record is not on main.** `c7151a1` was pushed after #2000 merged at `90fc5a7`, so + it is carried on this branch. + +## 4. Gap matrix: what Codegraph still cannot prove + +| gap | effect on an answer | measured where | what would close it | +|---|---|---|---| +| crates not in the store | external callers have no position | dt64: 261/370 public symbols; `admit`: 13 consumers missing | one Charon artifact per consumer (EXO-229) | +| test targets, `#[cfg(test)]` modules, examples | test callers unobserved | `LaneBinding::check`: 48 name-matched test sites, none resolved | Charon/RA on test targets | +| calls inside closures passed to std adapters | parent→closure edge missing | foundry-parity-lab: 96 closure bodies in the crate, linked only by name | link by Charon's naming as POSSIBLE (done in the #422 builder, not in Codegraph) | +| macro arguments (RA) | call rows missing; region marked | `lane_socket.rs`: 7/7 sites | Charon (LLBC sees through macros) | +| wrong Cargo target extracted | an apparently empty crate | foundry-parity-lab picked `bench` | name the target; treat `BODY_NOT_STRUCTURED` as refusal | +| Charon errors inside a crate | `PARTIAL` CRATE, zero residuals | r2il (`dyn Fn` type alias) | read CRATE status, not only residuals | +| declared scope is trusted | a wrong dependents list removes a real gap | my own wrong-column `--deps` gave "no consumer gap" | dependents from Cargo metadata, not a caller-built list | +| store location-dependence | identical content, different digests | contract build-script outputs, LLBC path | relative `OUT_DIR` paths in ruff_charon | +| semantics of a body | no BODY_SEMANTICS beyond R2IL bindings | Rust functions are `NOT_A_METHOD` | out of scope | +| production data | no recipe distribution | #422: PRODUCTION_DISTRIBUTION = UNKNOWN | not a code fact | +| performance | no timing evidence | #422 benchmarks: ASSERTED | executed benchmark with disable arms | + +## 5. Grading (Gate 4) + +**There was no held-out manual review to grade against.** No manual #422 review was found on the Linear +board, and the GitHub PR conversation was not reachable from this session. So recall against a human +review is **not measured**. What was measured instead: an independent grader, given only the rendered +`review.md`, the sources and the PR, checked every claim and every witness. Its claims were then checked +against source before any correction was made, since a grader's statements are claims too. + +**First version, as graded:** + +| measure | result | +|---|---| +| claims | 45: 41 correct, 3 unsupported, 1 wrong | +| witnesses | 14: 8 resolve, 5 partially, 1 not | +| unsupported | "no per-row quotient on G1/G6" stated without qualification while mask-risc was unknown; "G6 compares stock against `d*q`" with no witness for it | +| wrong | Q3's falsifier: `cargo run --release --example u64x64` only prints usage; the benchmark is built per tier and run as `u64x64 bench `, and F7/F8 are parity disable arms for `check`, not speed | +| witness defects | the store revision was given as `317c4ff` but the store was extracted at `c7151a1`; Q3 pointed at the example directory, not plan §17 | +| misses | the G6 ceiling division at registration (`method.rs:58`); G1's open min/argmin step (EXO-227); "56 closure bodies" was crate-wide, not per path | +| readability | "NOT CLEAN" read as "defects found"; Q1's hedge appeared only in the unknowns; Q2's suggestion named a lance-graph location for an ndarray plan | + +**Corrections, each verified in source first:** +- mask-risc `GeI32` evaluation added as SOURCE_STRUCTURE (`ir.rs:133`, `exec.rs:588`, ndarray + `simd_masking_ops.rs:3449`), and the unknown narrowed to the predicates that were not read; +- G6 registration reached from `method::methods`, with its `d * q` (`method.rs:55`) and ceiling division + (`method.rs:58`); +- witnesses pinned to the extraction revision `c7151a1`; the builder now refuses if + `foundry-parity-lab` or `lance-graph-mask-risc` differ between that revision and `--lg-head`; +- Q3's witness is plan §17 and its falsifier the plan's own per-tier `bench` invocation; +- Q1's claim is scoped to shipped code and names what it does not cover; +- the verdict reads `INCOMPLETE REVIEW: run PARTIAL; not a defect verdict`; +- Q2's suggestion names the ndarray plan file and line. + +**Found while correcting:** nested closures (a closure inside a closure, as in `methods`'s +`flat_map(|m| … map(move |q| …))`) were never linked to their owner, because Charon names the inner one +under `…::{closure}`, which is not itself a definition. That is why G6 registration was missed. Resolved +to the nearest named owner: 96 closure bodies linked, up from 56. + +**Accuracy after correction** has not been re-graded independently; the numbers above are for the first +version. Readability and actionability are judged by the grader, one reader; they are indications. + +**Smallest next verification** (from the corrected report): run Charon on `lance-graph-mask-risc` and +re-run the reach into it, for the predicate kinds other than `GeI32` that the consumer builds. + +**Tool cost:** + +| step | cost | +|---|---| +| Charon, foundry-parity-lab lib (deps built) | 2 s | +| ruff_charon import | ≤ 7 s | +| `build_q8_evidence.py` + `crai_report.py render` | < 1 s | +| independent grader | 51 tool calls, 533 s | + +## 6. Recommendation: advisory GitHub CI + +Not built in this slice. If you want it: + +1. A `workflow_dispatch`-only job, plus an opt-in label. It runs Charon on the crates a PR touches, + their direct dependents, and test targets. It renders `review.md` / `review.ndjson` as an artifact. +2. **No comment, no status check, no blocking.** The run status is printed in the summary, and + PARTIAL is the honest default. +3. **Refuse rather than report empty:** a crate with `BODY_NOT_STRUCTURED` residuals, a non-COMPLETE + CRATE row, or a stale `files.tsv` makes the job say `PARTIAL` with the reason, never `clean`. +4. **Cost** (measured here): Charon 2–29 s per crate (contract 21 s, dt64 29 s, foundry lib 2 s once + built); ruff_charon import ≤ 7 s; impact/report < 1 s. RA over the whole workspace takes 108 s and + should run only when macro-region coverage is wanted. +5. Promote to a PR comment only after a held-out precision measurement over several real PRs. One + graded case is an indication, not a calibration. diff --git a/.claude/probes/2026-11-11-crai-report-1/build_q8_evidence.py b/.claude/probes/2026-11-11-crai-report-1/build_q8_evidence.py new file mode 100644 index 000000000..b9bfe7262 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/build_q8_evidence.py @@ -0,0 +1,386 @@ +#!/usr/bin/env python3 +"""Build the ndarray #422 admission-review input from tools, never from the PR's conclusions. + + python3 build_q8_evidence.py --ndarray DIR --base SHA --head SHA \ + --store FOUNDRY_STORE --lg-src LANCE_GRAPH_ROOT --lg-rev EXTRACTION_SHA [--lg-head SHA] > review-input.json + +Question: does the per-row quotient specialisation proposed in ndarray #422 reach the executable +Foundry consumer it names (lance-graph `foundry-parity-lab`, G1 capacity and G6 `CanCook`)? + +Facts come from: `git diff --name-only` and the PR head's `Cargo.toml` (what changed, in which +target kind); a Charon → ruff_charon store of `foundry-parity-lab`'s library target (calls, +dispatch, closures, and the division/overflow assertions Charon emits at each integer division). +The only human input is ENTRY_POINTS: the consumer functions the PR's spec names, labelled as such. +""" + +import argparse +import collections +import json +import re +import subprocess +import sys +from pathlib import Path + +# Named by the PR's spec (D-QUOT8-ADMISSION-0 §16, commit 3ef39dd), not derived here. +ENTRY_POINTS = { + "G1 capacity (arm_b)": ["arm_b::{ItemQuery<'s>}::max_quantities", "arm_b::{ItemQuery<'s>}::network_capacity"], + "G6 CanCook (method)": ["method::execute_can_cook", "method::{PreparedMethod<'s>}::prepare", + "method::{PreparedMethod<'s>}::run"], +} +# Where G6's methods are built: registration, not the execution entry points above. +REGISTRATION = ["method::methods"] +REFERENCE_ARMS = ["oracle::{Oracle}::network_capacity", "arm_a::{Objects}::network_capacity"] +CRATE = "foundry_parity_lab" +PLAN = ".claude/plans/u64x64-llvm-probe-v1.md" +DIV = ("DivisionByZero", "Overflow:Div") +NL = b"\n" + + +def fnv1a64(data): + h = 0xCBF29CE484222325 + for b in data: + h = ((h ^ b) * 0x100000001B3) & 0xFFFFFFFFFFFFFFFF + return f"{h:016x}" + + +def git(d, *a): + return subprocess.run(["git", "-C", d, *a], capture_output=True, text=True, check=True).stdout + + +def rows(path): + cols, out = None, [] + for ln in Path(path).read_text().splitlines(): + if ln.startswith("#schema "): + cols = ln[8:].split("\t") + elif ln and not ln.startswith("#"): + out.append(dict(zip(cols, ln.split("\t")))) + return out + + +def locate(text, needle): + """1-based line of the single occurrence of `needle` in `text`; refuses 0 or 2+ hits.""" + hits = [i + 1 for i, ln in enumerate(text.splitlines()) if needle in ln] + if len(hits) != 1: + sys.exit(f"expected exactly one line containing {needle!r}, found {hits}") + return hits[0] + + +def line_of(root, f, off): + return Path(root, f).read_bytes()[: int(off)].count(b"\n") + 1 + + +def main(argv): + ap = argparse.ArgumentParser() + for a in ("--ndarray", "--base", "--head", "--store", "--lg-src", "--lg-rev"): + ap.add_argument(a, required=True) + # --lg-rev is the revision the store was extracted at; --lg-head, when given, is a later + # lance-graph head the review is about. The two consumer crates must be unchanged between them. + ap.add_argument("--lg-head") + a = ap.parse_args(argv) + nd, lg_root = a.ndarray, Path(a.lg_src) + lg_src = lg_root / "crates/foundry-parity-lab" + risc = lg_root / "crates/lance-graph-mask-risc/src" + # The witnesses carry --lg-rev, so both inputs must be at it: the checkout (committed and + # uncommitted state of the two consumer crates), and the store, whose file list records the + # hash of every source file it was extracted from. + consumer = ["crates/foundry-parity-lab", "crates/lance-graph-mask-risc"] + if subprocess.run(["git", "-C", str(lg_root), "diff", "--quiet", a.lg_rev, "--", *consumer]).returncode != 0: + sys.exit(f"--lg-src differs from {a.lg_rev} in the consumer crates (other revision or local changes)") + # `git diff` does not see untracked files; a new source file would be invisible to it. + untracked = git(str(lg_root), "status", "--porcelain", "--untracked-files=all", "--", *consumer).strip() + if untracked: + sys.exit(f"--lg-src has uncommitted or untracked files in the consumer crates:\n{untracked}") + listed = rows(f"{a.store}/{CRATE}.files.tsv") + if not listed: + sys.exit("the store has no file list; its extraction revision cannot be checked") + for f in listed: + src = lg_src / f["path"] + if not src.is_file() or fnv1a64(src.read_bytes()) != f["fnv64"]: + sys.exit(f"the store was not extracted from this source: {f['path']} differs") + # The file list is hashed, but rows and effects are separate files and could come from another + # extraction. Bind them to the hashed sources by content: every row or effect with a span must + # name a listed file and fit inside it, a definition's span must contain its own name (compiler-generated items excepted), and a + # division effect's span must contain a division. + hashed = {f["path"]: (lg_src / f["path"]).read_bytes() for f in listed} + for kind, name in (("rows", f"{CRATE}.rows.tsv"), ("effects", f"{CRATE}.effects.tsv")): + for r in rows(f"{a.store}/{name}"): + if r.get("file") in (None, "-") or r.get("start") in (None, "-"): + continue + src = hashed.get(r["file"]) + if src is None: + # Build-script outputs are recorded by absolute path and are not hashed sources. + if Path(r["file"]).is_absolute(): + continue + sys.exit(f"the store's {kind} name a file its file list does not: {r['file']}") + lo, hi = int(r["start"]), int(r["end"]) + if not 0 <= lo <= hi <= len(src): + sys.exit(f"the store's {kind} do not fit {r['file']}: span {lo}..{hi} of {len(src)} bytes") + text = src[lo:hi] + # Compiler-generated items (derives, drop glue, closures) have no name in their span. + generated = "{" in r["subject"] or any(seg.startswith("impl_") for seg in r["subject"].split("::")) + if kind == "rows" and r["predicate"] == "DEFINES" and not generated: + leaf = r["subject"].rsplit("::", 1)[-1].encode() + if leaf not in text: + sys.exit(f"the store's rows do not match the source: {r['subject']} is not defined at {r['file']}:{lo}") + if kind == "effects" and r["kind"] == "DivisionByZero" and b"/" not in text: + sys.exit(f"the store's effects do not match the source: no division at {r['file']}:{lo}") + same_at_head = None + if a.lg_head: + same_at_head = subprocess.run(["git", "-C", str(lg_root), "diff", "--quiet", a.lg_rev, a.lg_head, "--", + "crates/foundry-parity-lab", "crates/lance-graph-mask-risc"]).returncode == 0 + if not same_at_head: + sys.exit("consumer crates changed between the extraction revision and --lg-head; re-extract") + + # 1. What #422 changed, and in which Cargo target. + changed = sorted(git(nd, "diff", "--name-only", a.base, a.head).split()) + cargo = git(nd, "show", f"{a.head}:Cargo.toml") + examples = {m.group(2): m.group(1) for m in re.finditer(r'\[\[example\]\]\s*name\s*=\s*"([^"]+)"\s*path\s*=\s*"([^"]+)"', cargo)} + example_dirs = {str(Path(p).parent) + "/": n for p, n in examples.items()} + rust = [p for p in changed if p.endswith(".rs")] + in_example = {p: next((n for d, n in example_dirs.items() if p.startswith(d)), None) for p in rust} + lib_rust = [p for p, n in in_example.items() if n is None and p.startswith("src/")] + other_rust = [p for p, n in in_example.items() if n is None and not p.startswith("src/")] + + plan = git(nd, "show", f"{a.head}:{PLAN}") + + # 2. The consumer's compiler facts. + R = rows(f"{a.store}/{CRATE}.rows.tsv") + E = rows(f"{a.store}/{CRATE}.effects.tsv") + residuals = [r for r in rows(f"{a.store}/{CRATE}.residuals.tsv")] + defs = {r["subject"] for r in R if r["predicate"] == "DEFINES"} + callees, may, impls = collections.defaultdict(set), collections.defaultdict(set), collections.defaultdict(set) + for r in R: + if r["predicate"] == "CALLS_RESOLVED": + callees[r["subject"]].add(r["object"]) + elif r["predicate"] == "MAY_DISPATCH": + may[r["subject"]].add(r["object"].split(" via ")[0]) + elif r["predicate"] == "IMPLEMENTS": + impls[r["object"]].add(r["subject"]) + owned = collections.defaultdict(set) # closure bodies Charon names under their parent + for d in defs: + m = re.match(r"^(.*?)::\{impl Fn(?:Mut|Once)?<.*\{closure", d) + if not m: + continue + parent = m.group(1) + while parent not in defs and parent.endswith("::{closure}"): # a nested closure: its named owner + parent = parent[: -len("::{closure}")] + if parent in defs: + owned[parent].add(d) + divs = collections.defaultdict(list) + for e in E: + if e["kind"] in DIV: + ln = line_of(lg_src, e["file"], e["start"]) + text = Path(lg_src, e["file"]).read_bytes()[int(e["start"]):int(e["end"])].decode() + site = (f"crates/foundry-parity-lab/{e['file']}:{ln}", text) + if site not in divs[e["subject"]]: # one site carries both a zero and an overflow assertion + divs[e["subject"]].append(site) + src_defs = {r["subject"]: r for r in R if r["predicate"] == "DEFINES"} + + def thresholds(sym): + """Mask-predicate threshold operands (`t: …`) inside `sym`'s source span, with whether + each names a lane. Source structure, read mechanically from the span Charon gave.""" + d = src_defs[sym] + body = Path(lg_src, d["file"]).read_bytes() + out = [] + span = body[int(d["start"]):int(d["end"])] + pats = (rb"\bt:\s*([^,\n]+),", rb"SetExpr::i32\([^,]+,\s*Cmp::\w+,\s*([^)\n]+)\)") + for pat in pats: + for m in re.finditer(pat, span): + line = body[: int(d["start"]) + m.start()].count(NL) + 1 + out.append((f"crates/foundry-parity-lab/{d['file']}:{line}", + m.group(1).decode().strip(), b"lane" in m.group(1))) + return sorted(out, key=lambda x: int(x[0].rsplit(":", 1)[1])) + + def reach(root): + # Visited per (symbol, possible?) so a dispatch or closure visit cannot hide a later + # resolved-call path. A symbol is possible-only when no definite path reaches it. + visited, stack = {(root, False)}, [(root, False)] + while stack: + x, p = stack.pop() + nxt = [(c, p) for c in callees.get(x, ())] + nxt += [(i, True) for t in may.get(x, ()) for i in impls.get(t, ())] + nxt += [(c, True) for c in owned.get(x, ())] + for state in nxt: + if state not in visited: + visited.add(state) + stack.append(state) + definite = {x for x, p in visited if not p} + seen = {x for x, _ in visited} + return seen, seen - definite + + def short(s): + return s.split("::", 1)[1].split("::{impl")[0] + + lg = "AdaWorldAPI/lance-graph" + w_comp = lambda st, wit, q=None: {"grade": "COMPILER_DERIVED", "qualifier": q, "statement": st, "witness": wit, + "repo": lg, "revision": a.lg_rev, "tool": "charon c69e231 + ruff_charon"} + w_src = lambda st, wit: {"grade": "SOURCE_STRUCTURE", "statement": st, "witness": wit, "repo": "AdaWorldAPI/ndarray", + "revision": a.head, "tool": "git"} + + ev, exec_divs, confirmed, possible, missing_entry = [], set(), [], [], [] + ev.append(w_src(f"#422 changes {len(changed)} files: {len(rust)} Rust, {sum(1 for n in in_example.values() if n)} in example target(s) " + f"{sorted({n for n in in_example.values() if n})}; library Rust files changed: {len(lib_rust)}; " + f"other Rust files changed: {len(other_rust)}", + f"{a.base[:12]}..{a.head[:12]}")) + for label, roots in ENTRY_POINTS.items(): + for root in roots: + full = f"{CRATE}::{root}" + if full not in defs: + ev.append(w_comp(f"{label}: `{root}` is not in the store", "-")) + missing_entry.append(f"{label}: {root}") + continue + seen, poss = reach(full) + hits = sorted(x for x in seen if x in divs) + confirmed.append(f"{label}: {short(full)}") + ext = sorted({x.split("::")[0] for x in seen if not x.startswith(CRATE)} - {"core", "alloc", "std"}) + ev.append(w_comp(f"{label}: `{short(full)}` reaches {len(seen)} functions ({len(poss)} only via dispatch or a closure body); " + f"divisions reached: {[short(h) for h in hits] or 'none'}; other crates reached: {ext}", "store")) + exec_divs.update(hits) + for s in sorted(exec_divs): + for wit, text in divs[s]: + ev.append(w_comp(f"integer division on an executable path, in `{short(s)}`: `{text}`", wit)) + threshold_rows = {s: thresholds(s) for s in sorted(exec_divs)} + lg_src_w = lambda st, wit: {"grade": "SOURCE_STRUCTURE", "statement": st, "witness": wit, "repo": lg, + "revision": a.lg_rev, "tool": "source span read"} + for s, ts in threshold_rows.items(): + for wit, t, names_lane in ts: + ev.append(lg_src_w(f"mask-predicate threshold in `{short(s)}`: `t: {t}` ({'names a lane' if names_lane else 'names no lane'})", wit)) + reg_divs = set() + for root in REGISTRATION: + full = f"{CRATE}::{root}" + if full not in defs: + sys.exit(f"registration root {root} is not in the store") + seen, _ = reach(full) + reg_divs.update(x for x in seen if x in divs and x not in exec_divs) + for s in sorted(reg_divs): + for wit, text in divs[s]: + ev.append(w_comp(f"integer division at G6 method registration (`{short(s)}`, reached from " + f"{[r for r in REGISTRATION]}, not from the G6 execution entry points): `{text}`", wit)) + for wit, t, names_lane in thresholds(s): + ev.append(lg_src_w(f"mask-predicate threshold in `{short(s)}`: `{t}` ({'names a lane' if names_lane else 'names no lane'})", wit)) + for root in REFERENCE_ARMS: + full = f"{CRATE}::{root}" + seen, poss = reach(full) + for h in sorted(x for x in seen if x in divs): + how = ("through a closure body linked to its parent by Charon's name only" if h in poss + else "through resolved calls") + for wit, text in divs[h]: + ev.append(w_comp(f"reference arm `{short(full)}` reaches `{short(h)}` {how}: `{text}`", wit, + "POSSIBLE" if h in poss else None)) + possible.append(f"{short(full)} → {short(h)}") + # How mask-risc evaluates the `GeI32` predicate the G1/G6 thresholds feed. Not in the Charon + # store, so read as source at the extraction revision; the kernel is read at #422's head. + ir, ex = (risc / "ir.rs").read_text(), (risc / "exec.rs").read_text() + kern = git(nd, "show", f"{a.head}:src/simd_masking_ops.rs") + risc_w = lambda st, f, needle: lg_src_w(st, f"crates/lance-graph-mask-risc/src/{f}:{locate(ir if f == 'ir.rs' else ex, needle)}") + ev.append(risc_w("mask-risc `Pred::GeI32 { lane: u16, t: i32 }` is `lane[i] >= t` with `t` a scalar `i32`", + "ir.rs", "GeI32 { lane: u16, t: i32 }")) + ev.append(risc_w("the executor passes `t` unchanged to `ndarray::simd::ge_i32_to_mask`", + "exec.rs", "(Pred::GeI32 { lane, t: v }, None) => ge_i32_to_mask")) + ev.append(w_src("`ge_i32_to_mask` is the complement of `lt_i32_to_mask`, a compare of each lane value against " + "the splatted threshold; no division", + f"src/simd_masking_ops.rs:{locate(kern, 'pub fn ge_i32_to_mask(')}")) + unknown = [{"what": f"entry point {m}", "why": "not in the store; its path was not examined"} for m in missing_entry] + unknown += [{"what": "lance-graph-mask-risc beyond `GeI32`", "why": "not in the Charon store; only the `GeI32` evaluation path was read, as source"}, + {"what": "G1 per-store min/argmin (limiting resource)", "why": "not shipped: open in EXO-227 (P1b); this review covers shipped code only"}, + {"what": "production recipe divisor distribution", "why": "no production source; the only population is the synthetic fixture"}, + {"what": f"{sum(len(v) for v in owned.values())} closure bodies in the crate", "why": "linked to their parent by Charon's naming only (POSSIBLE), not by a call row"}] + if residuals: + unknown.append({"what": f"{len(residuals)} residual facts", "why": "ruff_charon could not represent them"}) + + stock_quotient_on_exec = any("/ d" in t for s in exec_divs for _, t in divs[s]) + # Every executable division must sit in a threshold operand that names no lane. + def in_scalar_threshold(s, text): + """The division is a lane-free threshold operand, directly or through one `let NAME = `.""" + d = src_defs[s] + span = Path(lg_src, d["file"]).read_bytes()[int(d["start"]):int(d["end"])].decode() + m = re.search(r"let\s+(\w+)\s*=\s*" + re.escape(text), span) + names = {text} | ({m.group(1)} if m else set()) + return any(not lane and any(n in t for n in names) for _, t, lane in thresholds(s)) + div_in_scalar_threshold = all(in_scalar_threshold(s, text) for s in exec_divs for _, text in divs[s]) + reg_in_scalar_threshold = all(in_scalar_threshold(s, text) for s in reg_divs for _, text in divs[s]) + g6_compares_dq = any(t.replace(" ", "") == "d*q" and not lane for s in reg_divs for _, t, lane in thresholds(s)) + findings = [{ + "id": "Q1", "kind": "admission", + "location": {"file": "examples/u64x64/route_c.rs", "symbol": "u64x64 route C / A power-of-two quotient arms"}, + "claim": (("In the consumer's shipped code, the per-row power-of-two quotient specialisation in #422 has no " + "call site to reach. #422's Rust changes are confined to the `u64x64` example target, which no crate " + "can depend on. The G1 and G6 paths in the Charon store reach no per-row stock quotient: their " + "mask predicates compare a stock lane against a scalar threshold" + + (" (G6: `d * q`, built at method registration)" if g6_compares_dq else "") + + ", and mask-risc evaluates `GeI32` as a plain compare. Not covered: mask-risc predicates other " + "than `GeI32`, and G1's unshipped per-store min/argmin step (EXO-227 P1b).") + if not stock_quotient_on_exec and not lib_rust and not other_rust and not missing_entry else + "Not established: " + + "; ".join(x for x in ( + "a stock quotient is on an executable path" if stock_quotient_on_exec else "", + f"library Rust changed ({len(lib_rust)} files)" if lib_rust else "", + f"Rust changed outside the library and the example targets: {other_rust}" if other_rust else "", + f"entry points missing from the store, so their paths were not examined: {missing_entry}" if missing_entry else "", + ) if x) + ". See evidence."), + "evidence": ev, + "reachability": {"confirmed": confirmed, "possible": possible, "unknown": unknown}, + "coverage": {"consumer_store": f"{CRATE} library target", "consumer_residuals": len(residuals), + "ndarray_library_rust_changed": len(lib_rust), "ndarray_other_rust_outside_examples": len(other_rust)}, + "falsifier": {"description": ("Run Charon on lance-graph-mask-risc and re-run the reach from the G1/G6 entry points " + "into it: any `DivisionByZero` assertion on a path that takes a stock lane as an " + "operand refutes the claim. Smallest next verification: the predicate kinds other " + "than `GeI32` that the consumer builds."), + "status": "NOT_RUN"}, + "suggestion": {"refusal": "an admission finding, not a defect: no code change follows from the evidence"}, + }] + if exec_divs: + sites = [w for s in sorted(exec_divs) for w, _ in divs[s]] + th = [lg_src_w(f"`t: {t}` ({'names a lane' if lane else 'names no lane'})", wit) + for s in sorted(exec_divs) for wit, t, lane in threshold_rows[s] if "/" in t] + findings.append({ + "id": "Q2", "kind": "research", + "location": {"file": "crates/foundry-parity-lab/src/arm_b.rs", "symbol": "arm_b::{ItemQuery}::cook_ops"}, + "claim": (("The executable path does evaluate integer division: `(q + per_staff - 1) / per_staff`. It is the " + "threshold operand of a mask predicate and names no lane, so it is computed once when the predicate is " + "built, not per row. G6 has the same ceiling division at method registration" + + ("" if reg_in_scalar_threshold else " (not confirmed as a threshold operand)") + + ". In shipped code, a per-row quotient specialisation has nothing to apply to.") + if div_in_scalar_threshold else + "The executable path evaluates integer division outside a scalar threshold; see evidence."), + "evidence": [w_comp("division assertion (zero and overflow) at this site", w) for w in sites] + + [w_comp("division assertion at G6 method registration", w) for s in sorted(reg_divs) for w, _ in divs[s]] + + th, + "reachability": {"confirmed": [short(s) for s in sorted(exec_divs | reg_divs)]}, + "falsifier": {"description": "Read the Pred::GeI32 threshold sites: the division's operands are query parameters, not lanes.", + "status": "NOT_RUN"}, + "suggestion": {"file": f"{PLAN} (ndarray)", "line": locate(plan, "quotient is evaluated on the executable path"), + "text": ("Narrow 'No quotient is evaluated on the executable path' to 'no per-row stock " + "quotient is evaluated': a scalar ceiling division builds the staff threshold."), + "base_sha": a.head}, + }) + findings.append({ + "id": "Q3", "kind": "research", + "location": {"file": "examples/u64x64/main.rs"}, + "claim": "The PR's benchmark results (power-of-two shift no-regret; best route only on AVX-512 hot) were not re-run here.", + "evidence": [{"grade": "ASSERTED", "statement": "benchmark results and disable runs, author-reported (plan §17)", + "witness": f"{PLAN}:{locate(plan, '## 17. Results, D-QUOT8-ADMISSION-0')}", + "repo": "AdaWorldAPI/ndarray", "revision": a.head}], + "falsifier": {"description": ("Per tier T in v2/v3/v4, build with `env -u RUSTFLAGS cargo --config .cargo/config-$T.toml " + "rustc --release --example u64x64` (plan §4) and run `u64x64 bench ` for the " + "§16 scenarios; compare with §17. The F7/F8 disable arms (test `d > 0` instead of " + "`is_power_of_two`) are parity checks: they must turn `u64x64 check` red, and say " + "nothing about speed."), + "status": "NOT_RUN"}, + "suggestion": {"refusal": "a performance claim outside this review's evidence; no defect follows"}, + }) + review = {"review": {"repo": "AdaWorldAPI/ndarray", "pr": 422, "base_sha": a.base, "head_sha": a.head, + "heads": {lg: a.lg_rev}, + "scope": ("PR #422 commits; consumer: lance-graph foundry-parity-lab (lib), extracted at " + f"{a.lg_rev}" + (f"; foundry-parity-lab and mask-risc unchanged at {a.lg_head}" + if same_at_head else "")), + "reviewer": {"tool": "crai_report.py + build_q8_evidence.py"}}, + "run": {"status": "PARTIAL", "reasons": ["mask-risc not in the Charon store (GeI32 read as source only)", + "no test or benchmark executed"]}, + "findings": findings} + json.dump(review, sys.stdout, indent=1, sort_keys=True) + print() + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/.claude/probes/2026-11-11-crai-report-1/crai_report.py b/.claude/probes/2026-11-11-crai-report-1/crai_report.py new file mode 100644 index 000000000..54f3a046c --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/crai_report.py @@ -0,0 +1,450 @@ +#!/usr/bin/env python3 +"""D-CRAI-REPORT-1: render compiler evidence as a CodeRabbit-shaped review, read-only. + + render --input REVIEW.json --md OUT.md --ndjson OUT.ndjson + from-packet --packet PACKET.json --repo R --pr N --head SHA [--scope S] > REVIEW.json + --self-test + +The finding record keeps CodeRabbit's public `--agent` fields (`fileName`, `comment`, `severity`, +`suggestions`, `codegenInstructions`; CR-SRC-01) and adds crai-rs's five separate axes +(CR-H0-REVIEW-SEMANTICS §2): severity, evidence class, confidence, provenance, lifecycle. + +The renderer computes, never accepts: +- the evidence class: the highest grade among witnesses that are current. Severity, confidence + and repetition never raise it (RS-F01, RS-F08). TEST_OBSERVED needs a test that was run and + shown able to fail (a disable or mutation run red, then the code green; §5, RS-F05). +- the finding status: a witness from a revision other than the review head, or from a stale + file, makes the finding `stale` with no coverage claim (RS-F04). +- whether the review is clean: only a COMPLETE run on the head with zero open findings + (§3, RS-F03). + +It never posts, applies or uploads anything. A suggestion is printed as an inert proposal bound to +its base revision and span; reviewer and agent text is printed as quoted data (RS-F09). +""" + +import argparse +import json +import sys +import tempfile +import unittest +from pathlib import Path + +GRADES = ["ASSERTED", "SOURCE_STRUCTURE", "COMPILER_DERIVED", "TEST_OBSERVED"] +RUN_STATUSES = {"NOT_RUN", "SKIPPED", "PARTIAL", "COMPLETE", "FAILED"} +FINDING_STATUSES = {"open", "resolved", "outdated", "stale", "withdrawn"} +KINDS = {"defect", "impact", "coverage", "admission", "research"} +SEMANTICS = "crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35)" + + +class InputError(Exception): + pass + + +def heads_of(review): + """Head revision per repository: the PR's own repo plus any declared in `review.heads`. A + witness from a repository with no declared head can never be current.""" + r = review["review"] if "review" in review else review + return {r["repo"]: r["head_sha"], **(r.get("heads") or {})} + + +def witness_is_current(w, heads, repo): + want = heads.get(w.get("repo", repo)) + return want is not None and w.get("revision") == want and w.get("fresh", True) + + +def evidence_class(finding, heads, repo): + """Highest grade among current witnesses. A TEST_OBSERVED witness counts only when its + falsifier ran red under a disable/mutation and green on the code (§5).""" + best = 0 + for w in finding.get("evidence", []): + if not witness_is_current(w, heads, repo): + continue + g = w.get("grade") + if g not in GRADES: + raise InputError(f"{finding['id']}: unknown grade {g!r}") + if g == "TEST_OBSERVED" and finding.get("falsifier", {}).get("status") != "RAN_RED_THEN_GREEN": + g = "ASSERTED" # a statement about a test that did not run red-then-green is a claim + best = max(best, GRADES.index(g)) + return GRADES[best] + + +def finding_status(finding, heads, repo): + stated = finding.get("status", "open") + if stated not in FINDING_STATUSES: + raise InputError(f"{finding['id']}: unknown status {stated!r}") + if stated in ("withdrawn", "resolved", "outdated"): + return stated + ev = finding.get("evidence", []) + if any(not witness_is_current(w, heads, repo) for w in ev): + return "stale" + return stated + + +def normalise(review): + """Validate the input and derive every computed field. Deterministic: no clock, no + environment, stable ordering.""" + r = review["review"] + head, repo, heads = r["head_sha"], r["repo"], heads_of(review) + run = review["run"] + if run["status"] not in RUN_STATUSES: + raise InputError(f"unknown run status {run['status']!r}") + out = [] + seen_claims = {} + for f in sorted(review.get("findings", []), key=lambda f: f["id"]): + if f.get("kind") not in KINDS: + raise InputError(f"{f['id']}: unknown kind {f.get('kind')!r}") + g = dict(f) + g["evidence_class"] = evidence_class(f, heads, repo) + g["status"] = finding_status(f, heads, repo) + g["confidence"] = f.get("confidence") if (f.get("confidence") or {}).get("source") else {"value": "UNKNOWN", "source": None} + g["severity"] = f.get("severity") # verbatim reviewer label, or None; never computed + fs = f.get("falsifier") or {} + g["falsifier"] = {"description": fs.get("description", "NOT_SPECIFIED"), "command": fs.get("command"), + "status": fs.get("status", "NOT_RUN"), "disable_run": fs.get("disable_run")} + # A repeat is the same claim, at the same place, in the same lifecycle state. A resolved + # record never absorbs an open one elsewhere or in another state. + loc = f.get("location") or {} + claim = (f.get("claim") or "").strip().lower() + key = (claim, loc.get("file"), loc.get("symbol"), tuple(loc.get("lines") or ()), g["status"]) if claim else None + if key and key in seen_claims: + g["duplicate_of"] = seen_claims[key] # repetition is not a second witness (RS-F08) + elif key: + seen_claims[key] = f["id"] + reach = f.get("reachability") or {} + g["reachability"] = {"confirmed": sorted(reach.get("confirmed", [])), + "possible": sorted(reach.get("possible", [])), + "unknown": sorted(reach.get("unknown", []), key=json.dumps)} + out.append(g) + open_findings = [f for f in out if f["status"] == "open" and "duplicate_of" not in f] + # A stale finding was neither confirmed nor refuted at this head, so it blocks a clean verdict. + stale = [f for f in out if f["status"] == "stale" and "duplicate_of" not in f] + wrong_head = run.get("head_sha", head) != head + clean = run["status"] == "COMPLETE" and not open_findings and not stale and not wrong_head + counts = f"{len(open_findings)} open finding(s)" + (f", {len(stale)} stale, not revalidated at the head" if stale else "") + verdict = ("CLEAN: complete run on the head, zero open or stale findings" if clean + else f"INCOMPLETE REVIEW: run {run['status']}; not a defect verdict ({counts})" if run["status"] != "COMPLETE" + else f"INCOMPLETE REVIEW: the run was on {run['head_sha']}, not the review head ({counts})" if wrong_head + else counts) + return {"review": r, "run": run, "findings": out, "verdict": verdict, "clean": clean} + + +def site(f): + loc = f.get("location") or {} + lines = loc.get("lines") + return loc.get("file", "-") + (f":{lines[0]}-{lines[1]}" if lines else "") + + +def to_ndjson(n): + r, rows = n["review"], [] + rows.append({"type": "review_start", "repo": r["repo"], "pr": r.get("pr"), "base_sha": r.get("base_sha"), + "head_sha": r["head_sha"], "heads": heads_of(n), "scope": r.get("scope"), "reviewer": r.get("reviewer"), + "semantics": SEMANTICS}) + for f in n["findings"]: + sug = f.get("suggestion") or {} + rows.append({ + "type": "finding", "id": f["id"], "kind": f["kind"], + "fileName": (f.get("location") or {}).get("file"), "lines": (f.get("location") or {}).get("lines"), + "symbol": (f.get("location") or {}).get("symbol"), + "comment": f.get("claim"), "severity": f["severity"], + "suggestions": [sug] if sug.get("text") else [], + "codegenInstructions": None, + "evidence_class": f["evidence_class"], "confidence": f["confidence"], + "provenance": f.get("provenance"), "status": f["status"], + "evidence": f.get("evidence", []), "reachability": f["reachability"], + "coverage": f.get("coverage", {}), "falsifier": f["falsifier"], + "refusal": sug.get("refusal"), "duplicate_of": f.get("duplicate_of"), + "status_detail": f.get("status_detail"), + }) + rows.append({"type": "complete", "status": n["run"]["status"], "reasons": n["run"].get("reasons", []), + "findings": len(n["findings"]), "clean": n["clean"], "verdict": n["verdict"]}) + return "".join(json.dumps(x, sort_keys=True, ensure_ascii=False) + "\n" for x in rows) + + +def q(text): + """Untrusted text as a Markdown blockquote: never a heading, link target or instruction.""" + return "\n".join("> " + ln.replace("`", "'") for ln in str(text).splitlines()) or "> " + + +def inline(text): + """Untrusted text inside one Markdown line or table cell: one line, no code span, no cell + break. An embedded newline can therefore never start a heading or a list item.""" + return " ".join(str(text).split()).replace("`", "'").replace("|", "/") + + +def to_md(n): + r = n["review"] + L = [f"# Review: {r['repo']}" + (f" #{r['pr']}" if r.get("pr") else ""), "", + f"- **Head:** `{r['head_sha']}`" + (f" (base `{r['base_sha']}`)" if r.get("base_sha") else ""), + *[f"- **Evidence head, {k}:** `{v}`" for k, v in sorted(heads_of(n).items()) if k != r["repo"]], + f"- **Scope:** {inline(r.get('scope', 'not stated'))}", + f"- **Reviewer:** {inline(json.dumps(r.get('reviewer'), sort_keys=True))}", + f"- **Run:** `{n['run']['status']}`" + (" (" + "; ".join(inline(x) for x in n["run"].get("reasons", [])) + ")" if n["run"].get("reasons") else ""), + f"- **Verdict:** {inline(n['verdict'])}", f"- **Semantics:** {SEMANTICS}. Severity, evidence and confidence are separate axes.", ""] + if not n["findings"]: + L += ["No findings." + ("" if n["clean"] else " This is **not** a clean review: the run did not complete."), ""] + for f in n["findings"]: + L += [f"## {f['id']} · {f['kind']} · {f['status']}", "", + f"**Location:** `{site(f)}`" + (f" · `{(f.get('location') or {}).get('symbol')}`" if (f.get('location') or {}).get('symbol') else ""), "", + f"| severity | evidence class | confidence |", "|---|---|---|", + f"| {f['severity']['value'] + ' (' + f['severity']['source'] + ')' if f['severity'] else 'not assessed'} | {f['evidence_class']} | {f['confidence']['value']}" + + (f" ({f['confidence']['source']})" if f['confidence']['source'] else "") + " |", "", + "**Claim**", "", q(f.get("claim", "")), ""] + if f.get("duplicate_of"): + L += [f"Same claim as {f['duplicate_of']}; not counted as a second witness.", ""] + if f.get("evidence"): + L += ["**Evidence**", "", "| grade | qualifier | statement | witness | revision |", "|---|---|---|---|---|"] + for w in f["evidence"]: + cur = "" if witness_is_current(w, heads_of(n), r["repo"]) else " (not current)" + where = (w.get("repo") or r["repo"]).split("/")[-1] + L.append(f"| {w['grade']} | {w.get('qualifier') or ''} | {inline(w.get('statement', ''))} | `{inline(where)}:{inline(w.get('witness', '-'))}` | `{(w.get('revision') or '-')[:12]}`{cur} |") + L.append("") + rc = f["reachability"] + if any(rc.values()): + L += ["**Reachability**", "", f"- confirmed: {', '.join(f'`{x}`' for x in rc['confirmed']) or 'none observed'}", + f"- possible: {', '.join(f'`{x}`' for x in rc['possible']) or 'none observed'}", + "- unknown: " + ("; ".join(u.get("what", str(u)) + (f" ({u['why']})" if u.get("why") else "") for u in rc["unknown"]) or "none recorded"), ""] + cov = f.get("coverage") or {} + if cov: + L += ["**Coverage**", ""] + [f"- {k}: {v}" for k, v in sorted(cov.items())] + [""] + fs = f["falsifier"] + L += ["**Falsifier**", "", f"- {fs['description']}", f"- status: `{fs['status']}`" + + (f", command `{fs['command']}`" if fs.get("command") else "")] + if fs.get("disable_run"): + L.append(f"- disable run: {fs['disable_run']}") + L.append("") + sug = f.get("suggestion") or {} + if sug.get("text"): + L += ["**Suggestion** (inert proposal; applying it needs the owner's approval and revalidation" + f" against `{sug.get('base_sha', '?')[:12]}`)", "", q(sug["text"]), ""] + elif sug.get("refusal"): + L += [f"**No suggestion:** {sug['refusal']}", ""] + if f.get("status_detail"): + L += [f"**Status detail:** {f['status_detail']}", ""] + return "\n".join(L).rstrip("\n") + "\n" + + +# -------------------------------------------------------------------------------------------- +# Adapter: a recon.py ReviewEvidencePacket into review input. Facts only; no severity. + +def from_packet(p, repo, pr, head, scope): + ident, cs, aff = p["identity"], p["changed_source"], p["affected_symbols"] + src = ident["source_span"] + rev = ident["commit_sha"] + fresh = not cs["stale"] and not cs.get("dependency_evidence_stale", False) + prov = {"tool": "lance-graph recon.py packet over a Charon/ruff_charon store", "revision": rev, + "crate_instance": ident["crate_instance"], "features": ident["features"], + "target": ident["target_triple"], "rustc": ident["rustc_version"]} + loc = {"file": src["file"], "lines": src["lines"], "symbol": cs["subject"]} + wit = [{"grade": "COMPILER_DERIVED", "statement": f"`{e['caller']}` calls `{cs['subject']}`", "witness": s, + "tool": "charon", "revision": rev, "fresh": fresh and e.get("fresh", True)} + for e in p.get("witnessed_edges", []) for s in e["sites"]] + tests = [i for f in p["findings"] if f["id"] == "tests" for i in f["items"]] + findings = [{ + "id": "F1", "kind": "impact", "location": loc, "provenance": prov, + "claim": f"Changing `{cs['subject']}` affects its in-store callers. Callers outside the analysed crates are not observed.", + "evidence": wit, + "reachability": {"confirmed": aff["confirmed"], "possible": aff["possible"], "unknown": aff["unknown"]}, + "coverage": {"observed_crate": ident["crate_instance"], "unsupported_regions": len(p.get("unsupported_regions", []))}, + "falsifier": {"description": "Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`.", + "status": "NOT_RUN"}, + "suggestion": {"refusal": "impact is a fact, not a defect; nothing to change"}, + }, { + "id": "F2", "kind": "coverage", "location": loc, "provenance": prov, + "claim": f"{len(tests)} test call sites match `{cs['subject'].split('::')[-1]}` by name. None is resolved to this symbol, and none ran.", + "evidence": [{"grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "statement": f"name match, receiver unresolved ({i['ra']})", + "witness": i["site"], "tool": "source search", "revision": rev, "fresh": fresh} for i in tests], + "reachability": {"unknown": [{"what": "test callers", "why": "library targets only; macro regions and cfg(test) modules not indexed"}]}, + "falsifier": {"description": "Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out.", + "status": "NOT_RUN"}, + "suggestion": {"refusal": "coverage gap; the next step is extraction, not a code change"}, + }] + return {"review": {"repo": repo, "pr": pr, "head_sha": head, "base_sha": cs.get("base"), "scope": scope, + "reviewer": {"tool": "crai_report.py", "input": "ReviewEvidencePacket"}}, + "run": {"status": "PARTIAL", "reasons": ["library targets only", "consumer crates not in store", "no test executed"]}, + "findings": findings} + + +# -------------------------------------------------------------------------------------------- +# Negative controls (D-CRAI-REPORT-1 Gate 3; crai-rs RS-F01..F10 where they apply). + +HEAD = "a" * 40 +OLD = "b" * 40 + + +def base(findings, status="COMPLETE"): + return {"review": {"repo": "x/y", "pr": 1, "head_sha": HEAD, "scope": "PR"}, "run": {"status": status}, "findings": findings} + + +def fnd(fid="F1", **kw): + f = {"id": fid, "kind": "defect", "claim": "c", "location": {"file": "a.rs", "lines": [1, 2]}} + f.update(kw) + return f + + +def w(grade, rev=HEAD, fresh=True, **kw): + return {"grade": grade, "statement": "s", "witness": "a.rs:1", "revision": rev, "fresh": fresh, **kw} + + +class Negatives(unittest.TestCase): + def test_missing_consumer_crates_yield_unknown_not_unaffected(self): + p = json.loads(Path(__file__).with_name("packet-LaneBinding-check.json").read_text()) + n = normalise(from_packet(p, "x/y", 1, p["identity"]["commit_sha"], "PR")) + unk = n["findings"][0]["reachability"]["unknown"] + self.assertTrue(any("outside the store" in u["what"] for u in unk)) + self.assertNotIn("unaffected", to_md(n).lower()) + + def test_stale_packet_cannot_produce_a_current_head_finding(self): # RS-F04 + n = normalise(base([fnd(evidence=[w("COMPILER_DERIVED", rev=OLD)])])) + self.assertEqual(n["findings"][0]["status"], "stale") + self.assertEqual(n["findings"][0]["evidence_class"], "ASSERTED") + n = normalise(base([fnd(evidence=[w("COMPILER_DERIVED", fresh=False)])])) + self.assertEqual(n["findings"][0]["status"], "stale") + + def test_cross_repo_evidence_is_current_only_at_its_own_head(self): + other = {"grade": "COMPILER_DERIVED", "statement": "s", "witness": "b.rs:1", "repo": "x/z", "revision": OLD} + undeclared = normalise(base([fnd(evidence=[other])])) + self.assertEqual(undeclared["findings"][0]["status"], "stale") # no declared head for x/z + rv = base([fnd(evidence=[other])]) + rv["review"]["heads"] = {"x/z": OLD} + self.assertEqual(normalise(rv)["findings"][0]["status"], "open") + self.assertEqual(normalise(rv)["findings"][0]["evidence_class"], "COMPILER_DERIVED") + + def test_partial_or_skipped_with_zero_findings_is_never_clean(self): # RS-F03 + for st in ("PARTIAL", "SKIPPED", "NOT_RUN", "FAILED"): + n = normalise(base([], status=st)) + self.assertFalse(n["clean"], st) + self.assertIn("INCOMPLETE REVIEW", n["verdict"]) + self.assertNotIn("CLEAN:", n["verdict"]) + self.assertTrue(normalise(base([]))["clean"]) # twin: COMPLETE with zero findings is clean + + def test_a_named_test_without_an_executed_falsifier_stays_not_run(self): # RS-F05 + n = normalise(base([fnd(evidence=[w("TEST_OBSERVED")], falsifier={"description": "t", "command": "cargo test x"})])) + self.assertEqual(n["findings"][0]["falsifier"]["status"], "NOT_RUN") + # A statement about a test that did not run is a claim, not source structure. + self.assertEqual(n["findings"][0]["evidence_class"], "ASSERTED") + green_only = fnd(evidence=[w("TEST_OBSERVED")], falsifier={"description": "t", "status": "RAN_GREEN_ONLY"}) + self.assertNotEqual(normalise(base([green_only]))["findings"][0]["evidence_class"], "TEST_OBSERVED") + ok = fnd(evidence=[w("TEST_OBSERVED")], falsifier={"description": "t", "status": "RAN_RED_THEN_GREEN"}) + self.assertEqual(normalise(base([ok]))["findings"][0]["evidence_class"], "TEST_OBSERVED") + + def test_compiler_evidence_and_reviewer_hypotheses_keep_separate_grades(self): # RS-F01/F02 + hyp = fnd("F1", severity={"value": "critical", "source": "reviewer"}, evidence=[w("ASSERTED")]) + comp = fnd("F2", claim="d", evidence=[w("COMPILER_DERIVED")]) + a, b = normalise(base([hyp, comp]))["findings"] + self.assertEqual((a["evidence_class"], a["severity"]["value"]), ("ASSERTED", "critical")) + self.assertEqual((b["evidence_class"], b["severity"]), ("COMPILER_DERIVED", None)) + self.assertEqual(a["confidence"]["value"], "UNKNOWN") # never derived from severity + + def test_an_irrelevant_benchmark_does_not_become_a_defect(self): + # A benchmark result with no witness on changed code is research, and stays ASSERTED. + bench = fnd(kind="research", claim="route F halves O6 on AVX-512", evidence=[w("ASSERTED")], + location={"file": "examples/u64x64/main.rs"}) + n = normalise(base([bench])) + self.assertEqual((n["findings"][0]["kind"], n["findings"][0]["evidence_class"]), ("research", "ASSERTED")) + self.assertNotIn("defect", to_ndjson(n)) + + def test_repeated_input_regenerates_byte_identical_reports(self): + p = json.loads(Path(__file__).with_name("packet-LaneBinding-check.json").read_text()) + i = from_packet(p, "x/y", 1, p["identity"]["commit_sha"], "PR") + a, b = normalise(json.loads(json.dumps(i))), normalise(json.loads(json.dumps(i))) + self.assertEqual((to_md(a), to_ndjson(a)), (to_md(b), to_ndjson(b))) + shuffled = dict(i, findings=list(reversed(i["findings"]))) + self.assertEqual(to_ndjson(normalise(shuffled)), to_ndjson(a)) + + def test_possible_dispatch_is_never_a_confirmed_caller(self): # RS-F07 + n = normalise(base([fnd(reachability={"possible": ["c"], "confirmed": []})])) + self.assertEqual(n["findings"][0]["reachability"]["confirmed"], []) + + def test_repetition_is_not_a_second_witness(self): # RS-F08 + n = normalise(base([fnd("F1", claim="same"), fnd("F2", claim="Same")])) + self.assertEqual(n["findings"][1].get("duplicate_of"), "F1") + self.assertIn("1 open finding", n["verdict"]) + + def test_a_stale_finding_blocks_a_clean_verdict(self): # RS-F04 + n = normalise(base([fnd(evidence=[w("COMPILER_DERIVED", rev=OLD)])])) + self.assertEqual(n["findings"][0]["status"], "stale") + self.assertFalse(n["clean"]) + self.assertIn("1 stale", n["verdict"]) + + def test_a_resolved_record_does_not_absorb_an_open_one(self): # RS-F08 + n = normalise(base([fnd("F1", claim="same", status="resolved", evidence=[w("COMPILER_DERIVED")]), + fnd("F2", claim="same", location={"file": "b.rs", "lines": [3, 4]}, + evidence=[w("COMPILER_DERIVED")])])) + self.assertNotIn("duplicate_of", n["findings"][1]) + self.assertFalse(n["clean"]) + self.assertIn("1 open finding", n["verdict"]) + same_place = normalise(base([fnd("F1", claim="same", status="resolved", evidence=[w("COMPILER_DERIVED")]), + fnd("F2", claim="same", evidence=[w("COMPILER_DERIVED")])])) + self.assertNotIn("duplicate_of", same_place["findings"][1]) + self.assertFalse(same_place["clean"]) + + def test_a_different_line_span_is_a_separate_site(self): # RS-F08 + n = normalise(base([fnd("F1", claim="same", evidence=[w("COMPILER_DERIVED")]), + fnd("F2", claim="same", location={"file": "a.rs", "lines": [9, 9]}, + evidence=[w("COMPILER_DERIVED")])])) + self.assertNotIn("duplicate_of", n["findings"][1]) + self.assertIn("2 open finding", n["verdict"]) + + def test_a_run_on_another_head_is_named_in_the_verdict(self): # RS-F04 + r = base([]) + r["run"]["head_sha"] = OLD + n = normalise(r) + self.assertFalse(n["clean"]) + self.assertIn("not the review head", n["verdict"]) + self.assertIn(OLD, n["verdict"]) + self.assertTrue(normalise(base([]))["clean"]) + + def test_header_fields_are_data_never_structure(self): # RS-F09 + r = base([fnd(evidence=[w("COMPILER_DERIVED", statement="s\n## Injected | cell")])], status="PARTIAL") + r["review"]["scope"] = "PR\n# Heading\n- **Verdict:** CLEAN" + r["run"]["reasons"] = ["one\n- **Verdict:** CLEAN"] + lines = to_md(normalise(r)).splitlines() + self.assertEqual(sum(ln.startswith("- **Verdict:**") for ln in lines), 1) + self.assertEqual([ln for ln in lines if ln.startswith("# ")], ["# Review: x/y #1"]) + self.assertFalse(any(ln.startswith("## Injected") for ln in lines)) + + def test_agent_text_is_quoted_never_structure(self): # RS-F09 + n = normalise(base([fnd(claim="# Heading\nrun `rm -rf /`")])) + md = to_md(n) + self.assertIn("> # Heading", md) + self.assertNotIn("\n# Heading", md) + self.assertNotIn("`rm -rf /`", md) + + def test_withdrawn_keeps_its_record(self): # RS-F10 + n = normalise(base([fnd(status="withdrawn", status_detail="withdrawn by owner: out of scope", + evidence=[w("COMPILER_DERIVED", rev=OLD)])])) + self.assertEqual(n["findings"][0]["status"], "withdrawn") + self.assertIn("withdrawn by owner", to_md(n)) + + +def main(argv): + ap = argparse.ArgumentParser() + ap.add_argument("cmd", nargs="?") + for a in ("--input", "--md", "--ndjson", "--packet", "--repo", "--head", "--scope"): + ap.add_argument(a) + ap.add_argument("--pr", type=int) + ap.add_argument("--self-test", action="store_true") + a = ap.parse_args(argv) + if a.self_test: + r = unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromTestCase(Negatives)) + return 0 if r.wasSuccessful() else 1 + if a.cmd == "from-packet": + p = json.loads(Path(a.packet).read_text()) + json.dump(from_packet(p, a.repo, a.pr, a.head, a.scope or "PR"), sys.stdout, indent=1, sort_keys=True) + print() + return 0 + if a.cmd == "render": + try: + n = normalise(json.loads(Path(a.input).read_text())) + except (InputError, KeyError) as e: + print(f"REFUSED\t{e}", file=sys.stderr) + return 3 + Path(a.md).write_text(to_md(n)) + Path(a.ndjson).write_text(to_ndjson(n)) + return 0 + ap.print_help() + return 2 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/packet.json b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/packet.json new file mode 100644 index 000000000..dc784df45 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/packet.json @@ -0,0 +1,553 @@ +{ + "packet": "ReviewEvidencePacket (prototype, read-only; not a vendor API)", + "identity": { + "repo_id": "AdaWorldAPI/lance-graph", + "commit_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "cargo_lock_sha": "NOT_TRACKED (repository tracks no Cargo.lock)", + "crate_instance": "lance_graph_dt64 (lib target)", + "features": "default", + "target_triple": "x86_64-unknown-linux-gnu", + "rustc_version": "nightly-2026-09-17 (charon)", + "file_blob_sha": "a0aa6e6658872d07c93990095d2fab2beff1487d", + "source_span": { + "file": "crates/lance-graph-dt64/src/lane.rs", + "bytes": [ + 10592, + 12497 + ], + "lines": [ + 307, + 349 + ] + } + }, + "changed_source": { + "subject": "lance_graph_dt64::lane::{LaneBinding}::check", + "base": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "diff": "NOT_SUPPLIED (prototype: change of the whole span)", + "stale": false, + "freshness": "FRESH", + "dependency_evidence_stale": false + }, + "affected_symbols": { + "confirmed": [ + "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "lance_graph_dt64::lane::{LaneBinding}::lane" + ], + "possible": [], + "stale": [], + "unknown": [ + { + "what": "callers in crates outside the store", + "observed_crates": [ + "lance_graph_contract", + "lance_graph_dt64", + "lance_graph_quack", + "lance_graph_r2il" + ], + "why": "symbol is PUBLIC; only these crates' library targets were compiled" + }, + { + "what": "test targets, examples, cfg(test) modules", + "why": "store holds library targets only" + } + ] + }, + "witnessed_edges": [ + { + "caller": "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "callee": "lance_graph_dt64::lane::{LaneBinding}::check", + "sites": [ + "crates/lance-graph-dt64/src/lane.rs:386" + ], + "fresh": true + }, + { + "caller": "lance_graph_dt64::lane::{LaneBinding}::lane", + "callee": "lance_graph_dt64::lane::{LaneBinding}::check", + "sites": [ + "crates/lance-graph-dt64/src/lane.rs:360" + ], + "fresh": true + } + ], + "possible_edges": [ + { + "dispatch_target": "lance_graph_dt64::lane::LaneSource::lane_of" + } + ], + "co_changed_only": "NOT_RUN (no history projection in this prototype)", + "unsupported_regions": [ + "crates/cognitive-polyfill-probe/tests/p0.rs", + "crates/dir-rmap-probe/tests/equivalence.rs", + "crates/dr-isa-stream-lab/tests/integration/g2l.rs", + "crates/dr-math-binding-probe/tests/binding.rs", + "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs", + "crates/lance-graph-dt64/tests/dr.rs", + "crates/lance-graph-dt64/tests/lane_socket.rs", + "crates/lance-graph-report/src/lane_source/tests.rs", + "crates/thought-git-probe/tests/receipt.rs", + "crates/xlog-relcomp-probe/tests/dto_binding.rs" + ], + "findings": [ + { + "id": "dependents", + "summary": "2 confirmed transitive in-store callers; external callers UNKNOWN", + "severity": null, + "evidence_class": "COMPILER_DERIVED", + "confidence": "as graded per item", + "provenance": { + "tool": "charon c69e231 -> ruff_charon import (rows.tsv v2)", + "toolchain": "nightly-2026-09-17", + "sysroot": "default (cargo-miri absent; std bodies opaque)" + }, + "lifecycle": "open", + "run_status": "PARTIAL" + }, + { + "id": "tests", + "summary": "48 candidate test call sites by name; none run", + "severity": null, + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "items": [ + { + "site": "crates/cognitive-polyfill-probe/tests/p0.rs:271", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/cognitive-polyfill-probe/tests/p0.rs:275", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:234", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:238", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:249", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:481", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:522", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:663", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:677", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:678", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:680", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:136", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:263", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dr-math-binding-probe/tests/binding.rs:234", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:58", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:60", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:72", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:82", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:86", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:89", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:90", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:93", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:776", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:777", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:808", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:814", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:824", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:827", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:828", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:227", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:277", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:314", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:369", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:373", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:403", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:407", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:424", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/thought-git-probe/tests/receipt.rs:715", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/thought-git-probe/tests/receipt.rs:715", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/xlog-relcomp-probe/tests/dto_binding.rs:233", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:320", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:341", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:418", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:623", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + } + ], + "provenance": { + "tool": "source search + rust-analyzer GRAPH=1 (ra_ap 0.0.358)" + }, + "lifecycle": "open", + "run_status": "NOT_RUN" + }, + { + "id": "contracts", + "summary": "trait methods the symbol dispatches through (a change may interact with any impl)", + "severity": null, + "evidence_class": "COMPILER_DERIVED", + "qualifier": "POSSIBLE", + "items": [ + "lance_graph_dt64::lane::LaneSource::lane_of" + ], + "provenance": { + "tool": "charon c69e231 -> ruff_charon import (rows.tsv v2)", + "toolchain": "nightly-2026-09-17", + "sysroot": "default (cargo-miri absent; std bodies opaque)" + }, + "lifecycle": "open", + "run_status": "COMPLETE" + }, + { + "id": "execution_paths", + "summary": "entry points (in-store callers with no in-store caller)", + "severity": null, + "evidence_class": "COMPILER_DERIVED", + "items": [ + "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "lance_graph_dt64::lane::{LaneBinding}::lane" + ], + "provenance": { + "tool": "charon c69e231 -> ruff_charon import (rows.tsv v2)", + "toolchain": "nightly-2026-09-17", + "sysroot": "default (cargo-miri absent; std bodies opaque)" + }, + "lifecycle": "open", + "run_status": "PARTIAL" + } + ], + "r2il": { + "method": "NOT_A_METHOD", + "body_semantics": "UNKNOWN", + "why": "R2IL describes the effects of a registered DT64 MethodBinding (prepare binds them to opcodes); a Rust function found by the compiler is not one, so its body has no R2IL reading" + }, + "expected_behavior": "NOT_SUPPLIED (must come from intent/tests, independently of this packet)", + "candidate_behavior": "NOT_INFERRED", + "missing_necessary_evidence": [ + "test runs (TEST_OBSERVED needs a run that can fail, CR-H0 \u00a75)", + "compiler artifacts of consumer crates and test targets", + "a resolved receiver for each name-matched test site" + ], + "permission_state": "NOT_DERIVED (never from confidence)" +} diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-input-stale.json b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-input-stale.json new file mode 100644 index 000000000..72b7a8c8b --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-input-stale.json @@ -0,0 +1,566 @@ +{ + "findings": [ + { + "claim": "Changing `lance_graph_dt64::lane::{LaneBinding}::check` affects its in-store callers. Callers outside the analysed crates are not observed.", + "coverage": { + "observed_crate": "lance_graph_dt64 (lib target)", + "unsupported_regions": 10 + }, + "evidence": [ + { + "fresh": true, + "grade": "COMPILER_DERIVED", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "`lance_graph_dt64::lane::{LaneBinding}::borrow_all` calls `lance_graph_dt64::lane::{LaneBinding}::check`", + "tool": "charon", + "witness": "crates/lance-graph-dt64/src/lane.rs:386" + }, + { + "fresh": true, + "grade": "COMPILER_DERIVED", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "`lance_graph_dt64::lane::{LaneBinding}::lane` calls `lance_graph_dt64::lane::{LaneBinding}::check`", + "tool": "charon", + "witness": "crates/lance-graph-dt64/src/lane.rs:360" + } + ], + "falsifier": { + "description": "Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`.", + "status": "NOT_RUN" + }, + "id": "F1", + "kind": "impact", + "location": { + "file": "crates/lance-graph-dt64/src/lane.rs", + "lines": [ + 307, + 349 + ], + "symbol": "lance_graph_dt64::lane::{LaneBinding}::check" + }, + "provenance": { + "crate_instance": "lance_graph_dt64 (lib target)", + "features": "default", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "rustc": "nightly-2026-09-17 (charon)", + "target": "x86_64-unknown-linux-gnu", + "tool": "lance-graph recon.py packet over a Charon/ruff_charon store" + }, + "reachability": { + "confirmed": [ + "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "lance_graph_dt64::lane::{LaneBinding}::lane" + ], + "possible": [], + "unknown": [ + { + "observed_crates": [ + "lance_graph_contract", + "lance_graph_dt64", + "lance_graph_quack", + "lance_graph_r2il" + ], + "what": "callers in crates outside the store", + "why": "symbol is PUBLIC; only these crates' library targets were compiled" + }, + { + "what": "test targets, examples, cfg(test) modules", + "why": "store holds library targets only" + } + ] + }, + "suggestion": { + "refusal": "impact is a fact, not a defect; nothing to change" + } + }, + { + "claim": "48 test call sites match `check` by name. None is resolved to this symbol, and none ran.", + "evidence": [ + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:271" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:275" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:234" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:238" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:249" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:481" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:522" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:663" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:677" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:678" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:680" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:136" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:263" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dr-math-binding-probe/tests/binding.rs:234" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:58" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:60" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:72" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:82" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:86" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:89" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:90" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:93" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:776" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:777" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:808" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:814" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:824" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:827" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:828" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:227" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:277" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:314" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:369" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:373" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:403" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:407" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:424" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/thought-git-probe/tests/receipt.rs:715" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/thought-git-probe/tests/receipt.rs:715" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/xlog-relcomp-probe/tests/dto_binding.rs:233" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:320" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:341" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:418" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:623" + } + ], + "falsifier": { + "description": "Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out.", + "status": "NOT_RUN" + }, + "id": "F2", + "kind": "coverage", + "location": { + "file": "crates/lance-graph-dt64/src/lane.rs", + "lines": [ + 307, + 349 + ], + "symbol": "lance_graph_dt64::lane::{LaneBinding}::check" + }, + "provenance": { + "crate_instance": "lance_graph_dt64 (lib target)", + "features": "default", + "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "rustc": "nightly-2026-09-17 (charon)", + "target": "x86_64-unknown-linux-gnu", + "tool": "lance-graph recon.py packet over a Charon/ruff_charon store" + }, + "reachability": { + "unknown": [ + { + "what": "test callers", + "why": "library targets only; macro regions and cfg(test) modules not indexed" + } + ] + }, + "suggestion": { + "refusal": "coverage gap; the next step is extraction, not a code change" + } + } + ], + "review": { + "base_sha": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "head_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "pr": 2000, + "repo": "AdaWorldAPI/lance-graph", + "reviewer": { + "input": "ReviewEvidencePacket", + "tool": "crai_report.py" + }, + "scope": "the same scope review, from a packet built at an older head" + }, + "run": { + "reasons": [ + "library targets only", + "consumer crates not in store", + "no test executed" + ], + "status": "PARTIAL" + } +} diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-input.json b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-input.json new file mode 100644 index 000000000..7454f6486 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-input.json @@ -0,0 +1,566 @@ +{ + "findings": [ + { + "claim": "Changing `lance_graph_dt64::lane::{LaneBinding}::check` affects its in-store callers. Callers outside the analysed crates are not observed.", + "coverage": { + "observed_crate": "lance_graph_dt64 (lib target)", + "unsupported_regions": 10 + }, + "evidence": [ + { + "fresh": true, + "grade": "COMPILER_DERIVED", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "`lance_graph_dt64::lane::{LaneBinding}::borrow_all` calls `lance_graph_dt64::lane::{LaneBinding}::check`", + "tool": "charon", + "witness": "crates/lance-graph-dt64/src/lane.rs:386" + }, + { + "fresh": true, + "grade": "COMPILER_DERIVED", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "`lance_graph_dt64::lane::{LaneBinding}::lane` calls `lance_graph_dt64::lane::{LaneBinding}::check`", + "tool": "charon", + "witness": "crates/lance-graph-dt64/src/lane.rs:360" + } + ], + "falsifier": { + "description": "Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`.", + "status": "NOT_RUN" + }, + "id": "F1", + "kind": "impact", + "location": { + "file": "crates/lance-graph-dt64/src/lane.rs", + "lines": [ + 307, + 349 + ], + "symbol": "lance_graph_dt64::lane::{LaneBinding}::check" + }, + "provenance": { + "crate_instance": "lance_graph_dt64 (lib target)", + "features": "default", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "rustc": "nightly-2026-09-17 (charon)", + "target": "x86_64-unknown-linux-gnu", + "tool": "lance-graph recon.py packet over a Charon/ruff_charon store" + }, + "reachability": { + "confirmed": [ + "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "lance_graph_dt64::lane::{LaneBinding}::lane" + ], + "possible": [], + "unknown": [ + { + "observed_crates": [ + "lance_graph_contract", + "lance_graph_dt64", + "lance_graph_quack", + "lance_graph_r2il" + ], + "what": "callers in crates outside the store", + "why": "symbol is PUBLIC; only these crates' library targets were compiled" + }, + { + "what": "test targets, examples, cfg(test) modules", + "why": "store holds library targets only" + } + ] + }, + "suggestion": { + "refusal": "impact is a fact, not a defect; nothing to change" + } + }, + { + "claim": "48 test call sites match `check` by name. None is resolved to this symbol, and none ran.", + "evidence": [ + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:271" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:275" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:234" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:238" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:249" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:481" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:522" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:663" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:677" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:678" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dir-rmap-probe/tests/equivalence.rs:680" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:136" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:263" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/dr-math-binding-probe/tests/binding.rs:234" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:58" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:60" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:72" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:82" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:86" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:89" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:90" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:93" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:776" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:777" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:808" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:814" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:824" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:827" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/dr.rs:828" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:227" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:277" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:314" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:369" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:373" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:403" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:407" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", + "tool": "source search", + "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:424" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/thought-git-probe/tests/receipt.rs:715" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/thought-git-probe/tests/receipt.rs:715" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/xlog-relcomp-probe/tests/dto_binding.rs:233" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:320" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:341" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:418" + }, + { + "fresh": true, + "grade": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", + "tool": "source search", + "witness": "crates/lance-graph-report/src/lane_source/tests.rs:623" + } + ], + "falsifier": { + "description": "Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out.", + "status": "NOT_RUN" + }, + "id": "F2", + "kind": "coverage", + "location": { + "file": "crates/lance-graph-dt64/src/lane.rs", + "lines": [ + 307, + 349 + ], + "symbol": "lance_graph_dt64::lane::{LaneBinding}::check" + }, + "provenance": { + "crate_instance": "lance_graph_dt64 (lib target)", + "features": "default", + "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "rustc": "nightly-2026-09-17 (charon)", + "target": "x86_64-unknown-linux-gnu", + "tool": "lance-graph recon.py packet over a Charon/ruff_charon store" + }, + "reachability": { + "unknown": [ + { + "what": "test callers", + "why": "library targets only; macro regions and cfg(test) modules not indexed" + } + ] + }, + "suggestion": { + "refusal": "coverage gap; the next step is extraction, not a code change" + } + } + ], + "review": { + "base_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "head_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", + "pr": 2000, + "repo": "AdaWorldAPI/lance-graph", + "reviewer": { + "input": "ReviewEvidencePacket", + "tool": "crai_report.py" + }, + "scope": "scope review of a hypothetical change to LaneBinding::check (lance-graph-dt64 lib); base equals head, no diff" + }, + "run": { + "reasons": [ + "library targets only", + "consumer crates not in store", + "no test executed" + ], + "status": "PARTIAL" + } +} diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-stale.md b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-stale.md new file mode 100644 index 000000000..7556b76f9 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-stale.md @@ -0,0 +1,123 @@ +# Review: AdaWorldAPI/lance-graph #2000 + +- **Head:** `90fc5a76c12714d3bd00bcc5be96125aef74d89f` (base `0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb`) +- **Scope:** the same scope review, from a packet built at an older head +- **Reviewer:** {"input": "ReviewEvidencePacket", "tool": "crai_report.py"} +- **Run:** `PARTIAL` (library targets only; consumer crates not in store; no test executed) +- **Verdict:** INCOMPLETE REVIEW: run PARTIAL; not a defect verdict (0 open finding(s), 2 stale, not revalidated at the head) +- **Semantics:** crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35). Severity, evidence and confidence are separate axes. + +## F1 · impact · stale + +**Location:** `crates/lance-graph-dt64/src/lane.rs:307-349` · `lance_graph_dt64::lane::{LaneBinding}::check` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | ASSERTED | UNKNOWN | + +**Claim** + +> Changing 'lance_graph_dt64::lane::{LaneBinding}::check' affects its in-store callers. Callers outside the analysed crates are not observed. + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| COMPILER_DERIVED | | 'lance_graph_dt64::lane::{LaneBinding}::borrow_all' calls 'lance_graph_dt64::lane::{LaneBinding}::check' | `lance-graph:crates/lance-graph-dt64/src/lane.rs:386` | `0c9ae23ac6a2` (not current) | +| COMPILER_DERIVED | | 'lance_graph_dt64::lane::{LaneBinding}::lane' calls 'lance_graph_dt64::lane::{LaneBinding}::check' | `lance-graph:crates/lance-graph-dt64/src/lane.rs:360` | `0c9ae23ac6a2` (not current) | + +**Reachability** + +- confirmed: `lance_graph_dt64::lane::{LaneBinding}::borrow_all`, `lance_graph_dt64::lane::{LaneBinding}::lane` +- possible: none observed +- unknown: callers in crates outside the store (symbol is PUBLIC; only these crates' library targets were compiled); test targets, examples, cfg(test) modules (store holds library targets only) + +**Coverage** + +- observed_crate: lance_graph_dt64 (lib target) +- unsupported_regions: 10 + +**Falsifier** + +- Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`. +- status: `NOT_RUN` + +**No suggestion:** impact is a fact, not a defect; nothing to change + +## F2 · coverage · stale + +**Location:** `crates/lance-graph-dt64/src/lane.rs:307-349` · `lance_graph_dt64::lane::{LaneBinding}::check` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | ASSERTED | UNKNOWN | + +**Claim** + +> 48 test call sites match 'check' by name. None is resolved to this symbol, and none ran. + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/cognitive-polyfill-probe/tests/p0.rs:271` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/cognitive-polyfill-probe/tests/p0.rs:275` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:234` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:238` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:249` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:481` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:522` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:663` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:677` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:678` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:680` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dr-isa-stream-lab/tests/integration/g2l.rs:136` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dr-isa-stream-lab/tests/integration/g2l.rs:263` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dr-math-binding-probe/tests/binding.rs:234` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:58` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:60` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:72` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:82` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:86` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:89` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:90` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:93` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:776` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:777` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:808` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:814` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:824` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:827` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:828` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:227` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:277` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:314` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:369` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:373` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:403` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:407` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:424` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/thought-git-probe/tests/receipt.rs:715` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/thought-git-probe/tests/receipt.rs:715` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/xlog-relcomp-probe/tests/dto_binding.rs:233` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:320` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:341` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:418` | `0c9ae23ac6a2` (not current) | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:623` | `0c9ae23ac6a2` (not current) | + +**Reachability** + +- confirmed: none observed +- possible: none observed +- unknown: test callers (library targets only; macro regions and cfg(test) modules not indexed) + +**Falsifier** + +- Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out. +- status: `NOT_RUN` + +**No suggestion:** coverage gap; the next step is extraction, not a code change diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-stale.ndjson b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-stale.ndjson new file mode 100644 index 000000000..4f09f6817 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review-stale.ndjson @@ -0,0 +1,4 @@ +{"base_sha": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "head_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "heads": {"AdaWorldAPI/lance-graph": "90fc5a76c12714d3bd00bcc5be96125aef74d89f"}, "pr": 2000, "repo": "AdaWorldAPI/lance-graph", "reviewer": {"input": "ReviewEvidencePacket", "tool": "crai_report.py"}, "scope": "the same scope review, from a packet built at an older head", "semantics": "crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35)", "type": "review_start"} +{"codegenInstructions": null, "comment": "Changing `lance_graph_dt64::lane::{LaneBinding}::check` affects its in-store callers. Callers outside the analysed crates are not observed.", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {"observed_crate": "lance_graph_dt64 (lib target)", "unsupported_regions": 10}, "duplicate_of": null, "evidence": [{"fresh": true, "grade": "COMPILER_DERIVED", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "`lance_graph_dt64::lane::{LaneBinding}::borrow_all` calls `lance_graph_dt64::lane::{LaneBinding}::check`", "tool": "charon", "witness": "crates/lance-graph-dt64/src/lane.rs:386"}, {"fresh": true, "grade": "COMPILER_DERIVED", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "`lance_graph_dt64::lane::{LaneBinding}::lane` calls `lance_graph_dt64::lane::{LaneBinding}::check`", "tool": "charon", "witness": "crates/lance-graph-dt64/src/lane.rs:360"}], "evidence_class": "ASSERTED", "falsifier": {"command": null, "description": "Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "crates/lance-graph-dt64/src/lane.rs", "id": "F1", "kind": "impact", "lines": [307, 349], "provenance": {"crate_instance": "lance_graph_dt64 (lib target)", "features": "default", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "rustc": "nightly-2026-09-17 (charon)", "target": "x86_64-unknown-linux-gnu", "tool": "lance-graph recon.py packet over a Charon/ruff_charon store"}, "reachability": {"confirmed": ["lance_graph_dt64::lane::{LaneBinding}::borrow_all", "lance_graph_dt64::lane::{LaneBinding}::lane"], "possible": [], "unknown": [{"observed_crates": ["lance_graph_contract", "lance_graph_dt64", "lance_graph_quack", "lance_graph_r2il"], "what": "callers in crates outside the store", "why": "symbol is PUBLIC; only these crates' library targets were compiled"}, {"what": "test targets, examples, cfg(test) modules", "why": "store holds library targets only"}]}, "refusal": "impact is a fact, not a defect; nothing to change", "severity": null, "status": "stale", "status_detail": null, "suggestions": [], "symbol": "lance_graph_dt64::lane::{LaneBinding}::check", "type": "finding"} +{"codegenInstructions": null, "comment": "48 test call sites match `check` by name. None is resolved to this symbol, and none ran.", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {}, "duplicate_of": null, "evidence": [{"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:271"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:275"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:234"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:238"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:249"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:481"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:522"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:663"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:677"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:678"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:680"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:136"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:263"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dr-math-binding-probe/tests/binding.rs:234"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:58"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:60"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:72"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:82"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:86"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:89"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:90"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:93"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:776"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:777"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:808"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:814"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:824"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:827"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:828"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:227"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:277"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:314"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:369"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:373"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:403"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:407"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:424"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/thought-git-probe/tests/receipt.rs:715"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/thought-git-probe/tests/receipt.rs:715"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/xlog-relcomp-probe/tests/dto_binding.rs:233"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:320"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:341"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:418"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:623"}], "evidence_class": "ASSERTED", "falsifier": {"command": null, "description": "Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "crates/lance-graph-dt64/src/lane.rs", "id": "F2", "kind": "coverage", "lines": [307, 349], "provenance": {"crate_instance": "lance_graph_dt64 (lib target)", "features": "default", "revision": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", "rustc": "nightly-2026-09-17 (charon)", "target": "x86_64-unknown-linux-gnu", "tool": "lance-graph recon.py packet over a Charon/ruff_charon store"}, "reachability": {"confirmed": [], "possible": [], "unknown": [{"what": "test callers", "why": "library targets only; macro regions and cfg(test) modules not indexed"}]}, "refusal": "coverage gap; the next step is extraction, not a code change", "severity": null, "status": "stale", "status_detail": null, "suggestions": [], "symbol": "lance_graph_dt64::lane::{LaneBinding}::check", "type": "finding"} +{"clean": false, "findings": 2, "reasons": ["library targets only", "consumer crates not in store", "no test executed"], "status": "PARTIAL", "type": "complete", "verdict": "INCOMPLETE REVIEW: run PARTIAL; not a defect verdict (0 open finding(s), 2 stale, not revalidated at the head)"} diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review.md b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review.md new file mode 100644 index 000000000..e9fcb4ea9 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review.md @@ -0,0 +1,123 @@ +# Review: AdaWorldAPI/lance-graph #2000 + +- **Head:** `90fc5a76c12714d3bd00bcc5be96125aef74d89f` (base `90fc5a76c12714d3bd00bcc5be96125aef74d89f`) +- **Scope:** scope review of a hypothetical change to LaneBinding::check (lance-graph-dt64 lib); base equals head, no diff +- **Reviewer:** {"input": "ReviewEvidencePacket", "tool": "crai_report.py"} +- **Run:** `PARTIAL` (library targets only; consumer crates not in store; no test executed) +- **Verdict:** INCOMPLETE REVIEW: run PARTIAL; not a defect verdict (2 open finding(s)) +- **Semantics:** crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35). Severity, evidence and confidence are separate axes. + +## F1 · impact · open + +**Location:** `crates/lance-graph-dt64/src/lane.rs:307-349` · `lance_graph_dt64::lane::{LaneBinding}::check` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | COMPILER_DERIVED | UNKNOWN | + +**Claim** + +> Changing 'lance_graph_dt64::lane::{LaneBinding}::check' affects its in-store callers. Callers outside the analysed crates are not observed. + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| COMPILER_DERIVED | | 'lance_graph_dt64::lane::{LaneBinding}::borrow_all' calls 'lance_graph_dt64::lane::{LaneBinding}::check' | `lance-graph:crates/lance-graph-dt64/src/lane.rs:386` | `90fc5a76c127` | +| COMPILER_DERIVED | | 'lance_graph_dt64::lane::{LaneBinding}::lane' calls 'lance_graph_dt64::lane::{LaneBinding}::check' | `lance-graph:crates/lance-graph-dt64/src/lane.rs:360` | `90fc5a76c127` | + +**Reachability** + +- confirmed: `lance_graph_dt64::lane::{LaneBinding}::borrow_all`, `lance_graph_dt64::lane::{LaneBinding}::lane` +- possible: none observed +- unknown: callers in crates outside the store (symbol is PUBLIC; only these crates' library targets were compiled); test targets, examples, cfg(test) modules (store holds library targets only) + +**Coverage** + +- observed_crate: lance_graph_dt64 (lib target) +- unsupported_regions: 10 + +**Falsifier** + +- Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`. +- status: `NOT_RUN` + +**No suggestion:** impact is a fact, not a defect; nothing to change + +## F2 · coverage · open + +**Location:** `crates/lance-graph-dt64/src/lane.rs:307-349` · `lance_graph_dt64::lane::{LaneBinding}::check` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | SOURCE_STRUCTURE | UNKNOWN | + +**Claim** + +> 48 test call sites match 'check' by name. None is resolved to this symbol, and none ran. + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/cognitive-polyfill-probe/tests/p0.rs:271` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/cognitive-polyfill-probe/tests/p0.rs:275` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:234` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:238` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:249` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:481` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:522` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:663` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:677` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:678` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dir-rmap-probe/tests/equivalence.rs:680` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dr-isa-stream-lab/tests/integration/g2l.rs:136` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dr-isa-stream-lab/tests/integration/g2l.rs:263` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/dr-math-binding-probe/tests/binding.rs:234` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:58` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:60` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:72` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:82` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:86` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:89` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:90` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:93` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:776` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:777` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:808` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:814` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:824` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:827` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/dr.rs:828` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:227` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:277` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:314` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:369` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:373` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:403` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:407` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: inside a macro region) | `lance-graph:crates/lance-graph-dt64/tests/lane_socket.rs:424` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/thought-git-probe/tests/receipt.rs:715` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/thought-git-probe/tests/receipt.rs:715` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/xlog-relcomp-probe/tests/dto_binding.rs:233` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:320` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:341` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:418` | `90fc5a76c127` | +| SOURCE_STRUCTURE | POSSIBLE | name match, receiver unresolved (UNKNOWN: file not indexed) | `lance-graph:crates/lance-graph-report/src/lane_source/tests.rs:623` | `90fc5a76c127` | + +**Reachability** + +- confirmed: none observed +- possible: none observed +- unknown: test callers (library targets only; macro regions and cfg(test) modules not indexed) + +**Falsifier** + +- Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out. +- status: `NOT_RUN` + +**No suggestion:** coverage gap; the next step is extraction, not a code change diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review.ndjson b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review.ndjson new file mode 100644 index 000000000..960c8ce63 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/lance-graph-2000/review.ndjson @@ -0,0 +1,4 @@ +{"base_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "head_sha": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "heads": {"AdaWorldAPI/lance-graph": "90fc5a76c12714d3bd00bcc5be96125aef74d89f"}, "pr": 2000, "repo": "AdaWorldAPI/lance-graph", "reviewer": {"input": "ReviewEvidencePacket", "tool": "crai_report.py"}, "scope": "scope review of a hypothetical change to LaneBinding::check (lance-graph-dt64 lib); base equals head, no diff", "semantics": "crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35)", "type": "review_start"} +{"codegenInstructions": null, "comment": "Changing `lance_graph_dt64::lane::{LaneBinding}::check` affects its in-store callers. Callers outside the analysed crates are not observed.", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {"observed_crate": "lance_graph_dt64 (lib target)", "unsupported_regions": 10}, "duplicate_of": null, "evidence": [{"fresh": true, "grade": "COMPILER_DERIVED", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "`lance_graph_dt64::lane::{LaneBinding}::borrow_all` calls `lance_graph_dt64::lane::{LaneBinding}::check`", "tool": "charon", "witness": "crates/lance-graph-dt64/src/lane.rs:386"}, {"fresh": true, "grade": "COMPILER_DERIVED", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "`lance_graph_dt64::lane::{LaneBinding}::lane` calls `lance_graph_dt64::lane::{LaneBinding}::check`", "tool": "charon", "witness": "crates/lance-graph-dt64/src/lane.rs:360"}], "evidence_class": "COMPILER_DERIVED", "falsifier": {"command": null, "description": "Remove one witnessed call site and rebuild the store: the caller must leave `confirmed`.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "crates/lance-graph-dt64/src/lane.rs", "id": "F1", "kind": "impact", "lines": [307, 349], "provenance": {"crate_instance": "lance_graph_dt64 (lib target)", "features": "default", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "rustc": "nightly-2026-09-17 (charon)", "target": "x86_64-unknown-linux-gnu", "tool": "lance-graph recon.py packet over a Charon/ruff_charon store"}, "reachability": {"confirmed": ["lance_graph_dt64::lane::{LaneBinding}::borrow_all", "lance_graph_dt64::lane::{LaneBinding}::lane"], "possible": [], "unknown": [{"observed_crates": ["lance_graph_contract", "lance_graph_dt64", "lance_graph_quack", "lance_graph_r2il"], "what": "callers in crates outside the store", "why": "symbol is PUBLIC; only these crates' library targets were compiled"}, {"what": "test targets, examples, cfg(test) modules", "why": "store holds library targets only"}]}, "refusal": "impact is a fact, not a defect; nothing to change", "severity": null, "status": "open", "status_detail": null, "suggestions": [], "symbol": "lance_graph_dt64::lane::{LaneBinding}::check", "type": "finding"} +{"codegenInstructions": null, "comment": "48 test call sites match `check` by name. None is resolved to this symbol, and none ran.", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {}, "duplicate_of": null, "evidence": [{"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:271"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/cognitive-polyfill-probe/tests/p0.rs:275"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:234"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:238"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:249"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:481"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:522"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:663"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:677"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:678"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dir-rmap-probe/tests/equivalence.rs:680"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:136"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:263"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/dr-math-binding-probe/tests/binding.rs:234"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:58"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:60"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:72"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:82"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:86"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:89"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:90"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:93"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:776"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:777"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:808"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:814"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:824"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:827"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/dr.rs:828"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:227"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:277"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:314"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:369"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:373"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:403"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:407"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: inside a macro region)", "tool": "source search", "witness": "crates/lance-graph-dt64/tests/lane_socket.rs:424"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/thought-git-probe/tests/receipt.rs:715"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/thought-git-probe/tests/receipt.rs:715"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/xlog-relcomp-probe/tests/dto_binding.rs:233"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:320"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:341"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:418"}, {"fresh": true, "grade": "SOURCE_STRUCTURE", "qualifier": "POSSIBLE", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "statement": "name match, receiver unresolved (UNKNOWN: file not indexed)", "tool": "source search", "witness": "crates/lance-graph-report/src/lane_source/tests.rs:623"}], "evidence_class": "SOURCE_STRUCTURE", "falsifier": {"command": null, "description": "Extract the test targets and re-run impact: name-matched sites either become confirmed callers or drop out.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "crates/lance-graph-dt64/src/lane.rs", "id": "F2", "kind": "coverage", "lines": [307, 349], "provenance": {"crate_instance": "lance_graph_dt64 (lib target)", "features": "default", "revision": "90fc5a76c12714d3bd00bcc5be96125aef74d89f", "rustc": "nightly-2026-09-17 (charon)", "target": "x86_64-unknown-linux-gnu", "tool": "lance-graph recon.py packet over a Charon/ruff_charon store"}, "reachability": {"confirmed": [], "possible": [], "unknown": [{"what": "test callers", "why": "library targets only; macro regions and cfg(test) modules not indexed"}]}, "refusal": "coverage gap; the next step is extraction, not a code change", "severity": null, "status": "open", "status_detail": null, "suggestions": [], "symbol": "lance_graph_dt64::lane::{LaneBinding}::check", "type": "finding"} +{"clean": false, "findings": 2, "reasons": ["library targets only", "consumer crates not in store", "no test executed"], "status": "PARTIAL", "type": "complete", "verdict": "INCOMPLETE REVIEW: run PARTIAL; not a defect verdict (2 open finding(s))"} diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review-input.json b/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review-input.json new file mode 100644 index 000000000..ac50419e0 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review-input.json @@ -0,0 +1,301 @@ +{ + "findings": [ + { + "claim": "In the consumer's shipped code, the per-row power-of-two quotient specialisation in #422 has no call site to reach. #422's Rust changes are confined to the `u64x64` example target, which no crate can depend on. The G1 and G6 paths in the Charon store reach no per-row stock quotient: their mask predicates compare a stock lane against a scalar threshold (G6: `d * q`, built at method registration), and mask-risc evaluates `GeI32` as a plain compare. Not covered: mask-risc predicates other than `GeI32`, and G1's unshipped per-store min/argmin step (EXO-227 P1b).", + "coverage": { + "consumer_residuals": 0, + "consumer_store": "foundry_parity_lab library target", + "ndarray_library_rust_changed": 0, + "ndarray_other_rust_outside_examples": 0 + }, + "evidence": [ + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/ndarray", + "revision": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", + "statement": "#422 changes 6 files: 3 Rust, 3 in example target(s) ['u64x64']; library Rust files changed: 0; other Rust files changed: 0", + "tool": "git", + "witness": "97654984da60..f279fe75f4a5" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "G1 capacity (arm_b): `arm_b::{ItemQuery<'s>}::max_quantities` reaches 35 functions (3 only via dispatch or a closure body); divisions reached: [\"arm_b::{ItemQuery<'s>}::cook_ops\"]; other crates reached: ['lance_graph_mask_risc']", + "tool": "charon c69e231 + ruff_charon", + "witness": "store" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "G1 capacity (arm_b): `arm_b::{ItemQuery<'s>}::network_capacity` reaches 27 functions (2 only via dispatch or a closure body); divisions reached: [\"arm_b::{ItemQuery<'s>}::cook_ops\"]; other crates reached: ['lance_graph_mask_risc']", + "tool": "charon c69e231 + ruff_charon", + "witness": "store" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "G6 CanCook (method): `method::execute_can_cook` reaches 57 functions (7 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_contract', 'lance_graph_dt64', 'lance_graph_mask_risc', 'lance_graph_relalg']", + "tool": "charon c69e231 + ruff_charon", + "witness": "store" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "G6 CanCook (method): `method::{PreparedMethod<'s>}::prepare` reaches 49 functions (7 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_contract', 'lance_graph_dt64', 'lance_graph_mask_risc', 'lance_graph_relalg']", + "tool": "charon c69e231 + ruff_charon", + "witness": "store" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "G6 CanCook (method): `method::{PreparedMethod<'s>}::run` reaches 12 functions (0 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_mask_risc']", + "tool": "charon c69e231 + ruff_charon", + "witness": "store" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "integer division on an executable path, in `arm_b::{ItemQuery<'s>}::cook_ops`: `(q + r.per_staff - 1) / r.per_staff`", + "tool": "charon c69e231 + ruff_charon", + "witness": "crates/foundry-parity-lab/src/arm_b.rs:245" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "mask-predicate threshold in `arm_b::{ItemQuery<'s>}::cook_ops`: `t: d * q` (names no lane)", + "tool": "source span read", + "witness": "crates/foundry-parity-lab/src/arm_b.rs:235" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "mask-predicate threshold in `arm_b::{ItemQuery<'s>}::cook_ops`: `t: (q + r.per_staff - 1) / r.per_staff` (names no lane)", + "tool": "source span read", + "witness": "crates/foundry-parity-lab/src/arm_b.rs:245" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "integer division at G6 method registration (`method::can_cook_guard`, reached from ['method::methods'], not from the G6 execution entry points): `(q + r.per_staff - 1) / r.per_staff`", + "tool": "charon c69e231 + ruff_charon", + "witness": "crates/foundry-parity-lab/src/method.rs:58" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "mask-predicate threshold in `method::can_cook_guard`: `d * q` (names no lane)", + "tool": "source span read", + "witness": "crates/foundry-parity-lab/src/method.rs:55" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "mask-predicate threshold in `method::can_cook_guard`: `staff` (names no lane)", + "tool": "source span read", + "witness": "crates/foundry-parity-lab/src/method.rs:59" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": "POSSIBLE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "reference arm `oracle::{Oracle}::network_capacity` reaches `oracle::{Oracle}::can_cook` through a closure body linked to its parent by Charon's name only: `fx::stock(s, k, self.restocked) / d`", + "tool": "charon c69e231 + ruff_charon", + "witness": "crates/foundry-parity-lab/src/oracle.rs:62" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": "POSSIBLE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "reference arm `arm_a::{Objects}::network_capacity` reaches `arm_a::{Objects}::can_cook` through a closure body linked to its parent by Charon's name only: `v / d`", + "tool": "charon c69e231 + ruff_charon", + "witness": "crates/foundry-parity-lab/src/arm_a.rs:75" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "mask-risc `Pred::GeI32 { lane: u16, t: i32 }` is `lane[i] >= t` with `t` a scalar `i32`", + "tool": "source span read", + "witness": "crates/lance-graph-mask-risc/src/ir.rs:133" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "the executor passes `t` unchanged to `ndarray::simd::ge_i32_to_mask`", + "tool": "source span read", + "witness": "crates/lance-graph-mask-risc/src/exec.rs:588" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/ndarray", + "revision": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", + "statement": "`ge_i32_to_mask` is the complement of `lt_i32_to_mask`, a compare of each lane value against the splatted threshold; no division", + "tool": "git", + "witness": "src/simd_masking_ops.rs:3449" + } + ], + "falsifier": { + "description": "Run Charon on lance-graph-mask-risc and re-run the reach from the G1/G6 entry points into it: any `DivisionByZero` assertion on a path that takes a stock lane as an operand refutes the claim. Smallest next verification: the predicate kinds other than `GeI32` that the consumer builds.", + "status": "NOT_RUN" + }, + "id": "Q1", + "kind": "admission", + "location": { + "file": "examples/u64x64/route_c.rs", + "symbol": "u64x64 route C / A power-of-two quotient arms" + }, + "reachability": { + "confirmed": [ + "G1 capacity (arm_b): arm_b::{ItemQuery<'s>}::max_quantities", + "G1 capacity (arm_b): arm_b::{ItemQuery<'s>}::network_capacity", + "G6 CanCook (method): method::execute_can_cook", + "G6 CanCook (method): method::{PreparedMethod<'s>}::prepare", + "G6 CanCook (method): method::{PreparedMethod<'s>}::run" + ], + "possible": [ + "oracle::{Oracle}::network_capacity \u2192 oracle::{Oracle}::can_cook", + "arm_a::{Objects}::network_capacity \u2192 arm_a::{Objects}::can_cook" + ], + "unknown": [ + { + "what": "lance-graph-mask-risc beyond `GeI32`", + "why": "not in the Charon store; only the `GeI32` evaluation path was read, as source" + }, + { + "what": "G1 per-store min/argmin (limiting resource)", + "why": "not shipped: open in EXO-227 (P1b); this review covers shipped code only" + }, + { + "what": "production recipe divisor distribution", + "why": "no production source; the only population is the synthetic fixture" + }, + { + "what": "96 closure bodies in the crate", + "why": "linked to their parent by Charon's naming only (POSSIBLE), not by a call row" + } + ] + }, + "suggestion": { + "refusal": "an admission finding, not a defect: no code change follows from the evidence" + } + }, + { + "claim": "The executable path does evaluate integer division: `(q + per_staff - 1) / per_staff`. It is the threshold operand of a mask predicate and names no lane, so it is computed once when the predicate is built, not per row. G6 has the same ceiling division at method registration. In shipped code, a per-row quotient specialisation has nothing to apply to.", + "evidence": [ + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "division assertion (zero and overflow) at this site", + "tool": "charon c69e231 + ruff_charon", + "witness": "crates/foundry-parity-lab/src/arm_b.rs:245" + }, + { + "grade": "COMPILER_DERIVED", + "qualifier": null, + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "division assertion at G6 method registration", + "tool": "charon c69e231 + ruff_charon", + "witness": "crates/foundry-parity-lab/src/method.rs:58" + }, + { + "grade": "SOURCE_STRUCTURE", + "repo": "AdaWorldAPI/lance-graph", + "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", + "statement": "`t: (q + r.per_staff - 1) / r.per_staff` (names no lane)", + "tool": "source span read", + "witness": "crates/foundry-parity-lab/src/arm_b.rs:245" + } + ], + "falsifier": { + "description": "Read the Pred::GeI32 threshold sites: the division's operands are query parameters, not lanes.", + "status": "NOT_RUN" + }, + "id": "Q2", + "kind": "research", + "location": { + "file": "crates/foundry-parity-lab/src/arm_b.rs", + "symbol": "arm_b::{ItemQuery}::cook_ops" + }, + "reachability": { + "confirmed": [ + "arm_b::{ItemQuery<'s>}::cook_ops", + "method::can_cook_guard" + ] + }, + "suggestion": { + "base_sha": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", + "file": ".claude/plans/u64x64-llvm-probe-v1.md (ndarray)", + "line": 921, + "text": "Narrow 'No quotient is evaluated on the executable path' to 'no per-row stock quotient is evaluated': a scalar ceiling division builds the staff threshold." + } + }, + { + "claim": "The PR's benchmark results (power-of-two shift no-regret; best route only on AVX-512 hot) were not re-run here.", + "evidence": [ + { + "grade": "ASSERTED", + "repo": "AdaWorldAPI/ndarray", + "revision": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", + "statement": "benchmark results and disable runs, author-reported (plan \u00a717)", + "witness": ".claude/plans/u64x64-llvm-probe-v1.md:949" + } + ], + "falsifier": { + "description": "Per tier T in v2/v3/v4, build with `env -u RUSTFLAGS cargo --config .cargo/config-$T.toml rustc --release --example u64x64` (plan \u00a74) and run `u64x64 bench ` for the \u00a716 scenarios; compare with \u00a717. The F7/F8 disable arms (test `d > 0` instead of `is_power_of_two`) are parity checks: they must turn `u64x64 check` red, and say nothing about speed.", + "status": "NOT_RUN" + }, + "id": "Q3", + "kind": "research", + "location": { + "file": "examples/u64x64/main.rs" + }, + "suggestion": { + "refusal": "a performance claim outside this review's evidence; no defect follows" + } + } + ], + "review": { + "base_sha": "97654984da601c4705bc2350aa586d39d7c57fd2", + "head_sha": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", + "heads": { + "AdaWorldAPI/lance-graph": "c7151a1ecb03d4523ece505e42de1e77ed23111e" + }, + "pr": 422, + "repo": "AdaWorldAPI/ndarray", + "reviewer": { + "tool": "crai_report.py + build_q8_evidence.py" + }, + "scope": "PR #422 commits; consumer: lance-graph foundry-parity-lab (lib), extracted at c7151a1ecb03d4523ece505e42de1e77ed23111e; foundry-parity-lab and mask-risc unchanged at 317c4ffc04cb557d1142fd1331a0ccaedcd286de" + }, + "run": { + "reasons": [ + "mask-risc not in the Charon store (GeI32 read as source only)", + "no test or benchmark executed" + ], + "status": "PARTIAL" + } +} diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review.md b/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review.md new file mode 100644 index 000000000..d34702b34 --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review.md @@ -0,0 +1,123 @@ +# Review: AdaWorldAPI/ndarray #422 + +- **Head:** `f279fe75f4a5c4aff75f473a38508cf9e9d20aea` (base `97654984da601c4705bc2350aa586d39d7c57fd2`) +- **Evidence head, AdaWorldAPI/lance-graph:** `c7151a1ecb03d4523ece505e42de1e77ed23111e` +- **Scope:** PR #422 commits; consumer: lance-graph foundry-parity-lab (lib), extracted at c7151a1ecb03d4523ece505e42de1e77ed23111e; foundry-parity-lab and mask-risc unchanged at 317c4ffc04cb557d1142fd1331a0ccaedcd286de +- **Reviewer:** {"tool": "crai_report.py + build_q8_evidence.py"} +- **Run:** `PARTIAL` (mask-risc not in the Charon store (GeI32 read as source only); no test or benchmark executed) +- **Verdict:** INCOMPLETE REVIEW: run PARTIAL; not a defect verdict (3 open finding(s)) +- **Semantics:** crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35). Severity, evidence and confidence are separate axes. + +## Q1 · admission · open + +**Location:** `examples/u64x64/route_c.rs` · `u64x64 route C / A power-of-two quotient arms` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | COMPILER_DERIVED | UNKNOWN | + +**Claim** + +> In the consumer's shipped code, the per-row power-of-two quotient specialisation in #422 has no call site to reach. #422's Rust changes are confined to the 'u64x64' example target, which no crate can depend on. The G1 and G6 paths in the Charon store reach no per-row stock quotient: their mask predicates compare a stock lane against a scalar threshold (G6: 'd * q', built at method registration), and mask-risc evaluates 'GeI32' as a plain compare. Not covered: mask-risc predicates other than 'GeI32', and G1's unshipped per-store min/argmin step (EXO-227 P1b). + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| SOURCE_STRUCTURE | | #422 changes 6 files: 3 Rust, 3 in example target(s) ['u64x64']; library Rust files changed: 0; other Rust files changed: 0 | `ndarray:97654984da60..f279fe75f4a5` | `f279fe75f4a5` | +| COMPILER_DERIVED | | G1 capacity (arm_b): 'arm_b::{ItemQuery<'s>}::max_quantities' reaches 35 functions (3 only via dispatch or a closure body); divisions reached: ["arm_b::{ItemQuery<'s>}::cook_ops"]; other crates reached: ['lance_graph_mask_risc'] | `lance-graph:store` | `c7151a1ecb03` | +| COMPILER_DERIVED | | G1 capacity (arm_b): 'arm_b::{ItemQuery<'s>}::network_capacity' reaches 27 functions (2 only via dispatch or a closure body); divisions reached: ["arm_b::{ItemQuery<'s>}::cook_ops"]; other crates reached: ['lance_graph_mask_risc'] | `lance-graph:store` | `c7151a1ecb03` | +| COMPILER_DERIVED | | G6 CanCook (method): 'method::execute_can_cook' reaches 57 functions (7 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_contract', 'lance_graph_dt64', 'lance_graph_mask_risc', 'lance_graph_relalg'] | `lance-graph:store` | `c7151a1ecb03` | +| COMPILER_DERIVED | | G6 CanCook (method): 'method::{PreparedMethod<'s>}::prepare' reaches 49 functions (7 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_contract', 'lance_graph_dt64', 'lance_graph_mask_risc', 'lance_graph_relalg'] | `lance-graph:store` | `c7151a1ecb03` | +| COMPILER_DERIVED | | G6 CanCook (method): 'method::{PreparedMethod<'s>}::run' reaches 12 functions (0 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_mask_risc'] | `lance-graph:store` | `c7151a1ecb03` | +| COMPILER_DERIVED | | integer division on an executable path, in 'arm_b::{ItemQuery<'s>}::cook_ops': '(q + r.per_staff - 1) / r.per_staff' | `lance-graph:crates/foundry-parity-lab/src/arm_b.rs:245` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | mask-predicate threshold in 'arm_b::{ItemQuery<'s>}::cook_ops': 't: d * q' (names no lane) | `lance-graph:crates/foundry-parity-lab/src/arm_b.rs:235` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | mask-predicate threshold in 'arm_b::{ItemQuery<'s>}::cook_ops': 't: (q + r.per_staff - 1) / r.per_staff' (names no lane) | `lance-graph:crates/foundry-parity-lab/src/arm_b.rs:245` | `c7151a1ecb03` | +| COMPILER_DERIVED | | integer division at G6 method registration ('method::can_cook_guard', reached from ['method::methods'], not from the G6 execution entry points): '(q + r.per_staff - 1) / r.per_staff' | `lance-graph:crates/foundry-parity-lab/src/method.rs:58` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | mask-predicate threshold in 'method::can_cook_guard': 'd * q' (names no lane) | `lance-graph:crates/foundry-parity-lab/src/method.rs:55` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | mask-predicate threshold in 'method::can_cook_guard': 'staff' (names no lane) | `lance-graph:crates/foundry-parity-lab/src/method.rs:59` | `c7151a1ecb03` | +| COMPILER_DERIVED | POSSIBLE | reference arm 'oracle::{Oracle}::network_capacity' reaches 'oracle::{Oracle}::can_cook' through a closure body linked to its parent by Charon's name only: 'fx::stock(s, k, self.restocked) / d' | `lance-graph:crates/foundry-parity-lab/src/oracle.rs:62` | `c7151a1ecb03` | +| COMPILER_DERIVED | POSSIBLE | reference arm 'arm_a::{Objects}::network_capacity' reaches 'arm_a::{Objects}::can_cook' through a closure body linked to its parent by Charon's name only: 'v / d' | `lance-graph:crates/foundry-parity-lab/src/arm_a.rs:75` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | mask-risc 'Pred::GeI32 { lane: u16, t: i32 }' is 'lane[i] >= t' with 't' a scalar 'i32' | `lance-graph:crates/lance-graph-mask-risc/src/ir.rs:133` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | the executor passes 't' unchanged to 'ndarray::simd::ge_i32_to_mask' | `lance-graph:crates/lance-graph-mask-risc/src/exec.rs:588` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | 'ge_i32_to_mask' is the complement of 'lt_i32_to_mask', a compare of each lane value against the splatted threshold; no division | `ndarray:src/simd_masking_ops.rs:3449` | `f279fe75f4a5` | + +**Reachability** + +- confirmed: `G1 capacity (arm_b): arm_b::{ItemQuery<'s>}::max_quantities`, `G1 capacity (arm_b): arm_b::{ItemQuery<'s>}::network_capacity`, `G6 CanCook (method): method::execute_can_cook`, `G6 CanCook (method): method::{PreparedMethod<'s>}::prepare`, `G6 CanCook (method): method::{PreparedMethod<'s>}::run` +- possible: `arm_a::{Objects}::network_capacity → arm_a::{Objects}::can_cook`, `oracle::{Oracle}::network_capacity → oracle::{Oracle}::can_cook` +- unknown: 96 closure bodies in the crate (linked to their parent by Charon's naming only (POSSIBLE), not by a call row); G1 per-store min/argmin (limiting resource) (not shipped: open in EXO-227 (P1b); this review covers shipped code only); lance-graph-mask-risc beyond `GeI32` (not in the Charon store; only the `GeI32` evaluation path was read, as source); production recipe divisor distribution (no production source; the only population is the synthetic fixture) + +**Coverage** + +- consumer_residuals: 0 +- consumer_store: foundry_parity_lab library target +- ndarray_library_rust_changed: 0 +- ndarray_other_rust_outside_examples: 0 + +**Falsifier** + +- Run Charon on lance-graph-mask-risc and re-run the reach from the G1/G6 entry points into it: any `DivisionByZero` assertion on a path that takes a stock lane as an operand refutes the claim. Smallest next verification: the predicate kinds other than `GeI32` that the consumer builds. +- status: `NOT_RUN` + +**No suggestion:** an admission finding, not a defect: no code change follows from the evidence + +## Q2 · research · open + +**Location:** `crates/foundry-parity-lab/src/arm_b.rs` · `arm_b::{ItemQuery}::cook_ops` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | COMPILER_DERIVED | UNKNOWN | + +**Claim** + +> The executable path does evaluate integer division: '(q + per_staff - 1) / per_staff'. It is the threshold operand of a mask predicate and names no lane, so it is computed once when the predicate is built, not per row. G6 has the same ceiling division at method registration. In shipped code, a per-row quotient specialisation has nothing to apply to. + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| COMPILER_DERIVED | | division assertion (zero and overflow) at this site | `lance-graph:crates/foundry-parity-lab/src/arm_b.rs:245` | `c7151a1ecb03` | +| COMPILER_DERIVED | | division assertion at G6 method registration | `lance-graph:crates/foundry-parity-lab/src/method.rs:58` | `c7151a1ecb03` | +| SOURCE_STRUCTURE | | 't: (q + r.per_staff - 1) / r.per_staff' (names no lane) | `lance-graph:crates/foundry-parity-lab/src/arm_b.rs:245` | `c7151a1ecb03` | + +**Reachability** + +- confirmed: `arm_b::{ItemQuery<'s>}::cook_ops`, `method::can_cook_guard` +- possible: none observed +- unknown: none recorded + +**Falsifier** + +- Read the Pred::GeI32 threshold sites: the division's operands are query parameters, not lanes. +- status: `NOT_RUN` + +**Suggestion** (inert proposal; applying it needs the owner's approval and revalidation against `f279fe75f4a5`) + +> Narrow 'No quotient is evaluated on the executable path' to 'no per-row stock quotient is evaluated': a scalar ceiling division builds the staff threshold. + +## Q3 · research · open + +**Location:** `examples/u64x64/main.rs` + +| severity | evidence class | confidence | +|---|---|---| +| not assessed | ASSERTED | UNKNOWN | + +**Claim** + +> The PR's benchmark results (power-of-two shift no-regret; best route only on AVX-512 hot) were not re-run here. + +**Evidence** + +| grade | qualifier | statement | witness | revision | +|---|---|---|---|---| +| ASSERTED | | benchmark results and disable runs, author-reported (plan §17) | `ndarray:.claude/plans/u64x64-llvm-probe-v1.md:949` | `f279fe75f4a5` | + +**Falsifier** + +- Per tier T in v2/v3/v4, build with `env -u RUSTFLAGS cargo --config .cargo/config-$T.toml rustc --release --example u64x64` (plan §4) and run `u64x64 bench ` for the §16 scenarios; compare with §17. The F7/F8 disable arms (test `d > 0` instead of `is_power_of_two`) are parity checks: they must turn `u64x64 check` red, and say nothing about speed. +- status: `NOT_RUN` + +**No suggestion:** a performance claim outside this review's evidence; no defect follows diff --git a/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review.ndjson b/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review.ndjson new file mode 100644 index 000000000..eabe582df --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/examples/ndarray-422/review.ndjson @@ -0,0 +1,5 @@ +{"base_sha": "97654984da601c4705bc2350aa586d39d7c57fd2", "head_sha": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", "heads": {"AdaWorldAPI/lance-graph": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "AdaWorldAPI/ndarray": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea"}, "pr": 422, "repo": "AdaWorldAPI/ndarray", "reviewer": {"tool": "crai_report.py + build_q8_evidence.py"}, "scope": "PR #422 commits; consumer: lance-graph foundry-parity-lab (lib), extracted at c7151a1ecb03d4523ece505e42de1e77ed23111e; foundry-parity-lab and mask-risc unchanged at 317c4ffc04cb557d1142fd1331a0ccaedcd286de", "semantics": "crai-rs CR-H0-REVIEW-SEMANTICS (c43ab35)", "type": "review_start"} +{"codegenInstructions": null, "comment": "In the consumer's shipped code, the per-row power-of-two quotient specialisation in #422 has no call site to reach. #422's Rust changes are confined to the `u64x64` example target, which no crate can depend on. The G1 and G6 paths in the Charon store reach no per-row stock quotient: their mask predicates compare a stock lane against a scalar threshold (G6: `d * q`, built at method registration), and mask-risc evaluates `GeI32` as a plain compare. Not covered: mask-risc predicates other than `GeI32`, and G1's unshipped per-store min/argmin step (EXO-227 P1b).", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {"consumer_residuals": 0, "consumer_store": "foundry_parity_lab library target", "ndarray_library_rust_changed": 0, "ndarray_other_rust_outside_examples": 0}, "duplicate_of": null, "evidence": [{"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/ndarray", "revision": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", "statement": "#422 changes 6 files: 3 Rust, 3 in example target(s) ['u64x64']; library Rust files changed: 0; other Rust files changed: 0", "tool": "git", "witness": "97654984da60..f279fe75f4a5"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "G1 capacity (arm_b): `arm_b::{ItemQuery<'s>}::max_quantities` reaches 35 functions (3 only via dispatch or a closure body); divisions reached: [\"arm_b::{ItemQuery<'s>}::cook_ops\"]; other crates reached: ['lance_graph_mask_risc']", "tool": "charon c69e231 + ruff_charon", "witness": "store"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "G1 capacity (arm_b): `arm_b::{ItemQuery<'s>}::network_capacity` reaches 27 functions (2 only via dispatch or a closure body); divisions reached: [\"arm_b::{ItemQuery<'s>}::cook_ops\"]; other crates reached: ['lance_graph_mask_risc']", "tool": "charon c69e231 + ruff_charon", "witness": "store"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "G6 CanCook (method): `method::execute_can_cook` reaches 57 functions (7 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_contract', 'lance_graph_dt64', 'lance_graph_mask_risc', 'lance_graph_relalg']", "tool": "charon c69e231 + ruff_charon", "witness": "store"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "G6 CanCook (method): `method::{PreparedMethod<'s>}::prepare` reaches 49 functions (7 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_contract', 'lance_graph_dt64', 'lance_graph_mask_risc', 'lance_graph_relalg']", "tool": "charon c69e231 + ruff_charon", "witness": "store"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "G6 CanCook (method): `method::{PreparedMethod<'s>}::run` reaches 12 functions (0 only via dispatch or a closure body); divisions reached: none; other crates reached: ['lance_graph_mask_risc']", "tool": "charon c69e231 + ruff_charon", "witness": "store"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "integer division on an executable path, in `arm_b::{ItemQuery<'s>}::cook_ops`: `(q + r.per_staff - 1) / r.per_staff`", "tool": "charon c69e231 + ruff_charon", "witness": "crates/foundry-parity-lab/src/arm_b.rs:245"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "mask-predicate threshold in `arm_b::{ItemQuery<'s>}::cook_ops`: `t: d * q` (names no lane)", "tool": "source span read", "witness": "crates/foundry-parity-lab/src/arm_b.rs:235"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "mask-predicate threshold in `arm_b::{ItemQuery<'s>}::cook_ops`: `t: (q + r.per_staff - 1) / r.per_staff` (names no lane)", "tool": "source span read", "witness": "crates/foundry-parity-lab/src/arm_b.rs:245"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "integer division at G6 method registration (`method::can_cook_guard`, reached from ['method::methods'], not from the G6 execution entry points): `(q + r.per_staff - 1) / r.per_staff`", "tool": "charon c69e231 + ruff_charon", "witness": "crates/foundry-parity-lab/src/method.rs:58"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "mask-predicate threshold in `method::can_cook_guard`: `d * q` (names no lane)", "tool": "source span read", "witness": "crates/foundry-parity-lab/src/method.rs:55"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "mask-predicate threshold in `method::can_cook_guard`: `staff` (names no lane)", "tool": "source span read", "witness": "crates/foundry-parity-lab/src/method.rs:59"}, {"grade": "COMPILER_DERIVED", "qualifier": "POSSIBLE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "reference arm `oracle::{Oracle}::network_capacity` reaches `oracle::{Oracle}::can_cook` through a closure body linked to its parent by Charon's name only: `fx::stock(s, k, self.restocked) / d`", "tool": "charon c69e231 + ruff_charon", "witness": "crates/foundry-parity-lab/src/oracle.rs:62"}, {"grade": "COMPILER_DERIVED", "qualifier": "POSSIBLE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "reference arm `arm_a::{Objects}::network_capacity` reaches `arm_a::{Objects}::can_cook` through a closure body linked to its parent by Charon's name only: `v / d`", "tool": "charon c69e231 + ruff_charon", "witness": "crates/foundry-parity-lab/src/arm_a.rs:75"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "mask-risc `Pred::GeI32 { lane: u16, t: i32 }` is `lane[i] >= t` with `t` a scalar `i32`", "tool": "source span read", "witness": "crates/lance-graph-mask-risc/src/ir.rs:133"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "the executor passes `t` unchanged to `ndarray::simd::ge_i32_to_mask`", "tool": "source span read", "witness": "crates/lance-graph-mask-risc/src/exec.rs:588"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/ndarray", "revision": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", "statement": "`ge_i32_to_mask` is the complement of `lt_i32_to_mask`, a compare of each lane value against the splatted threshold; no division", "tool": "git", "witness": "src/simd_masking_ops.rs:3449"}], "evidence_class": "COMPILER_DERIVED", "falsifier": {"command": null, "description": "Run Charon on lance-graph-mask-risc and re-run the reach from the G1/G6 entry points into it: any `DivisionByZero` assertion on a path that takes a stock lane as an operand refutes the claim. Smallest next verification: the predicate kinds other than `GeI32` that the consumer builds.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "examples/u64x64/route_c.rs", "id": "Q1", "kind": "admission", "lines": null, "provenance": null, "reachability": {"confirmed": ["G1 capacity (arm_b): arm_b::{ItemQuery<'s>}::max_quantities", "G1 capacity (arm_b): arm_b::{ItemQuery<'s>}::network_capacity", "G6 CanCook (method): method::execute_can_cook", "G6 CanCook (method): method::{PreparedMethod<'s>}::prepare", "G6 CanCook (method): method::{PreparedMethod<'s>}::run"], "possible": ["arm_a::{Objects}::network_capacity → arm_a::{Objects}::can_cook", "oracle::{Oracle}::network_capacity → oracle::{Oracle}::can_cook"], "unknown": [{"what": "96 closure bodies in the crate", "why": "linked to their parent by Charon's naming only (POSSIBLE), not by a call row"}, {"what": "G1 per-store min/argmin (limiting resource)", "why": "not shipped: open in EXO-227 (P1b); this review covers shipped code only"}, {"what": "lance-graph-mask-risc beyond `GeI32`", "why": "not in the Charon store; only the `GeI32` evaluation path was read, as source"}, {"what": "production recipe divisor distribution", "why": "no production source; the only population is the synthetic fixture"}]}, "refusal": "an admission finding, not a defect: no code change follows from the evidence", "severity": null, "status": "open", "status_detail": null, "suggestions": [], "symbol": "u64x64 route C / A power-of-two quotient arms", "type": "finding"} +{"codegenInstructions": null, "comment": "The executable path does evaluate integer division: `(q + per_staff - 1) / per_staff`. It is the threshold operand of a mask predicate and names no lane, so it is computed once when the predicate is built, not per row. G6 has the same ceiling division at method registration. In shipped code, a per-row quotient specialisation has nothing to apply to.", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {}, "duplicate_of": null, "evidence": [{"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "division assertion (zero and overflow) at this site", "tool": "charon c69e231 + ruff_charon", "witness": "crates/foundry-parity-lab/src/arm_b.rs:245"}, {"grade": "COMPILER_DERIVED", "qualifier": null, "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "division assertion at G6 method registration", "tool": "charon c69e231 + ruff_charon", "witness": "crates/foundry-parity-lab/src/method.rs:58"}, {"grade": "SOURCE_STRUCTURE", "repo": "AdaWorldAPI/lance-graph", "revision": "c7151a1ecb03d4523ece505e42de1e77ed23111e", "statement": "`t: (q + r.per_staff - 1) / r.per_staff` (names no lane)", "tool": "source span read", "witness": "crates/foundry-parity-lab/src/arm_b.rs:245"}], "evidence_class": "COMPILER_DERIVED", "falsifier": {"command": null, "description": "Read the Pred::GeI32 threshold sites: the division's operands are query parameters, not lanes.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "crates/foundry-parity-lab/src/arm_b.rs", "id": "Q2", "kind": "research", "lines": null, "provenance": null, "reachability": {"confirmed": ["arm_b::{ItemQuery<'s>}::cook_ops", "method::can_cook_guard"], "possible": [], "unknown": []}, "refusal": null, "severity": null, "status": "open", "status_detail": null, "suggestions": [{"base_sha": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", "file": ".claude/plans/u64x64-llvm-probe-v1.md (ndarray)", "line": 921, "text": "Narrow 'No quotient is evaluated on the executable path' to 'no per-row stock quotient is evaluated': a scalar ceiling division builds the staff threshold."}], "symbol": "arm_b::{ItemQuery}::cook_ops", "type": "finding"} +{"codegenInstructions": null, "comment": "The PR's benchmark results (power-of-two shift no-regret; best route only on AVX-512 hot) were not re-run here.", "confidence": {"source": null, "value": "UNKNOWN"}, "coverage": {}, "duplicate_of": null, "evidence": [{"grade": "ASSERTED", "repo": "AdaWorldAPI/ndarray", "revision": "f279fe75f4a5c4aff75f473a38508cf9e9d20aea", "statement": "benchmark results and disable runs, author-reported (plan §17)", "witness": ".claude/plans/u64x64-llvm-probe-v1.md:949"}], "evidence_class": "ASSERTED", "falsifier": {"command": null, "description": "Per tier T in v2/v3/v4, build with `env -u RUSTFLAGS cargo --config .cargo/config-$T.toml rustc --release --example u64x64` (plan §4) and run `u64x64 bench ` for the §16 scenarios; compare with §17. The F7/F8 disable arms (test `d > 0` instead of `is_power_of_two`) are parity checks: they must turn `u64x64 check` red, and say nothing about speed.", "disable_run": null, "status": "NOT_RUN"}, "fileName": "examples/u64x64/main.rs", "id": "Q3", "kind": "research", "lines": null, "provenance": null, "reachability": {"confirmed": [], "possible": [], "unknown": []}, "refusal": "a performance claim outside this review's evidence; no defect follows", "severity": null, "status": "open", "status_detail": null, "suggestions": [], "symbol": null, "type": "finding"} +{"clean": false, "findings": 3, "reasons": ["mask-risc not in the Charon store (GeI32 read as source only)", "no test or benchmark executed"], "status": "PARTIAL", "type": "complete", "verdict": "INCOMPLETE REVIEW: run PARTIAL; not a defect verdict (3 open finding(s))"} diff --git a/.claude/probes/2026-11-11-crai-report-1/packet-LaneBinding-check.json b/.claude/probes/2026-11-11-crai-report-1/packet-LaneBinding-check.json new file mode 100644 index 000000000..50b4a66fd --- /dev/null +++ b/.claude/probes/2026-11-11-crai-report-1/packet-LaneBinding-check.json @@ -0,0 +1,553 @@ +{ + "packet": "ReviewEvidencePacket (prototype, read-only; not a vendor API)", + "identity": { + "repo_id": "AdaWorldAPI/lance-graph", + "commit_sha": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "cargo_lock_sha": "NOT_TRACKED (repository tracks no Cargo.lock)", + "crate_instance": "lance_graph_dt64 (lib target)", + "features": "default", + "target_triple": "x86_64-unknown-linux-gnu", + "rustc_version": "nightly-2026-09-17 (charon)", + "file_blob_sha": "a0aa6e6658872d07c93990095d2fab2beff1487d", + "source_span": { + "file": "crates/lance-graph-dt64/src/lane.rs", + "bytes": [ + 10592, + 12497 + ], + "lines": [ + 307, + 349 + ] + } + }, + "changed_source": { + "subject": "lance_graph_dt64::lane::{LaneBinding}::check", + "base": "0c9ae23ac6a20ca6cd0c50da7e7a69e0f5df34eb", + "diff": "diff --git a/crates/lance-graph-dt64/src/lane.rs b/crates/lance-graph-dt64/src/lane.rs\nindex a0aa6e665..d21a5b602 100644\n--- a/crates/lance-graph-dt64/src/lane.rs\n+++ b/crates/lance-graph-dt64/src/lane.rs\n@@ -312,7 +312,7 @@ impl LaneBinding {\n source: &S,\n ) -> Result<(), LaneRefusal> {\n source_owns(frames, source)?;\n- frames.check(&self.frame).map_err(LaneRefusal::Frame)?;\n+ frames.check(&self.frame).map_err(LaneRefusal::Frame)?; // probe edit\n current_route(store, self.route.position, self.class)?;\n // Revision and count only: the ordered predicate witness was checked\n // when the binding was made (bind_lanes resolves through the\n", + "stale": false, + "freshness": "FRESH", + "dependency_evidence_stale": false + }, + "affected_symbols": { + "confirmed": [ + "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "lance_graph_dt64::lane::{LaneBinding}::lane" + ], + "possible": [], + "stale": [], + "unknown": [ + { + "what": "callers in crates outside the store", + "observed_crates": [ + "lance_graph_contract", + "lance_graph_dt64", + "lance_graph_quack", + "lance_graph_r2il" + ], + "why": "symbol is PUBLIC; only these crates' library targets were compiled" + }, + { + "what": "test targets, examples, cfg(test) modules", + "why": "store holds library targets only" + } + ] + }, + "witnessed_edges": [ + { + "caller": "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "callee": "lance_graph_dt64::lane::{LaneBinding}::check", + "sites": [ + "crates/lance-graph-dt64/src/lane.rs:386" + ], + "fresh": true + }, + { + "caller": "lance_graph_dt64::lane::{LaneBinding}::lane", + "callee": "lance_graph_dt64::lane::{LaneBinding}::check", + "sites": [ + "crates/lance-graph-dt64/src/lane.rs:360" + ], + "fresh": true + } + ], + "possible_edges": [ + { + "dispatch_target": "lance_graph_dt64::lane::LaneSource::lane_of" + } + ], + "co_changed_only": "NOT_RUN (no history projection in this prototype)", + "unsupported_regions": [ + "crates/cognitive-polyfill-probe/tests/p0.rs", + "crates/dir-rmap-probe/tests/equivalence.rs", + "crates/dr-isa-stream-lab/tests/integration/g2l.rs", + "crates/dr-math-binding-probe/tests/binding.rs", + "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs", + "crates/lance-graph-dt64/tests/dr.rs", + "crates/lance-graph-dt64/tests/lane_socket.rs", + "crates/lance-graph-report/src/lane_source/tests.rs", + "crates/thought-git-probe/tests/receipt.rs", + "crates/xlog-relcomp-probe/tests/dto_binding.rs" + ], + "findings": [ + { + "id": "dependents", + "summary": "2 confirmed transitive in-store callers; external callers UNKNOWN", + "severity": null, + "evidence_class": "COMPILER_DERIVED", + "confidence": "as graded per item", + "provenance": { + "tool": "charon c69e231 -> ruff_charon import (rows.tsv v2)", + "toolchain": "nightly-2026-09-17", + "sysroot": "default (cargo-miri absent; std bodies opaque)" + }, + "lifecycle": "open", + "run_status": "PARTIAL" + }, + { + "id": "tests", + "summary": "48 candidate test call sites by name; none run", + "severity": null, + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "items": [ + { + "site": "crates/cognitive-polyfill-probe/tests/p0.rs:271", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/cognitive-polyfill-probe/tests/p0.rs:275", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:234", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:238", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:249", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:481", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:522", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:663", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:677", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:678", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dir-rmap-probe/tests/equivalence.rs:680", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:136", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dr-isa-stream-lab/tests/integration/g2l.rs:263", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/dr-math-binding-probe/tests/binding.rs:234", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:162", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:722", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1012", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dir-sim/tests/ordinal_chain_lab.rs:1328", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:58", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:60", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:72", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:82", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:86", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:89", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:90", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:93", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:776", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:777", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:808", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:814", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:824", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:827", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/dr.rs:828", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:227", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:277", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:314", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:369", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:373", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:403", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:407", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-dt64/tests/lane_socket.rs:424", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: inside a macro region", + "run_status": "NOT_RUN" + }, + { + "site": "crates/thought-git-probe/tests/receipt.rs:715", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/thought-git-probe/tests/receipt.rs:715", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/xlog-relcomp-probe/tests/dto_binding.rs:233", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:320", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:341", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:418", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + }, + { + "site": "crates/lance-graph-report/src/lane_source/tests.rs:623", + "evidence_class": "SOURCE_STRUCTURE", + "qualifier": "POSSIBLE", + "why": "method-name match, receiver unresolved", + "ra": "UNKNOWN: file not indexed", + "run_status": "NOT_RUN" + } + ], + "provenance": { + "tool": "source search + rust-analyzer GRAPH=1 (ra_ap 0.0.358)" + }, + "lifecycle": "open", + "run_status": "NOT_RUN" + }, + { + "id": "contracts", + "summary": "trait methods the symbol dispatches through (a change may interact with any impl)", + "severity": null, + "evidence_class": "COMPILER_DERIVED", + "qualifier": "POSSIBLE", + "items": [ + "lance_graph_dt64::lane::LaneSource::lane_of" + ], + "provenance": { + "tool": "charon c69e231 -> ruff_charon import (rows.tsv v2)", + "toolchain": "nightly-2026-09-17", + "sysroot": "default (cargo-miri absent; std bodies opaque)" + }, + "lifecycle": "open", + "run_status": "COMPLETE" + }, + { + "id": "execution_paths", + "summary": "entry points (in-store callers with no in-store caller)", + "severity": null, + "evidence_class": "COMPILER_DERIVED", + "items": [ + "lance_graph_dt64::lane::{LaneBinding}::borrow_all", + "lance_graph_dt64::lane::{LaneBinding}::lane" + ], + "provenance": { + "tool": "charon c69e231 -> ruff_charon import (rows.tsv v2)", + "toolchain": "nightly-2026-09-17", + "sysroot": "default (cargo-miri absent; std bodies opaque)" + }, + "lifecycle": "open", + "run_status": "PARTIAL" + } + ], + "r2il": { + "method": "NOT_A_METHOD", + "body_semantics": "UNKNOWN", + "why": "R2IL describes the effects of a registered DT64 MethodBinding (prepare binds them to opcodes); a Rust function found by the compiler is not one, so its body has no R2IL reading" + }, + "expected_behavior": "NOT_SUPPLIED (must come from intent/tests, independently of this packet)", + "candidate_behavior": "NOT_INFERRED", + "missing_necessary_evidence": [ + "test runs (TEST_OBSERVED needs a run that can fail, CR-H0 \u00a75)", + "compiler artifacts of consumer crates and test targets", + "a resolved receiver for each name-matched test site" + ], + "permission_state": "NOT_DERIVED (never from confidence)" +} diff --git a/.codegraph/coverage.tsv b/.codegraph/coverage.tsv index c2e4302d6..a44ee53b2 100644 --- a/.codegraph/coverage.tsv +++ b/.codegraph/coverage.tsv @@ -36,7 +36,7 @@ lance-graph-benches 0 10 0 macro-generated items invisible;fn-local use not scan lance-graph-callcenter 35 6 3 macro-generated items invisible;fn-local use not scanned lance-graph-catalog 9 1 0 macro-generated items invisible;fn-local use not scanned lance-graph-codec-research 10 0 0 macro-generated items invisible;fn-local use not scanned -lance-graph-codegraph 8 11 0 macro-generated items invisible;fn-local use not scanned +lance-graph-codegraph 9 12 0 macro-generated items invisible;fn-local use not scanned lance-graph-cognitive 60 0 0 macro-generated items invisible;fn-local use not scanned lance-graph-consumer-conformance 2 0 0 macro-generated items invisible;fn-local use not scanned lance-graph-contract 175 35 2 macro-generated items invisible;fn-local use not scanned diff --git a/.codegraph/crates.tsv b/.codegraph/crates.tsv index 9c2335869..960b07544 100644 --- a/.codegraph/crates.tsv +++ b/.codegraph/crates.tsv @@ -36,7 +36,7 @@ lance-graph-benches crates/lance-graph-benches member 2f2fb296a08260fb lance-graph-callcenter crates/lance-graph-callcenter member 41a65d38ac70bc87 lance-graph-catalog crates/lance-graph-catalog member 9d0c34f70c28a465 lance-graph-codec-research crates/lance-graph-codec-research excluded 8b8afbd9a6d0f359 -lance-graph-codegraph crates/lance-graph-codegraph excluded bd209bed318ffbbc +lance-graph-codegraph crates/lance-graph-codegraph excluded e2541778f093a41e lance-graph-cognitive crates/lance-graph-cognitive excluded 93f956ac0d69ca66 lance-graph-consumer-conformance crates/lance-graph-consumer-conformance member 82e980465d770990 lance-graph-contract crates/lance-graph-contract member 6b4e13ff1d0afadb diff --git a/.codegraph/crates/lance-graph-codegraph.index.md b/.codegraph/crates/lance-graph-codegraph.index.md index 73728ed9c..6d0f44494 100644 --- a/.codegraph/crates/lance-graph-codegraph.index.md +++ b/.codegraph/crates/lance-graph-codegraph.index.md @@ -3,20 +3,20 @@ crate: lance-graph-codegraph path: crates/lance-graph-codegraph workspace: excluded -digest: bd209bed318ffbbc +digest: e2541778f093a41e evidence legend: ../index.md#evidence-legend Generated; the code is the truth. See ../index.md. ## Depends on -- dep lance-graph-contract dev — crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED +- dep lance-graph-contract normal — crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED - dep lance-graph-dt64 normal — crates/lance-graph-codegraph/Cargo.toml:13 CONFIRMED - dep lance-graph-mask-risc normal — crates/lance-graph-codegraph/Cargo.toml:15 CONFIRMED -- dep lance-graph-planner dev — crates/lance-graph-codegraph/Cargo.toml:22 CONFIRMED +- dep lance-graph-planner dev — crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED - dep lance-graph-quack normal — crates/lance-graph-codegraph/Cargo.toml:14 CONFIRMED - dep lance-graph-xlog normal — crates/lance-graph-codegraph/Cargo.toml:12 CONFIRMED -- dep ndarray normal — crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED +- dep ndarray normal — crates/lance-graph-codegraph/Cargo.toml:17 CONFIRMED - dep tokio dev — crates/lance-graph-codegraph/Cargo.toml:24 CONFIRMED ## Depended on by @@ -174,26 +174,37 @@ Generated; the code is the truth. See ../index.md. - fn Codegraph::any_partial [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1009 CONFIRMED - fn Codegraph::words [pub] — crates/lance-graph-codegraph/src/graph.rs:1014 CONFIRMED - fn Codegraph::mask_of [pub] — crates/lance-graph-codegraph/src/graph.rs:1019 CONFIRMED -- fn Codegraph::crate_status [pub] — crates/lance-graph-codegraph/src/graph.rs:1030 CONFIRMED -- fn Codegraph::rows [pub] — crates/lance-graph-codegraph/src/graph.rs:1036 CONFIRMED -- fn Codegraph::row_predicate [pub] — crates/lance-graph-codegraph/src/graph.rs:1041 CONFIRMED -- fn Codegraph::row_subject [pub] — crates/lance-graph-codegraph/src/graph.rs:1046 CONFIRMED -- fn Codegraph::row_object [pub] — crates/lance-graph-codegraph/src/graph.rs:1051 CONFIRMED -- fn Codegraph::site [pub] — crates/lance-graph-codegraph/src/graph.rs:1056 CONFIRMED -- fn Codegraph::cube [pub] — crates/lance-graph-codegraph/src/graph.rs:1070 CONFIRMED -- fn Codegraph::cube_mut [pub] — crates/lance-graph-codegraph/src/graph.rs:1075 CONFIRMED -- fn Codegraph::cube_and_table_mut [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1081 CONFIRMED -- fn Codegraph::table [pub] — crates/lance-graph-codegraph/src/graph.rs:1086 CONFIRMED -- fn Codegraph::fns [pub] — crates/lance-graph-codegraph/src/graph.rs:1091 CONFIRMED -- fn Codegraph::public [pub] — crates/lance-graph-codegraph/src/graph.rs:1095 CONFIRMED -- fn Codegraph::impl_subjects [pub] — crates/lance-graph-codegraph/src/graph.rs:1099 CONFIRMED -- fn Codegraph::synthetic [pub] — crates/lance-graph-codegraph/src/graph.rs:1103 CONFIRMED -- fn Codegraph::referenced [pub] — crates/lance-graph-codegraph/src/graph.rs:1107 CONFIRMED -- fn Codegraph::called [pub] — crates/lance-graph-codegraph/src/graph.rs:1111 CONFIRMED -- fn Codegraph::may_targets [pub] — crates/lance-graph-codegraph/src/graph.rs:1115 CONFIRMED -- fn Codegraph::dynamic_callers [pub] — crates/lance-graph-codegraph/src/graph.rs:1119 CONFIRMED -- fn Codegraph::stored_owner [pub] — crates/lance-graph-codegraph/src/graph.rs:1123 CONFIRMED -- fn Codegraph::closure [pub] — crates/lance-graph-codegraph/src/graph.rs:1129 CONFIRMED +- fn Codegraph::crate_list [pub] — crates/lance-graph-codegraph/src/graph.rs:1031 CONFIRMED +- fn Codegraph::has_rows [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1052 CONFIRMED +- fn Codegraph::crate_residuals [pub] — crates/lance-graph-codegraph/src/graph.rs:1062 CONFIRMED +- fn Codegraph::crate_status [pub] — crates/lance-graph-codegraph/src/graph.rs:1067 CONFIRMED +- fn Codegraph::rows [pub] — crates/lance-graph-codegraph/src/graph.rs:1073 CONFIRMED +- fn Codegraph::row_predicate [pub] — crates/lance-graph-codegraph/src/graph.rs:1078 CONFIRMED +- fn Codegraph::row_subject [pub] — crates/lance-graph-codegraph/src/graph.rs:1083 CONFIRMED +- fn Codegraph::row_object [pub] — crates/lance-graph-codegraph/src/graph.rs:1088 CONFIRMED +- fn Codegraph::site [pub] — crates/lance-graph-codegraph/src/graph.rs:1093 CONFIRMED +- fn Codegraph::cube [pub] — crates/lance-graph-codegraph/src/graph.rs:1107 CONFIRMED +- fn Codegraph::cube_mut [pub] — crates/lance-graph-codegraph/src/graph.rs:1112 CONFIRMED +- fn Codegraph::cube_and_table_mut [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1118 CONFIRMED +- fn Codegraph::table [pub] — crates/lance-graph-codegraph/src/graph.rs:1123 CONFIRMED +- fn Codegraph::fns [pub] — crates/lance-graph-codegraph/src/graph.rs:1128 CONFIRMED +- fn Codegraph::public [pub] — crates/lance-graph-codegraph/src/graph.rs:1132 CONFIRMED +- fn Codegraph::impl_subjects [pub] — crates/lance-graph-codegraph/src/graph.rs:1136 CONFIRMED +- fn Codegraph::synthetic [pub] — crates/lance-graph-codegraph/src/graph.rs:1140 CONFIRMED +- fn Codegraph::referenced [pub] — crates/lance-graph-codegraph/src/graph.rs:1144 CONFIRMED +- fn Codegraph::called [pub] — crates/lance-graph-codegraph/src/graph.rs:1148 CONFIRMED +- fn Codegraph::may_targets [pub] — crates/lance-graph-codegraph/src/graph.rs:1152 CONFIRMED +- fn Codegraph::dynamic_callers [pub] — crates/lance-graph-codegraph/src/graph.rs:1156 CONFIRMED +- fn Codegraph::stored_owner [pub] — crates/lance-graph-codegraph/src/graph.rs:1160 CONFIRMED +- fn Codegraph::closure [pub] — crates/lance-graph-codegraph/src/graph.rs:1166 CONFIRMED +- enum Targets [pub] — crates/lance-graph-codegraph/src/impact_report.rs:29 CONFIRMED +- enum Dependents [pub] — crates/lance-graph-codegraph/src/impact_report.rs:39 CONFIRMED +- struct ExtractionScope [pub] — crates/lance-graph-codegraph/src/impact_report.rs:48 CONFIRMED +- enum CoverageGap [pub] — crates/lance-graph-codegraph/src/impact_report.rs:60 CONFIRMED +- struct ImpactReport [pub] — crates/lance-graph-codegraph/src/impact_report.rs:127 CONFIRMED +- fn ImpactReport::no_known_gap [pub] — crates/lance-graph-codegraph/src/impact_report.rs:138 CONFIRMED +- enum ImpactAnswer [pub] — crates/lance-graph-codegraph/src/impact_report.rs:145 CONFIRMED +- fn Codegraph::impact_report [pub] — crates/lance-graph-codegraph/src/impact_report.rs:163 CONFIRMED - enum Fault [pub(crate)] cfg=test — crates/lance-graph-codegraph/src/lab_wal.rs:19 CONFIRMED - struct LabWal [pub(crate)] cfg=test — crates/lance-graph-codegraph/src/lab_wal.rs:35 CONFIRMED - fn LabWal::new [pub(crate)] cfg=test — crates/lance-graph-codegraph/src/lab_wal.rs:44 CONFIRMED @@ -205,15 +216,15 @@ Generated; the code is the truth. See ../index.md. - mod artifact_bin [pub] — crates/lance-graph-codegraph/src/lib.rs:7 CONFIRMED - mod diag [pub] — crates/lance-graph-codegraph/src/lib.rs:8 CONFIRMED - mod graph [pub] — crates/lance-graph-codegraph/src/lib.rs:9 CONFIRMED -- mod query [pub] — crates/lance-graph-codegraph/src/lib.rs:12 CONFIRMED +- mod impact_report [pub] — crates/lance-graph-codegraph/src/lib.rs:10 CONFIRMED +- mod query [pub] — crates/lance-graph-codegraph/src/lib.rs:13 CONFIRMED - struct Graded [pub] — crates/lance-graph-codegraph/src/query.rs:21 CONFIRMED - struct Calls [pub] — crates/lance-graph-codegraph/src/query.rs:32 CONFIRMED - struct Sites [pub] — crates/lance-graph-codegraph/src/query.rs:41 CONFIRMED - enum QueryRefusal [pub] — crates/lance-graph-codegraph/src/query.rs:52 CONFIRMED - fn Codegraph::callers [pub] — crates/lance-graph-codegraph/src/query.rs:125 CONFIRMED - fn Codegraph::callees [pub] — crates/lance-graph-codegraph/src/query.rs:157 CONFIRMED -- fn Codegraph::references [pub] — crates/lance-graph-codegraph/src/query.rs:188 CONFIRMED -- fn Codegraph::impact [pub] — crates/lance-graph-codegraph/src/query.rs:239 CONFIRMED +- truncated (202 total), see symbols.tsv ## Imports from in-scope crates @@ -223,6 +234,7 @@ Generated; the code is the truth. See ../index.md. - use lance_graph_contract::ontology::DisplayTemplate cfg=test — crates/lance-graph-codegraph/src/graph/publication.rs:14 CONFIRMED - use lance_graph_contract::ontology::FieldRef cfg=test — crates/lance-graph-codegraph/src/graph/publication.rs:14 CONFIRMED - use lance_graph_contract::scheduler::DatasetVersion cfg=test — crates/lance-graph-codegraph/src/graph/publication.rs:15 CONFIRMED +- use lance_graph_contract::hash::fnv1a — crates/lance-graph-codegraph/src/impact_report.rs:22 CONFIRMED - use lance_graph_contract::scheduler::DatasetVersion cfg=test — crates/lance-graph-codegraph/src/lab_wal.rs:11 CONFIRMED ### lance-graph-dt64 - use lance_graph_dt64::dr::Axis — crates/lance-graph-codegraph/src/graph.rs:9 CONFIRMED @@ -280,10 +292,12 @@ Generated from Cargo manifests — extracted relationships only. ```mermaid flowchart LR n36["lance-graph-codegraph"] + n39["lance-graph-contract"] n42["lance-graph-dt64"] n47["lance-graph-mask-risc"] n57["lance-graph-quack"] n66["lance-graph-xlog"] + n36 --> n39 n36 --> n42 n36 --> n47 n36 --> n57 diff --git a/.codegraph/crates/lance-graph-contract.index.md b/.codegraph/crates/lance-graph-contract.index.md index b4f802be6..9afc04edf 100644 --- a/.codegraph/crates/lance-graph-contract.index.md +++ b/.codegraph/crates/lance-graph-contract.index.md @@ -38,7 +38,7 @@ Generated; the code is the truth. See ../index.md. - rdep lance-graph-archetype normal — crates/lance-graph-archetype/Cargo.toml:10 CONFIRMED - rdep lance-graph-arm-discovery normal optional — crates/lance-graph-arm-discovery/Cargo.toml:52 CONFIRMED - rdep lance-graph-callcenter normal — crates/lance-graph-callcenter/Cargo.toml:12 CONFIRMED -- rdep lance-graph-codegraph dev — crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED +- rdep lance-graph-codegraph normal — crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED - rdep lance-graph-cognitive normal — crates/lance-graph-cognitive/Cargo.toml:19 CONFIRMED - rdep lance-graph-consumer-conformance normal — crates/lance-graph-consumer-conformance/Cargo.toml:21 CONFIRMED - rdep lance-graph-dir-sim dev — crates/lance-graph-dir-sim/Cargo.toml:52 CONFIRMED @@ -315,6 +315,7 @@ flowchart LR n30["lance-graph-archetype"] n31["lance-graph-arm-discovery"] n33["lance-graph-callcenter"] + n36["lance-graph-codegraph"] n37["lance-graph-cognitive"] n38["lance-graph-consumer-conformance"] n39["lance-graph-contract"] @@ -364,6 +365,7 @@ flowchart LR n30 --> n39 n31 --> n39 n33 --> n39 + n36 --> n39 n37 --> n39 n38 --> n39 n41 --> n39 diff --git a/.codegraph/crates/lance-graph-planner.index.md b/.codegraph/crates/lance-graph-planner.index.md index 59ad1198b..a8d6900b8 100644 --- a/.codegraph/crates/lance-graph-planner.index.md +++ b/.codegraph/crates/lance-graph-planner.index.md @@ -34,7 +34,7 @@ Generated; the code is the truth. See ../index.md. - rdep drf-focus-probe normal optional — crates/drf-focus-probe/Cargo.toml:19 CONFIRMED - rdep lance-graph dev — crates/lance-graph/Cargo.toml:175 CONFIRMED - rdep lance-graph normal optional — crates/lance-graph/Cargo.toml:92 CONFIRMED -- rdep lance-graph-codegraph dev — crates/lance-graph-codegraph/Cargo.toml:22 CONFIRMED +- rdep lance-graph-codegraph dev — crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED - rdep lance-graph-dt64-lance normal — crates/lance-graph-dt64-lance/Cargo.toml:28 CONFIRMED - rdep lance-graph-osint normal — crates/lance-graph-osint/Cargo.toml:11 CONFIRMED - rdep lance-graph-supervisor normal optional — crates/lance-graph-supervisor/Cargo.toml:17 CONFIRMED diff --git a/.codegraph/dependencies.tsv b/.codegraph/dependencies.tsv index 8c57f4551..a5fea7ef9 100644 --- a/.codegraph/dependencies.tsv +++ b/.codegraph/dependencies.tsv @@ -245,13 +245,13 @@ lance-graph-catalog tokio dev false - - crates/lance-graph-catalog/Cargo.toml:28 lance-graph-catalog wiremock dev false - - crates/lance-graph-catalog/Cargo.toml:29 CONFIRMED no lance-graph-codec-research rustfft normal false - - crates/lance-graph-codec-research/Cargo.toml:10 CONFIRMED no lance-graph-codec-research tempfile dev false - - crates/lance-graph-codec-research/Cargo.toml:13 CONFIRMED no -lance-graph-codegraph lance-graph-contract dev false - - crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED yes +lance-graph-codegraph lance-graph-contract normal false - - crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED yes lance-graph-codegraph lance-graph-dt64 normal false - - crates/lance-graph-codegraph/Cargo.toml:13 CONFIRMED yes lance-graph-codegraph lance-graph-mask-risc normal false - - crates/lance-graph-codegraph/Cargo.toml:15 CONFIRMED yes -lance-graph-codegraph lance-graph-planner dev false - - crates/lance-graph-codegraph/Cargo.toml:22 CONFIRMED yes +lance-graph-codegraph lance-graph-planner dev false - - crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED yes lance-graph-codegraph lance-graph-quack normal false - - crates/lance-graph-codegraph/Cargo.toml:14 CONFIRMED yes lance-graph-codegraph lance-graph-xlog normal false - - crates/lance-graph-codegraph/Cargo.toml:12 CONFIRMED yes -lance-graph-codegraph ndarray normal false - - crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED no +lance-graph-codegraph ndarray normal false - - crates/lance-graph-codegraph/Cargo.toml:17 CONFIRMED no lance-graph-codegraph tokio dev false - - crates/lance-graph-codegraph/Cargo.toml:24 CONFIRMED no lance-graph-cognitive holograph normal false - - crates/lance-graph-cognitive/Cargo.toml:18 CONFIRMED yes lance-graph-cognitive lance-graph-contract normal false - - crates/lance-graph-cognitive/Cargo.toml:19 CONFIRMED yes diff --git a/.codegraph/freshness.tsv b/.codegraph/freshness.tsv index c6f966411..88b2ab8ce 100644 --- a/.codegraph/freshness.tsv +++ b/.codegraph/freshness.tsv @@ -36,7 +36,7 @@ lance-graph-benches 2f2fb296a08260fb Cargo.toml+src (1 files) lance-graph-callcenter 41a65d38ac70bc87 Cargo.toml+src (36 files) lance-graph-catalog 9d0c34f70c28a465 Cargo.toml+src (10 files) lance-graph-codec-research 8b8afbd9a6d0f359 Cargo.toml+src (11 files) -lance-graph-codegraph bd209bed318ffbbc Cargo.toml+src (9 files) +lance-graph-codegraph e2541778f093a41e Cargo.toml+src (10 files) lance-graph-cognitive 93f956ac0d69ca66 Cargo.toml+src (61 files) lance-graph-consumer-conformance 82e980465d770990 Cargo.toml+src (3 files) lance-graph-contract 6b4e13ff1d0afadb Cargo.toml+src (176 files) diff --git a/.codegraph/imports.tsv b/.codegraph/imports.tsv index 448f89dc0..b5c1582a5 100644 --- a/.codegraph/imports.tsv +++ b/.codegraph/imports.tsv @@ -4738,17 +4738,17 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 10 lance_graph_x lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 10 lance_graph_xlog::cube::StagedEdges - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 11 lance_graph_xlog::wide::WideRows - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 11 lance_graph_xlog::wide::WideStats - use - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1149 super::* - use test POSSIBLE -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1150 std::fs - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1151 std::path::PathBuf - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1152 std::sync::atomic::AtomicU32 - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1152 std::sync::atomic::Ordering - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1347 super::* - use test POSSIBLE -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1348 std::collections::BTreeMap - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1349 std::fs - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1350 std::path::PathBuf - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1351 std::sync::atomic::AtomicU32 - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1351 std::sync::atomic::Ordering - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1186 super::* - use test POSSIBLE +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1187 std::fs - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1188 std::path::PathBuf - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1189 std::sync::atomic::AtomicU32 - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1189 std::sync::atomic::Ordering - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1384 super::* - use test POSSIBLE +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1385 std::collections::BTreeMap - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1386 std::fs - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1387 std::path::PathBuf - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1388 std::sync::atomic::AtomicU32 - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1388 std::sync::atomic::Ordering - use test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 14 crate::artifact - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 14 crate::artifact::CrateSource - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 14 crate::artifact::Interner - use - CONFIRMED @@ -4807,6 +4807,14 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 22 s lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 23 super::Codegraph - use test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 23 super::PreparedRefresh - use test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 24 crate::lab_wal::LabWal - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 19 std::collections::BTreeSet - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 20 std::path::Path - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 22 lance_graph_contract::hash::fnv1a - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 24 crate::graph::Codegraph - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 24 crate::graph::Pos - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 24 crate::graph::RunStatus - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 25 crate::query::Graded - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 25 crate::query::QueryRefusal - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 11 lance_graph_contract::scheduler::DatasetVersion - use test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 13 lance_graph_planner::persist_sink::CommitError - use test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 13 lance_graph_planner::persist_sink::CommitOutcome - use test CONFIRMED @@ -4820,12 +4828,12 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 14 lance_graph lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 170 super::* - use test POSSIBLE lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 171 lance_graph_planner::persist_sink::CycleFrame - use test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 9 std::collections::BTreeMap - use test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 14 graph::Codegraph - pub-use - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 14 graph::IntakeRefusal - pub-use - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 14 graph::Pos - pub-use - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 14 graph::RefreshRefusal - pub-use - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 14 graph::RefreshStats - pub-use - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 14 graph::RunStatus - pub-use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 15 graph::Codegraph - pub-use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 15 graph::IntakeRefusal - pub-use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 15 graph::Pos - pub-use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 15 graph::RefreshRefusal - pub-use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 15 graph::RefreshStats - pub-use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 15 graph::RunStatus - pub-use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/query.rs 10 lance_graph_xlog::cube::CubeRefusal - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/query.rs 10 lance_graph_xlog::cube::RelId - use - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/query.rs 11 lance_graph_xlog::wide::WideRows - use - CONFIRMED diff --git a/.codegraph/index.md b/.codegraph/index.md index d4712c239..eb3f2ddd0 100644 --- a/.codegraph/index.md +++ b/.codegraph/index.md @@ -305,6 +305,7 @@ flowchart LR n33 --> n39 n33 --> n53 n33 --> n59 + n36 --> n39 n36 --> n42 n36 --> n47 n36 --> n57 diff --git a/.codegraph/reverse_dependencies.tsv b/.codegraph/reverse_dependencies.tsv index 0025ed11f..637106e6d 100644 --- a/.codegraph/reverse_dependencies.tsv +++ b/.codegraph/reverse_dependencies.tsv @@ -170,7 +170,7 @@ lance-graph-contract lance-graph normal false - - crates/lance-graph/Cargo.toml: lance-graph-contract lance-graph-archetype normal false - - crates/lance-graph-archetype/Cargo.toml:10 CONFIRMED yes lance-graph-contract lance-graph-arm-discovery normal true - landing crates/lance-graph-arm-discovery/Cargo.toml:52 CONFIRMED yes lance-graph-contract lance-graph-callcenter normal false - - crates/lance-graph-callcenter/Cargo.toml:12 CONFIRMED yes -lance-graph-contract lance-graph-codegraph dev false - - crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED yes +lance-graph-contract lance-graph-codegraph normal false - - crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED yes lance-graph-contract lance-graph-cognitive normal false - - crates/lance-graph-cognitive/Cargo.toml:19 CONFIRMED yes lance-graph-contract lance-graph-consumer-conformance normal false - - crates/lance-graph-consumer-conformance/Cargo.toml:21 CONFIRMED yes lance-graph-contract lance-graph-dir-sim dev false - rbac crates/lance-graph-dir-sim/Cargo.toml:52 CONFIRMED yes @@ -264,7 +264,7 @@ lance-graph-planner drf-focus-probe dev false - handoff crates/drf-focus-probe/C lance-graph-planner drf-focus-probe normal true - handoff crates/drf-focus-probe/Cargo.toml:19 CONFIRMED yes lance-graph-planner lance-graph dev false - planner crates/lance-graph/Cargo.toml:175 CONFIRMED yes lance-graph-planner lance-graph normal true - planner crates/lance-graph/Cargo.toml:92 CONFIRMED yes -lance-graph-planner lance-graph-codegraph dev false - - crates/lance-graph-codegraph/Cargo.toml:22 CONFIRMED yes +lance-graph-planner lance-graph-codegraph dev false - - crates/lance-graph-codegraph/Cargo.toml:23 CONFIRMED yes lance-graph-planner lance-graph-dt64-lance normal false - - crates/lance-graph-dt64-lance/Cargo.toml:28 CONFIRMED yes lance-graph-planner lance-graph-osint normal false - - crates/lance-graph-osint/Cargo.toml:11 CONFIRMED yes lance-graph-planner lance-graph-supervisor normal true - cycle-driver crates/lance-graph-supervisor/Cargo.toml:17 CONFIRMED yes @@ -335,7 +335,7 @@ ndarray jc-batch-probe normal false - - crates/jc-batch-probe/Cargo.toml:21 CONF ndarray lance-graph normal true - ndarray-hpc crates/lance-graph/Cargo.toml:89 CONFIRMED no ndarray lance-graph-arm-discovery normal true - ndarray-simd crates/lance-graph-arm-discovery/Cargo.toml:45 CONFIRMED no ndarray lance-graph-benches normal false - - crates/lance-graph-benches/Cargo.toml:30 CONFIRMED no -ndarray lance-graph-codegraph normal false - - crates/lance-graph-codegraph/Cargo.toml:16 CONFIRMED no +ndarray lance-graph-codegraph normal false - - crates/lance-graph-codegraph/Cargo.toml:17 CONFIRMED no ndarray lance-graph-cognitive normal false - - crates/lance-graph-cognitive/Cargo.toml:17 CONFIRMED no ndarray lance-graph-mask-risc normal false - - crates/lance-graph-mask-risc/Cargo.toml:20 CONFIRMED no ndarray lance-graph-onnx normal false - - crates/lance-graph-onnx/Cargo.toml:12 CONFIRMED no diff --git a/.codegraph/symbols.tsv b/.codegraph/symbols.tsv index bea7437c0..530198c36 100644 --- a/.codegraph/symbols.tsv +++ b/.codegraph/symbols.tsv @@ -8687,26 +8687,29 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1001 fn Codegrap lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1009 fn Codegraph::any_partial pub(crate) - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1014 fn Codegraph::words pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1019 fn Codegraph::mask_of pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1030 fn Codegraph::crate_status pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1036 fn Codegraph::rows pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1041 fn Codegraph::row_predicate pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1046 fn Codegraph::row_subject pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1051 fn Codegraph::row_object pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1056 fn Codegraph::site pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1070 fn Codegraph::cube pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1075 fn Codegraph::cube_mut pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1081 fn Codegraph::cube_and_table_mut pub(crate) - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1086 fn Codegraph::table pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1091 fn Codegraph::fns pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1095 fn Codegraph::public pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1099 fn Codegraph::impl_subjects pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1103 fn Codegraph::synthetic pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1107 fn Codegraph::referenced pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1111 fn Codegraph::called pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1115 fn Codegraph::may_targets pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1119 fn Codegraph::dynamic_callers pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1123 fn Codegraph::stored_owner pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1129 fn Codegraph::closure pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1031 fn Codegraph::crate_list pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1052 fn Codegraph::has_rows pub(crate) - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1062 fn Codegraph::crate_residuals pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1067 fn Codegraph::crate_status pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1073 fn Codegraph::rows pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1078 fn Codegraph::row_predicate pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1083 fn Codegraph::row_subject pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1088 fn Codegraph::row_object pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1093 fn Codegraph::site pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1107 fn Codegraph::cube pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1112 fn Codegraph::cube_mut pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1118 fn Codegraph::cube_and_table_mut pub(crate) - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1123 fn Codegraph::table pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1128 fn Codegraph::fns pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1132 fn Codegraph::public pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1136 fn Codegraph::impl_subjects pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1140 fn Codegraph::synthetic pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1144 fn Codegraph::referenced pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1148 fn Codegraph::called pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1152 fn Codegraph::may_targets pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1156 fn Codegraph::dynamic_callers pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1160 fn Codegraph::stored_owner pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1166 fn Codegraph::closure pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 130 impl PosAt for Positions - - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 158 impl PosAt for PosStage<'_> - - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 167 impl PosStage<'a> - - CONFIRMED @@ -8738,6 +8741,16 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 996 fn Codegraph lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 108 impl Record - test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 165 impl W0 - test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph/publication.rs 65 impl ClassView for PubView - test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 127 struct ImpactReport pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 136 impl ImpactReport - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 138 fn ImpactReport::no_known_gap pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 145 enum ImpactAnswer pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 161 impl Codegraph - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 163 fn Codegraph::impact_report pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 29 enum Targets pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 39 enum Dependents pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 48 struct ExtractionScope pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 60 enum CoverageGap pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 19 enum Fault pub(crate) test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 35 struct LabWal pub(crate) test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 43 impl LabWal - test CONFIRMED @@ -8747,7 +8760,8 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 58 fn LabWal:: lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 64 fn LabWal::reverse_physical_order pub(crate) test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 70 fn LabWal::image pub(crate) test CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lab_wal.rs 78 impl WalSink for LabWal - test CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 12 mod query pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 10 mod impact_report pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 13 mod query pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 6 mod artifact pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 7 mod artifact_bin pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/lib.rs 8 mod diag pub - CONFIRMED diff --git a/.codegraph/views/BindStore.md b/.codegraph/views/BindStore.md index 0af6749c8..724fbe3c5 100644 --- a/.codegraph/views/BindStore.md +++ b/.codegraph/views/BindStore.md @@ -53,7 +53,7 @@ Generated; the code is the truth. Same-name symbols stay separate per file. - crates/grammar-constraints-probe/src/when.rs:39 POSSIBLE - crates/grammar-constraints-probe/src/when.rs:313 POSSIBLE - crates/grammar-constraints-probe/src/when.rs:414 POSSIBLE -- crates/lance-graph-codegraph/src/graph.rs:1564 POSSIBLE +- crates/lance-graph-codegraph/src/graph.rs:1601 POSSIBLE - crates/lance-graph-codegraph/src/graph/publication.rs:6 POSSIBLE - crates/lance-graph-codegraph/src/graph/publication.rs:16 POSSIBLE - crates/lance-graph-codegraph/src/graph/publication.rs:39 POSSIBLE diff --git a/crates/lance-graph-codegraph/Cargo.toml b/crates/lance-graph-codegraph/Cargo.toml index f70dc454e..7b3c74e30 100644 --- a/crates/lance-graph-codegraph/Cargo.toml +++ b/crates/lance-graph-codegraph/Cargo.toml @@ -13,6 +13,7 @@ lance-graph-xlog = { path = "../lance-graph-xlog" } lance-graph-dt64 = { path = "../lance-graph-dt64" } lance-graph-quack = { path = "../lance-graph-quack" } lance-graph-mask-risc = { path = "../lance-graph-mask-risc" } +lance-graph-contract = { path = "../lance-graph-contract" } ndarray = { git = "https://github.com/AdaWorldAPI/ndarray", branch = "master", default-features = false, features = ["std"] } [dev-dependencies] @@ -20,7 +21,6 @@ ndarray = { git = "https://github.com/AdaWorldAPI/ndarray", branch = "master", d # `CommitError`, `DetachedCycleBatch`) for the G10 x G11 publication lab. Never # a production edge from the codegraph to the planner. lance-graph-planner = { path = "../lance-graph-planner" } -lance-graph-contract = { path = "../lance-graph-contract" } tokio = { version = "1", features = ["rt"] } # One ndarray (CARGO-COMPUTE-SUBSTRATE rule 9): the planner names the sibling diff --git a/crates/lance-graph-codegraph/examples/cg_query.rs b/crates/lance-graph-codegraph/examples/cg_query.rs index 4b4975ef8..14cd311f1 100644 --- a/crates/lance-graph-codegraph/examples/cg_query.rs +++ b/crates/lance-graph-codegraph/examples/cg_query.rs @@ -4,6 +4,7 @@ //! ```text //! cargo run --release --example cg_query -- symbols [SUBSTRING] //! cargo run --release --example cg_query -- callers|callees|impact|refs SYMBOL +//! cargo run --release --example cg_query -- impact-report SYMBOL [--deps a,b] [--with-tests] [--no-freshness] //! ``` //! //! Output is tab-separated, one fact per line. Every result line carries its @@ -17,6 +18,7 @@ use std::path::{Path, PathBuf}; use std::process::ExitCode; +use lance_graph_codegraph::impact_report::{Dependents, ExtractionScope, ImpactAnswer, Targets}; use lance_graph_codegraph::Codegraph; fn line_of(src_root: &Path, file: &str, offset: u32) -> String { @@ -64,7 +66,7 @@ fn observed_files(g: &Codegraph) -> Vec { fn main() -> ExitCode { let args: Vec = std::env::args().skip(1).collect(); if args.len() < 3 { - eprintln!("usage: cg_query symbols [SUBSTR] | callers|callees|impact|refs SYMBOL"); + eprintln!("usage: cg_query symbols [SUBSTR] | sweep | callers|callees|impact|refs SYMBOL | impact-report SYMBOL [--deps a,b] [--with-tests] [--no-freshness]"); return ExitCode::from(2); } let (store, src, cmd) = ( @@ -135,6 +137,89 @@ fn main() -> ExitCode { } return ExitCode::SUCCESS; } + if cmd == "impact-report" { + // impact-report SYMBOL [--deps a,b] [--with-tests] [--no-freshness] + // The scope flags declare what the rows cannot say. Nothing is assumed: without + // `--with-tests` the store is taken to hold library targets only, and without `--deps` + // the dependents are undeclared. `--deps ""` declares that there are none. + let Some(sym) = args.get(3) else { + eprintln!("impact-report needs a SYMBOL"); + return ExitCode::from(2); + }; + let rest = &args[4..]; + let flag = |f: &str| rest.iter().any(|a| a == f); + let deps_value = match rest.iter().position(|a| a == "--deps") { + None => None, + Some(i) => match rest.get(i + 1) { + Some(v) if !v.starts_with("--") => Some(v.as_str()), + _ => { + eprintln!("--deps needs a value: a comma-separated list, or \"\" for none"); + return ExitCode::from(2); + } + }, + }; + let deps_list: Vec = deps_value + .map(|v| { + v.split(',') + .filter(|s| !s.is_empty()) + .map(str::to_string) + .collect() + }) + .unwrap_or_default(); + let deps_ref: Vec<&str> = deps_list.iter().map(String::as_str).collect(); + let scope = ExtractionScope { + targets: if flag("--with-tests") { + Targets::LibraryAndTests + } else { + Targets::LibraryOnly + }, + dependents: if deps_value.is_some() { + Dependents::Declared(&deps_ref) + } else { + Dependents::NotDeclared + }, + sources: (!flag("--no-freshness")).then_some((store.as_path(), src.as_path())), + }; + return match g.impact_report(sym, &scope) { + Ok(ImpactAnswer::SymbolNotInStore { symbol, observed }) => { + println!( + "UNKNOWN\tsymbol-not-in-store\t{symbol}\tobserved={}", + observed.join(",") + ); + ExitCode::from(4) + } + Ok(ImpactAnswer::Found(r)) => { + for (grade, mask) in [ + ("CONFIRMED", &r.graded.confirmed), + ("POSSIBLE", &r.graded.possible), + ("UNKNOWN", &r.graded.unknown), + ] { + for n in names(&g, mask) { + println!("impact\t{grade}\t{n}"); + } + } + for (c, st) in &r.observed { + println!("observed\t{c}\t{st:?}"); + } + for gap in &r.gaps { + println!("gap\t{gap:?}"); + } + println!( + "coverage\t{}", + if r.no_known_gap() { + "no known gap within the declared scope (not a proof of completeness)" + } else { + "incomplete: see gaps" + } + ); + ExitCode::SUCCESS + } + Err(e) => { + println!("REFUSED\timpact-report\t{e:?}"); + ExitCode::from(3) + } + }; + } let Some(sym) = args.get(3) else { eprintln!("{cmd} needs a SYMBOL"); return ExitCode::from(2); diff --git a/crates/lance-graph-codegraph/src/graph.rs b/crates/lance-graph-codegraph/src/graph.rs index d6a20e156..ba81f46f4 100644 --- a/crates/lance-graph-codegraph/src/graph.rs +++ b/crates/lance-graph-codegraph/src/graph.rs @@ -1027,6 +1027,43 @@ impl Codegraph { } /// The extractor status of `krate`, from its CRATE row. + /// Every stored crate with its extractor status, sorted by name. + pub fn crate_list(&self) -> Vec<(String, RunStatus)> { + // Every crate that was read, not only those with a CRATE row: a rows file without one + // says nothing about its own completeness, so it is `Partial`. + let mut ids: Vec = self.crates.keys().copied().collect(); + ids.extend(self.lanes.crates()); + ids.sort_unstable(); + ids.dedup(); + let mut out: Vec<(String, RunStatus)> = ids + .into_iter() + .map(|k| { + let status = self.crates.get(&k).copied().unwrap_or(RunStatus::Partial); + (self.symbols.name(k).to_string(), status) + }) + .collect(); + out.sort_by(|a, b| a.0.cmp(&b.0)); + out + } + + /// Whether any row currently names `symbol` as subject, object or dispatch target. A + /// position outlives the rows that created it (a refresh never renumbers), so a position + /// alone does not show the symbol is still in the artifacts. + pub(crate) fn has_rows(&self, symbol: &str) -> bool { + let Some(id) = self.symbols.get(symbol) else { + return false; + }; + let l = &self.lanes; + l.subject.contains(&id) || l.object.contains(&id) || l.may_target.contains(&id) + } + + /// The residuals read beside `krate`'s rows: `None` when the crate is not in the store, + /// `Some(None)` when it was read without a residuals file. + pub fn crate_residuals(&self, krate: &str) -> Option> { + let id = self.symbols.get(krate)?; + self.lanes.residuals_of(id) + } + pub fn crate_status(&self, krate: &str) -> Option { let id = self.symbols.get(krate)?; self.crates.get(&id).copied() diff --git a/crates/lance-graph-codegraph/src/impact_report.rs b/crates/lance-graph-codegraph/src/impact_report.rs new file mode 100644 index 000000000..7c3fd5edd --- /dev/null +++ b/crates/lance-graph-codegraph/src/impact_report.rs @@ -0,0 +1,318 @@ +//! A coverage-aware impact report: [`Codegraph::impact`] plus what the answer could not see. +//! +//! [`Codegraph::impact`] answers in symbol positions, and that stays as it is. A caller in a +//! crate the store never loaded has no position, so it cannot appear in [`Graded::unknown`] +//! (that would be a fabricated entry). This module reports such callers as missing *coverage* +//! instead: an [`ImpactReport`] carries the unchanged [`Graded`] answer together with every +//! [`CoverageGap`] that applies to it. +//! +//! Some coverage facts cannot be read off the rows: which targets were extracted, which crates +//! depend on the symbol's crate, and whether a source file changed since extraction. The caller +//! declares those in an [`ExtractionScope`]. A fact it does not declare becomes a gap +//! ([`CoverageGap::ConsumersNotDeclared`], [`CoverageGap::FreshnessNotChecked`]), never an +//! assumption. +//! +//! An empty gap list means no *known* gap within the declared scope. Like +//! [`crate::diag::Coverage::no_known_gap`], it is never a proof that the harvest saw everything, +//! and the declared scope is only as complete as the caller made it. + +use std::collections::BTreeSet; +use std::path::Path; + +use lance_graph_contract::hash::fnv1a; + +use crate::graph::{Codegraph, Pos, RunStatus}; +use crate::query::{Graded, QueryRefusal}; + +/// Which compilation targets the store's crates were extracted from. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Targets { + /// Library targets only: test targets, `#[cfg(test)]` modules, examples and benches were + /// not compiled, so their calls are unobserved. + LibraryOnly, + /// Library and test targets. + LibraryAndTests, +} + +/// The crates that depend on the queried symbol's crate, as the caller knows them. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Dependents<'a> { + /// Not declared: callers outside the store are unknown. + NotDeclared, + /// These crates depend on the symbol's crate (an empty slice means none do). + Declared(&'a [&'a str]), +} + +/// How the store was produced, as far as the rows cannot say it themselves. +#[derive(Clone, Copy, Debug)] +pub struct ExtractionScope<'a> { + /// Targets compiled for every crate in the store. + pub targets: Targets, + /// Reverse dependencies of the queried symbol's crate. + pub dependents: Dependents<'a>, + /// The store directory (`.files.tsv`) and the source root its paths are relative to. + /// `None`: freshness is not checked. + pub sources: Option<(&'a Path, &'a Path)>, +} + +/// Something the answer could not observe. Each gap names its cause. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum CoverageGap { + /// Declared dependents whose crates are not in the store; their callers are unobserved. + ConsumersNotInStore { + /// Crate names, sorted. + crates: Vec, + }, + /// The symbol is public and its dependents were not declared, so callers outside the store + /// may exist. + ConsumersNotDeclared, + /// Only library targets were extracted; callers in tests are unobserved. + TestTargetsNotExtracted, + /// Callers reach the symbol only through trait dispatch (`possible`), which the compiler did + /// not resolve to this implementation. + UnresolvedDispatch { + /// Positions in `graded.possible`. + possible: u32, + }, + /// A dynamic call or function pointer may reach the symbol (`graded.unknown`). + DynamicCalls { + /// Positions in `graded.unknown`. + unknown: u32, + }, + /// A store crate's CRATE row is not `COMPLETE`. + PartialCrate { + /// The crate name. + krate: String, + }, + /// A store crate carries extraction residuals (e.g. `BODY_NOT_STRUCTURED`): facts ruff_charon + /// could not represent, any of which may hide a call to the symbol. + Residuals { + /// The crate name. + krate: String, + /// Residuals over every kind. + count: u32, + }, + /// A store crate was read without a `.residuals.tsv`: what its harvest missed is unknown. + ResidualsNotRead { + /// The crate name. + krate: String, + }, + /// Source files whose content no longer matches the store. + StaleSource { + /// Paths relative to the source root, sorted. + files: Vec, + }, + /// Source files the store indexes that are absent from the source root. + MissingSource { + /// Paths relative to the source root, sorted. + files: Vec, + }, + /// A store crate has no `.files.tsv` to check freshness against. + NoFileList { + /// The crate name. + krate: String, + }, + /// A store crate's `.files.tsv` has a row without `path` or `fnv64`, so its sources + /// could not be compared. + InvalidFileList { + /// The crate name. + krate: String, + }, + /// No source root was given, so freshness was not checked. + FreshnessNotChecked, +} + +/// The impact of a symbol and the coverage behind it. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ImpactReport { + /// Exactly [`Codegraph::impact`]. + pub graded: Graded, + /// Every crate in the store with its extractor status, sorted by name. + pub observed: Vec<(String, RunStatus)>, + /// What the answer could not see; empty only when nothing known is missing. + pub gaps: Vec, +} + +impl ImpactReport { + /// No known gap within the declared scope. Not a proof of completeness. + pub fn no_known_gap(&self) -> bool { + self.gaps.is_empty() + } +} + +/// An impact answer, or the statement that the symbol is not in the store. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ImpactAnswer { + /// The symbol has a position. + Found(ImpactReport), + /// No position. Not "no impact": the symbol may exist in an unloaded crate. + SymbolNotInStore { + /// The symbol asked for. + symbol: String, + /// The crates the store holds. + observed: Vec, + }, +} + +fn popcount(mask: &[u64]) -> u32 { + mask.iter().map(|w| w.count_ones()).sum() +} + +impl Codegraph { + /// [`Codegraph::impact`] of `symbol`, with the coverage gaps that apply to the answer. + pub fn impact_report( + &self, + symbol: &str, + scope: &ExtractionScope<'_>, + ) -> Result { + let observed = self.crate_list(); + // A position alone is not enough: it survives a refresh that removed every row. + let pos = self.pos(symbol).filter(|_| self.has_rows(symbol)); + let Some(pos) = pos else { + return Ok(ImpactAnswer::SymbolNotInStore { + symbol: symbol.to_string(), + observed: observed.into_iter().map(|(c, _)| c).collect(), + }); + }; + let graded = self.impact(pos)?; + let gaps = self.gaps(pos, &graded, &observed, scope); + Ok(ImpactAnswer::Found(ImpactReport { + graded, + observed, + gaps, + })) + } + + fn gaps( + &self, + pos: Pos, + graded: &Graded, + observed: &[(String, RunStatus)], + scope: &ExtractionScope<'_>, + ) -> Vec { + let mut gaps = Vec::new(); + let public = { + let w = (pos / 64) as usize; + self.public() + .get(w) + .is_some_and(|word| word >> (pos % 64) & 1 == 1) + }; + let in_store: BTreeSet<&str> = observed.iter().map(|(c, _)| c.as_str()).collect(); + match scope.dependents { + Dependents::Declared(deps) => { + let missing: BTreeSet = deps + .iter() + .filter(|d| !in_store.contains(**d)) + .map(|d| d.to_string()) + .collect(); + if !missing.is_empty() { + gaps.push(CoverageGap::ConsumersNotInStore { + crates: missing.into_iter().collect(), + }); + } + } + Dependents::NotDeclared if public => gaps.push(CoverageGap::ConsumersNotDeclared), + Dependents::NotDeclared => {} + } + if scope.targets == Targets::LibraryOnly { + gaps.push(CoverageGap::TestTargetsNotExtracted); + } + let possible = popcount(&graded.possible); + if possible > 0 { + gaps.push(CoverageGap::UnresolvedDispatch { possible }); + } + let unknown = popcount(&graded.unknown); + if unknown > 0 { + gaps.push(CoverageGap::DynamicCalls { unknown }); + } + for (krate, status) in observed { + if *status == RunStatus::Partial { + gaps.push(CoverageGap::PartialCrate { + krate: krate.clone(), + }); + } + match self.crate_residuals(krate) { + Some(Some(r)) if r.total() > 0 => gaps.push(CoverageGap::Residuals { + krate: krate.clone(), + count: r.total(), + }), + Some(None) => gaps.push(CoverageGap::ResidualsNotRead { + krate: krate.clone(), + }), + _ => {} + } + } + match scope.sources { + None => gaps.push(CoverageGap::FreshnessNotChecked), + Some((store, root)) => gaps.extend(freshness(store, root, observed)), + } + gaps + } +} + +/// The rows of a `#schema` TSV, by column name; `None` when the file is absent or has no header. +fn read_schema_rows(path: &Path) -> Option>> { + let text = std::fs::read_to_string(path).ok()?; + let mut cols: Option> = None; + let mut rows = Vec::new(); + for line in text.lines() { + if let Some(h) = line.strip_prefix("#schema ") { + cols = Some(h.split('\t').map(str::to_string).collect()); + } else if !line.is_empty() && !line.starts_with('#') { + let cols = cols.as_ref()?; + rows.push( + cols.iter() + .cloned() + .zip(line.split('\t').map(str::to_string)) + .collect(), + ); + } + } + cols.map(|_| rows) +} + +/// Stale and missing source files across every store crate. The whole answer is folded from +/// every crate's rows, so a change anywhere in the store can move it. +fn freshness(store: &Path, root: &Path, observed: &[(String, RunStatus)]) -> Vec { + let (mut stale, mut missing, mut gaps) = (BTreeSet::new(), BTreeSet::new(), Vec::new()); + for (krate, _) in observed { + let Some(rows) = read_schema_rows(&store.join(format!("{krate}.files.tsv"))) else { + gaps.push(CoverageGap::NoFileList { + krate: krate.clone(), + }); + continue; + }; + let mut invalid = false; + for row in rows { + let (Some(path), Some(want)) = (row.get("path"), row.get("fnv64")) else { + invalid = true; + continue; + }; + match std::fs::read(root.join(path)) { + Err(_) => { + missing.insert(path.clone()); + } + Ok(bytes) if format!("{:016x}", fnv1a(&bytes)) != *want => { + stale.insert(path.clone()); + } + Ok(_) => {} + } + } + if invalid { + gaps.push(CoverageGap::InvalidFileList { + krate: krate.clone(), + }); + } + } + if !stale.is_empty() { + gaps.push(CoverageGap::StaleSource { + files: stale.into_iter().collect(), + }); + } + if !missing.is_empty() { + gaps.push(CoverageGap::MissingSource { + files: missing.into_iter().collect(), + }); + } + gaps +} diff --git a/crates/lance-graph-codegraph/src/lib.rs b/crates/lance-graph-codegraph/src/lib.rs index 4a7144256..f81ba6eb2 100644 --- a/crates/lance-graph-codegraph/src/lib.rs +++ b/crates/lance-graph-codegraph/src/lib.rs @@ -7,6 +7,7 @@ pub mod artifact; pub mod artifact_bin; pub mod diag; pub mod graph; +pub mod impact_report; #[cfg(test)] mod lab_wal; pub mod query; diff --git a/crates/lance-graph-codegraph/tests/impact_coverage.rs b/crates/lance-graph-codegraph/tests/impact_coverage.rs new file mode 100644 index 000000000..27cf78010 --- /dev/null +++ b/crates/lance-graph-codegraph/tests/impact_coverage.rs @@ -0,0 +1,391 @@ +//! Coverage-aware impact (D-CODEGRAPH-RECON-2 Gate A), over real Charon artifacts. +//! +//! `tests/data/rev1` holds `cg_lib` and its consumer `cg_app`, extracted by ruff_charon from +//! `crates/sag-ra-probe/fixtures/codegraph/rev1`. Each case distinguishes a different reason an +//! impact answer can be incomplete, and each has a twin where the reason is absent and the gap +//! must not appear. + +use std::path::{Path, PathBuf}; + +use lance_graph_codegraph::impact_report::{ + CoverageGap, Dependents, ExtractionScope, ImpactAnswer, ImpactReport, Targets, +}; +use lance_graph_codegraph::Codegraph; + +fn data() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/rev1") +} + +fn source_root() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join("../sag-ra-probe/fixtures/codegraph/rev1") +} + +/// A directory under the system temp dir, removed when the test ends. +struct Tmp(PathBuf); + +impl Tmp { + fn new(name: &str) -> Tmp { + let dir = std::env::temp_dir().join(format!("lgcg_impact_{name}_{}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + std::fs::create_dir_all(&dir).unwrap(); + Tmp(dir) + } +} + +impl std::ops::Deref for Tmp { + type Target = Path; + fn deref(&self) -> &Path { + &self.0 + } +} + +impl Drop for Tmp { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.0); + } +} + +/// A store holding only `crates`, copied from rev1. +fn store(name: &str, crates: &[&str]) -> Tmp { + let dir = Tmp::new(name); + for c in crates { + for ext in ["rows.tsv", "files.tsv", "residuals.tsv"] { + std::fs::copy( + data().join(format!("{c}.{ext}")), + dir.join(format!("{c}.{ext}")), + ) + .unwrap(); + } + } + dir +} + +/// The fullest scope: tests extracted, dependents declared, freshness checked. +fn full<'a>(store: &'a Path, root: &'a Path, deps: &'a [&'a str]) -> ExtractionScope<'a> { + ExtractionScope { + targets: Targets::LibraryAndTests, + dependents: Dependents::Declared(deps), + sources: Some((store, root)), + } +} + +fn report(dir: &Path, symbol: &str, scope: &ExtractionScope<'_>) -> ImpactReport { + match Codegraph::open(dir) + .unwrap() + .impact_report(symbol, scope) + .unwrap() + { + ImpactAnswer::Found(r) => r, + other => panic!("{symbol} not found: {other:?}"), + } +} + +fn confirmed(dir: &Path, r: &ImpactReport) -> Vec { + let g = Codegraph::open(dir).unwrap(); + let mut out = Vec::new(); + for (w, &word) in r.graded.confirmed.iter().enumerate() { + for b in 0..64 { + if word >> b & 1 == 1 { + out.push(g.symbol((w * 64 + b) as u32).unwrap().to_string()); + } + } + } + out.sort(); + out +} + +#[test] +fn no_callers_inside_a_fully_observed_scope_has_no_gap() { + // cg_app::run is public, but nothing depends on cg_app, so the declared scope is complete. + let dir = store("complete", &["cg_lib", "cg_app"]); + let root = source_root(); + let r = report(&dir, "cg_app::run", &full(&dir, &root, &[])); + assert!(confirmed(&dir, &r).is_empty()); + assert_eq!(r.gaps, vec![]); + assert!(r.no_known_gap()); +} + +#[test] +fn a_public_symbol_with_unobserved_consumers_reports_missing_coverage() { + let dir = store("lib_only", &["cg_lib"]); + let root = source_root(); + let r = report( + &dir, + "cg_lib::util::double", + &full(&dir, &root, &["cg_app"]), + ); + // The consumer has no position, so it is not in the answer: it is a gap, never an entry. + assert!(r.gaps.contains(&CoverageGap::ConsumersNotInStore { + crates: vec!["cg_app".into()] + })); + assert!(!r.no_known_gap()); + // Undeclared dependents of a public symbol are a gap too. + let undeclared = ExtractionScope { + dependents: Dependents::NotDeclared, + ..full(&dir, &root, &[]) + }; + assert!(report(&dir, "cg_lib::util::double", &undeclared) + .gaps + .contains(&CoverageGap::ConsumersNotDeclared)); +} + +#[test] +fn library_only_extraction_reports_unobserved_test_callers() { + let dir = store("targets", &["cg_lib", "cg_app"]); + let root = source_root(); + let lib_only = ExtractionScope { + targets: Targets::LibraryOnly, + ..full(&dir, &root, &[]) + }; + assert!(report(&dir, "cg_app::run", &lib_only) + .gaps + .contains(&CoverageGap::TestTargetsNotExtracted)); + assert!(!report(&dir, "cg_app::run", &full(&dir, &root, &[])) + .gaps + .contains(&CoverageGap::TestTargetsNotExtracted)); +} + +#[test] +fn dispatch_only_callers_report_unresolved_dispatch() { + // cg_lib::area_of dispatches Shape::area, which Rect implements; nothing calls Rect::area + // directly, so every caller is possible only. + let dir = store("dispatch", &["cg_lib", "cg_app"]); + let root = source_root(); + let r = report( + &dir, + "cg_lib::shapes::impl_Shape_for_Rect::area", + &full(&dir, &root, &[]), + ); + assert!(confirmed(&dir, &r).is_empty()); + assert!( + r.gaps + .iter() + .any(|g| matches!(g, CoverageGap::UnresolvedDispatch { possible } if *possible > 0)), + "{:?}", + r.gaps + ); + // Twin: util::triple's only caller (macro_use::checked) is reached by resolved calls only. + // (util::double would not do: Square::area calls it, and area_of reaches Square::area + // through dispatch, so area_of is a legitimate possible impact of double.) + let d = report(&dir, "cg_lib::util::triple", &full(&dir, &root, &[])); + assert!( + !d.gaps + .iter() + .any(|g| matches!(g, CoverageGap::UnresolvedDispatch { .. })), + "{:?}", + d.gaps + ); + assert!(!confirmed(&dir, &d).is_empty()); +} + +#[test] +fn a_changed_source_file_reports_stale_coverage() { + let dir = store("stale", &["cg_lib", "cg_app"]); + let root = Tmp::new("src"); + for c in ["cg_lib", "cg_app"] { + copy_dir(&source_root().join(c), &root.join(c)); + } + assert!(!report(&dir, "cg_app::run", &full(&dir, &root, &[])) + .gaps + .iter() + .any(|g| matches!(g, CoverageGap::StaleSource { .. }))); + let f = root.join("cg_lib/src/util.rs"); + let mut text = std::fs::read(&f).unwrap(); + text.extend_from_slice(b"\n// edited after extraction\n"); + std::fs::write(&f, text).unwrap(); + let r = report(&dir, "cg_app::run", &full(&dir, &root, &[])); + assert!( + r.gaps.contains(&CoverageGap::StaleSource { + files: vec!["cg_lib/src/util.rs".into()] + }), + "{:?}", + r.gaps + ); + // No source root: freshness is not checked, and that is a gap, not a pass. + let unchecked = ExtractionScope { + sources: None, + ..full(&dir, &root, &[]) + }; + assert!(report(&dir, "cg_app::run", &unchecked) + .gaps + .contains(&CoverageGap::FreshnessNotChecked)); +} + +#[test] +fn a_symbol_absent_from_the_store_is_not_an_empty_impact() { + let dir = store("missing", &["cg_lib"]); + let root = source_root(); + let a = Codegraph::open(&dir) + .unwrap() + .impact_report("cg_app::run", &full(&dir, &root, &[])) + .unwrap(); + assert_eq!( + a, + ImpactAnswer::SymbolNotInStore { + symbol: "cg_app::run".into(), + observed: vec!["cg_lib".into()] + } + ); +} + +#[test] +fn adding_the_consumer_crate_upgrades_missing_coverage_to_confirmed() { + let root = source_root(); + let lib = store("before", &["cg_lib"]); + let before = report( + &lib, + "cg_lib::util::double", + &full(&lib, &root, &["cg_app"]), + ); + assert!(!confirmed(&lib, &before).contains(&"cg_app::run".to_string())); + assert!(before.gaps.contains(&CoverageGap::ConsumersNotInStore { + crates: vec!["cg_app".into()] + })); + + let both = store("after", &["cg_lib", "cg_app"]); + let after = report( + &both, + "cg_lib::util::double", + &full(&both, &root, &["cg_app"]), + ); + assert!( + confirmed(&both, &after).contains(&"cg_app::run".to_string()), + "{:?}", + confirmed(&both, &after) + ); + assert!(!after + .gaps + .iter() + .any(|g| matches!(g, CoverageGap::ConsumersNotInStore { .. }))); + // The unchanged position-mask answer is a superset of what it was. + assert!(confirmed(&lib, &before) + .iter() + .all(|s| confirmed(&both, &after).contains(s))); +} + +fn copy_dir(from: &Path, to: &Path) { + std::fs::create_dir_all(to).unwrap(); + for e in std::fs::read_dir(from).unwrap() { + let e = e.unwrap(); + let p = e.path(); + if p.is_dir() { + copy_dir(&p, &to.join(e.file_name())); + } else { + std::fs::copy(&p, to.join(e.file_name())).unwrap(); + } + } +} + +/// Fails if extraction residuals are dropped from the impact answer: a body ruff_charon could +/// not represent may call the symbol, so a crate with residuals is a gap even when its CRATE row +/// is `COMPLETE`. The twin is `no_callers_inside_a_fully_observed_scope_has_no_gap` (rev1 has +/// none). +#[test] +fn extraction_residuals_are_a_coverage_gap() { + let dir = store("residuals", &["cg_lib", "cg_app"]); + let root = source_root(); + let res = dir.join("cg_app.residuals.tsv"); + let mut t = std::fs::read_to_string(&res).unwrap(); + t += "BODY_NOT_STRUCTURED\tcg_app::run\n"; + std::fs::write(&res, t).unwrap(); + let r = report(&dir, "cg_app::run", &full(&dir, &root, &[])); + assert_eq!( + r.gaps, + vec![CoverageGap::Residuals { + krate: "cg_app".into(), + count: 1 + }] + ); + assert!(!r.no_known_gap()); +} + +/// Fails if a crate read without a residuals file counts as fully covered: nothing is known +/// about what its harvest missed. +#[test] +fn a_missing_residuals_file_is_a_coverage_gap() { + let dir = store("no_residuals", &["cg_lib", "cg_app"]); + let root = source_root(); + std::fs::remove_file(dir.join("cg_app.residuals.tsv")).unwrap(); + let r = report(&dir, "cg_app::run", &full(&dir, &root, &[])); + assert_eq!( + r.gaps, + vec![CoverageGap::ResidualsNotRead { + krate: "cg_app".into() + }] + ); +} + +/// Fails if a crate read without a CRATE row is left out of the report: nothing states that its +/// extraction completed, so it is a partial crate, and its residual and freshness checks still run. +#[test] +fn a_crate_without_a_crate_row_is_partial_not_absent() { + let dir = store("no_crate_row", &["cg_lib", "cg_app"]); + let root = source_root(); + let rows = dir.join("cg_app.rows.tsv"); + let text = std::fs::read_to_string(&rows).unwrap(); + let kept: Vec<&str> = text.lines().filter(|l| !l.starts_with("CRATE\t")).collect(); + assert_eq!( + kept.len() + 1, + text.lines().count(), + "exactly one CRATE row" + ); + std::fs::write(&rows, kept.join("\n") + "\n").unwrap(); + let r = report(&dir, "cg_app::run", &full(&dir, &root, &[])); + assert!( + r.observed.iter().any(|(c, _)| c == "cg_app"), + "{:?}", + r.observed + ); + assert_eq!( + r.gaps, + vec![CoverageGap::PartialCrate { + krate: "cg_app".into() + }] + ); +} + +/// Fails if a symbol whose rows a refresh removed still answers `Found` with an empty impact: its +/// position survives the refresh, but it is no longer in the artifacts. +#[test] +fn a_symbol_removed_by_a_refresh_is_not_found() { + let dir = store("removed", &["cg_lib", "cg_app"]); + let root = source_root(); + let mut g = Codegraph::open(&dir).unwrap(); + let scope = full(&dir, &root, &[]); + assert!(matches!( + g.impact_report("cg_app::run", &scope).unwrap(), + ImpactAnswer::Found(_) + )); + let rows = dir.join("cg_app.rows.tsv"); + let text = std::fs::read_to_string(&rows).unwrap(); + let kept: Vec<&str> = text + .lines() + .filter(|l| l.starts_with('#') || l.starts_with("CRATE\t")) + .collect(); + std::fs::write(&rows, kept.join("\n") + "\n").unwrap(); + g.refresh_crate(&dir, "cg_app").unwrap(); + assert!(g.pos("cg_app::run").is_some(), "the position is retained"); + assert!(matches!( + g.impact_report("cg_app::run", &scope).unwrap(), + ImpactAnswer::SymbolNotInStore { .. } + )); +} + +/// Fails if a file-list row without a hash passes as a successful freshness check: that source +/// file was never compared. +#[test] +fn a_malformed_file_list_row_is_a_freshness_gap() { + let dir = store("bad_files", &["cg_lib", "cg_app"]); + let root = source_root(); + let files = dir.join("cg_app.files.tsv"); + let mut t = std::fs::read_to_string(&files).unwrap(); + t += "cg_app/src/extra.rs\n"; + std::fs::write(&files, t).unwrap(); + let r = report(&dir, "cg_app::run", &full(&dir, &root, &[])); + assert_eq!( + r.gaps, + vec![CoverageGap::InvalidFileList { + krate: "cg_app".into() + }] + ); +}