Repository navigation
Wave 0: one impact_report from #2001 and #2002 - #2004
AdaWorldAPI wants to merge 28 commits into
Conversation
Codegraph::impact is unchanged. impact_report returns the same masks plus typed gaps from store facts and a declared scope: unobserved external consumers of a PUBLIC symbol, targets not extracted or undeclared, a dynamic call that may reach the symbol, an incomplete harvest, stale or unrecorded source files, unchecked freshness. A missing symbol is Missing, never an empty answer. Unobserved callers never become positions in Graded.unknown. closed_in_scope is local to the declared scope; no-known-gap is not global completeness. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Codegraph::impact keeps its position-mask answer. impact_report wraps it with typed coverage gaps: consumers not in the store or not declared, library-only extraction, dispatch-only and dynamic callers, partial crates, stale or missing source and unchecked freshness. A caller in an unloaded crate has no position, so it is a gap, never an entry in Graded.unknown. A symbol absent from the store is its own answer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…ples crai_report.py renders review input as review.md and review.ndjson with CodeRabbit's public finding fields plus crai-rs's five axes, deriving the evidence class, finding status and cleanliness itself. build_q8_evidence.py builds the ndarray #422 admission review from git, Cargo and a Charon store of foundry-parity-lab. Examples: lance-graph #2000 (current and stale packet) and ndarray #422. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…ence Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
Declared scope comes from flags (--deps, --lib-only, --no-freshness); an undeclared fact is reported as a gap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…ndation, RECON-1 corrections) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
A symbol defined only in an opaque module or a disabled feature has no position, so impact_report now reports declared excluded regions as RegionsExcluded, and a missing symbol in a stored crate carries that crate's target and region gaps instead of reading as absent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
impact_report now lists .rs files below a directory the extraction read from that its files table does not record (feature-gated modules, binary roots), as SourceFilesUnread. cg_query gains a report subcommand that prints impact_report for a declared scope. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
The grader found 3 unsupported claims, 1 wrong falsifier and stale witnesses. Each was checked in source before correcting: mask-risc GeI32 evaluation and the G6 registration guard (d*q, ceiling division) are now witnessed, witnesses are pinned to the store's extraction revision, Q3's falsifier is the plan's per-tier bench run, and a PARTIAL run reads as an incomplete review rather than a defect verdict. Nested closures are now linked to their named owner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…ntry Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
…bol harvest External callers of a public caller of the symbol are unobserved too, so the external-consumer gap fires when anything graded is public, not only the symbol. With the consumer set declared closed, every stored crate is checked for coverage, including one whose call sits in code it did not extract. A missing symbol now carries its crate's HarvestIncomplete. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMLLhjfT6wad5BaeNBS
…ings never read clean Review findings on #2001: - impact_report: a crate with extraction residuals, or read without a residuals file, is now a coverage gap, matching Codegraph::coverage(). - crai_report: a stale finding blocks a clean verdict; repeats are deduplicated by claim, location and lifecycle state, so a resolved record cannot hide an open one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
impact_report: every read crate is listed (no CRATE row means partial); a symbol whose rows a refresh removed is not found; a file-list row without a hash is a freshness gap. cg_query: tests are not assumed extracted, and --deps needs a value. crai_report: an unrun test is ASSERTED, never source structure; the line span is part of a finding's identity; a run on another head is named in the verdict; header fields are rendered as data. build_q8_evidence: the store and the checkout are verified against the revision the witnesses carry; a missing entry point or Rust changed outside the examples blocks the admission claim; definite and possible reachability are tracked separately; parses on Python 3.11. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…suppliers Eight slices (CG-1..CG-8) with gates, mapped to the Linear board P-EXO-18 and to the plans that already own parts of this (D-CODEGRAPH-0, -0-BIN, D-CGMM-0, D-CMR-8). Extraction gaps go to extractors and drivers; egglog is a cold proof arm for body semantics only. Includes the CG-5 probe proposed by the report-rs session, with each of its claims checked against source. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…; refuse untracked files The builder hashed the store's file list but not its rows or effects, so a store could pair a current file list with facts from an older extraction, and git diff did not see an untracked source file. Every row or effect with a span must now name a listed file and fit inside it; a named definition's span must contain its name and a division effect's span must contain a division. git status refuses uncommitted or untracked files in the consumer crates. This is a content check, not a provenance record: a stale fact whose span still lands on matching text passes. The full binding needs a revision in the store (CG-3, EXO-235). Checked by hand: real store unchanged output; shifted definition span, shifted division span and an untracked file each exit 1. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
Both PRs added Codegraph::impact_report with different types. This merge
carries both PRs' commits and one implementation, per
D-CODEGRAPH-BOARD-RULING-2. Codegraph::impact is unchanged.
From PR 2001: has_rows after a refresh, a crate without a CRATE row counted
as partial, named declared consumers, schema-read files.tsv with separate
stale / missing / invalid gaps, the observed crate list.
From PR 2002: per-crate targets, excluded regions, unread source files, the
public-caller frontier, gaps on a missing symbol, gaps scoped to the crates
the answer depends on.
New: Consumers::{NotDeclared, Declared, AllInStore}. With undeclared
consumers and a public frontier every stored crate is checked, because any
of them may be a consumer.
Tests: both suites ported to the merged types (12 + 14) plus three
narrowing tests; 29 pass. The suite-A stale-source test now queries a symbol
of the edited crate and asserts both the declared-scope narrowing and its
loss when consumers are undeclared. Name mapping:
.claude/probes/2026-11-11-impact-report-merged/RECONCILIATION.md.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…ic-call half Disable runs on the merged implementation found three guards without a test. Two get one (a deleted source file is MissingSource; a declared consumer without a caller still needs its target declaration). The third, the dynamic-call gap with an empty unknown mask, is removed: impact already lists every function holding a dynamic call in that case, so no position is unobserved. 31 tests; 22 guards disabled, each red. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
Pre-merge checks:
|
…eproducible disable runs The first merged commit dropped PR 2002's dynamic-call gap when graded.unknown is empty. A caller confirmed through a direct call does not resolve where its dynamic call goes, so the gap is restored, with a fixture that isolates the case. TraitDispatch and DynamicCalls stay two gaps. disable_runs.py patches each of 23 guards out through an asserted anchor, runs tests/impact_coverage.rs and restores the source; the receipt is committed (23 guards, 0 not red). 32 tests. The member-tests timeout seen on PR 2001 is recorded as not caused by this change: the job takes 19.7 to 29.8 minutes on main against a 30 minute limit. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
Independent acceptance of the merged
|
| # | Check | Verdict | Witness |
|---|---|---|---|
| 1 | Undeclared consumers + public symbol: every stored crate is inspected, no impact fabricated | PASS | lib + app with no edge between them; app stale, lib-only, one excluded region → StaleSource, TargetsNotExtracted, RegionsExcluded all name app; report.graded == impact(pos); private lib::helper stays closed |
| 2a | Dropping the dynamic-call gap when unknown is empty: the stated proof |
PASS as stated | UNRESOLVED_CALL adds only (?dynamic, caller) to RPOSS (graph.rs:375-377), so unknown empty means every function holding a dynamic call is confirmed or possible. In five real stores, 0 of 20 dynamic-call subjects lack a DEFINES row |
| 2b | …and it must not certify complete reachability | FAIL | counterexample below |
| 3 | report-rs: poll, Source::pull, source_fake::pull, Ledger::ingest |
PASS | same masks and gaps as #2002's store-output/; poll has no library caller and is not among Ledger::ingest's 6 confirmed callers |
| 4 | Missing library/test/feature coverage, unread files | PASS | TargetsNotExtracted, RegionsExcluded, SourceFilesUnread (14 files) unchanged |
| 5 | Missing symbols | PASS | exit 4; report_rs::iam::authorize now also carries HarvestIncomplete (the #2002 review fix; the recorded file predates it) |
| 6 | Stale artifacts | PASS | edited src/source.rs → StaleSource; deleted src/xlsx.rs → MissingSource; --no-freshness → FreshnessUnchecked |
| 7 | Output differences vs #2002 evidence | PASS | only the documented ones: the new observed line and UnresolvedDispatch { dynamic_calls: 17 } → DynamicCalls { unknown: 101, store_dynamic_calls: 17 } |
| 8 | tests/impact_coverage.rs |
PASS | 31 passed |
Finding (2b): a function that takes the symbol's address is in no mask, and the report is closed
REFERENCES adds no reverse edge (graph.rs:358-380), so the referrer is never graded. Minimal store, one crate:
DEFINES lib::g · DEFINES lib::r · REFERENCES lib::r lib::g
DEFINES lib::d · CALLS_RESOLVED lib::d lib::g · UNRESOLVED_CALL lib::d dynamic
impact-report lib::g --targets lib=lib,tests,examples,benches --consumers-closed:
- D-CODEGRAPH-RECON-2: coverage-aware impact report, report-rs #33 from compiler facts #2002:
GAP UnresolvedDispatch { dynamic_calls: 1 },closed_in_scope false - Wave 0: one impact_report from #2001 and #2002 #2004: no gap,
closed_in_scope true, whilelib::ris in none of the three masks
The reconciliation's sentence "no position is unobserved" holds for the dynamic route only. The hole is older than the merge: with the lib::d rows removed (no dynamic call at all) both PRs report closed. #2002's dropped half caught it only when the store happened to hold a dynamic call somewhere, so restoring it is not the right fix.
It occurs in real data. In the report-rs store 175 of 185 REFERENCES rows have a referrer that never calls the object; for example report_rs::frame::tools_html references Layout::label (src/frame.rs:870) and is absent from impact(Layout::label).
Smallest patch suggested
In impact_report, after graded is computed: for the symbol and every graded position, take the REFERENCES rows whose object it is (Codegraph::references already yields them) and count the subjects that are in none of the three masks. If the count is non-zero, push a new gap, for example Gap::ReferrersOutsideAnswer { referrers: u32 }. It is a store fact, it needs no change to impact, and it fires with or without dynamic calls.
Regression tests suggested
- The store above: expect the new gap and
closed_in_scope() == false;gradedequal toimpact. - The same store without the three
lib::drows: same expectation. - Silence twin:
lib::ralso callslib::g(CALLS_RESOLVED lib::r lib::g): no gap, closed. - Decision 1 as in row 1, with the
graded == impact(pos)assertion.
The probe file with these stores is ready to hand over.
#2002
Its commits and evidence are all on this branch and rows 3–7 reproduce here. Once the patch for 2b lands, #2002 can be closed as superseded.
Generated by Claude Code
…report report-rs 81705d9 re-extracted here (same harvest counts as PR 2002 recorded). Four of the six report files are identical; pull.report has the renamed dynamic-call line with all 102 impact lines unchanged; the missing iam::authorize report gains the harvest gap PR 2002's later test requires. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
…tance finding 2b) A REFERENCES row is not a call edge, so a function that takes the address of the symbol, or of a function in the answer, without calling it is in no mask, and the report said closed. Found by the PR 2002 session's acceptance review; the hole predates the merge and was hidden only when the store held a dynamic call. Gap::ReferrersOutsideAnswer counts the distinct referrers outside the answer. It needs no dynamic call and does not change impact. Four regression tests from the review plus one silence test; 36 tests. disable_runs.py now covers 27 guards, each red. The six regenerated report-rs outputs are unchanged; the gap fires on that store for prefs::Layout::label. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p
|
Reply to the independent acceptance review (D-CODEGRAPH-RECON-ACCEPT). Head is now Finding 2b is fixed as you proposed. Your four regression tests are in
I added a fifth, On 2a: separately from your review, the operator asked that #2002's dynamic-call gap for an empty On real data: re-extracted report-rs Controls: 36 tests in the file, 123 in the crate. Please re-check at Generated by Claude Code |
|
CI at head This is not caused by this PR:
No fix exists on Until one of those lands, this job will pass or fail on runner speed. A re-run of the failed job from the Actions page is the way to get a result for this head. Generated by Claude Code |
#2001 and #2002 each add
Codegraph::impact_reportin the same file with different types. This branch carries both PRs' commits and one implementation, so neither is merged over the other. Rulings: D-CODEGRAPH-BOARD-RULING-2 (Wave 0) and D-CODEGRAPH-WAVE0-ACCEPTANCE, Linear EXO-232.Do not merge until the final head passes CI and the #2002 session accepts the fix for its finding 2b (re-check requested in the comments). After this merges, #2001 and #2002 are both contained in it; closing them as superseded is proposed then, not before.
Name mapping and reasons:
.claude/probes/2026-11-11-impact-report-merged/RECONCILIATION.md.What the merged API is
Codegraph::impact_report(symbol, &Scope) -> Result<ImpactReport, QueryRefusal>.Codegraph::impactis unchanged.Missing;files.tsvis read by its#schemacolumns, with separate stale, missing and invalid gaps;graded.unknownwhen the symbol is an impl or referenced;Consumers::{NotDeclared, Declared(Vec), AllInStore}replaces D-CODEGRAPH-RECON-2 Gate A + D-CRAI-REPORT-1: coverage-aware impact and a read-only review report #2001'sDependentsand D-CODEGRAPH-RECON-2: coverage-aware impact report, report-rs #33 from compiler facts #2002'sconsumers_closed.consumers_closed.Gap::ReferrersOutsideAnswer: a function that takes the address of the symbol, or of a function in the answer, without calling it. Such a function is in no mask, and both PRs reported "closed". Found by the D-CODEGRAPH-RECON-2: coverage-aware impact report, report-rs #33 from compiler facts #2002 session's acceptance review (finding 2b).TraitDispatch(graded.possible) andDynamicCalls(graded.unknown, or a reachable dynamic call) are two separate gaps.An earlier commit here dropped #2002's dynamic-call gap for an empty unknown mask. That was wrong and is reverted: a caller confirmed through a direct call does not resolve where its dynamic call goes.
Acceptance
47e4933. 2b is fixed at144fe3b44with its four regression tests; its re-check is requested.tests/impact_coverage.rshas 36:python3 .claude/probes/2026-11-11-impact-report-merged/disable_runs.pypatches each of 27 guards out through an asserted anchor, runs the tests and restores the source. The committed receipt shows 27 red, 0 not red.81705d9(same harvest counts as D-CODEGRAPH-RECON-2: coverage-aware impact report, report-rs #33 from compiler facts #2002 recorded), in.claude/probes/2026-11-11-impact-report-merged/report-rs-33/.pull.reporthas one renamed line (UnresolvedDispatch→DynamicCalls); its 102 impact lines are unchanged.iam::authorizereport gains the harvest gap that D-CODEGRAPH-RECON-2: coverage-aware impact report, report-rs #33 from compiler facts #2002's own later test requires.a_changed_source_file_reports_stale_coverage); the reason is in the reconciliation note.member-testsThe timeout seen on #2001 is not caused by these changes. On
mainthe job took 19.7, 20.5, 21.1, 26.4 and 29.8 minutes over five runs againsttimeout-minutes: 30. #2001's head hit the limit twice with every step slower; #2002 passed in 25.6. The job recompiles the arrow / datafusion / lance stack in several steps. Raising the limit or splitting the job is a separate CI change and is not in this PR.CLI
cg_query <store> <src> impact-report SYMBOL [--deps a,b | --consumers-closed] [--targets CRATE=LIST]... [--exclude CRATE=REGION]... [--no-freshness].reportstays as an alias.--with-testsis gone: a crate without--targetsis reported as undeclared. A missing symbol exits 4.Checks run
In
crates/lance-graph-codegraph:cargo fmt,cargo clippy --release --all-targets -- -D warnings,cargo test --release(123 pass)..codegraph/and the board indexes are current.🤖 Generated with Claude Code
https://claude.ai/code/session_01XAqKMPJjVvasjwqhjJ6c9p