diff --git a/.claude/board/entries/2026-11-11-codegraph-recon-2.md b/.claude/board/entries/2026-11-11-codegraph-recon-2.md new file mode 100644 index 000000000..05db99f13 --- /dev/null +++ b/.claude/board/entries/2026-11-11-codegraph-recon-2.md @@ -0,0 +1,25 @@ +# 2026-11-11 — Coverage-aware impact; report-rs #33 recovered from compiler facts + +**Status:** MEASURED (probe). `.claude/probes/2026-11-11-codegraph-recon-2/`. Follows +`2026-11-11-codegraph-recon-1` (#2000). Board: EXO-229, EXO-230. + +`Codegraph::impact_report` (additive; `impact` unchanged) returns `impact`'s masks plus typed gaps: +external consumers unobserved, targets not extracted or undeclared, excluded regions, unresolved +dispatch, incomplete harvest, stale or unrecorded files, and `.rs` files under a read directory that +`files.tsv` does not list. Missing coverage never enters `Graded.unknown`. A missing symbol carries +its crate's gaps. 14 tests; every guard disable-verified red. + +report-rs `81705d9` through Charon (lib, default features, `crate::app` opaque): CRATE `COMPLETE`, +yet 14 of 59 `src/` files unread (`iam.rs`, `main.rs`, `project_plan/*`, …). The store recovers the +first #33 finding: `workbook_delta::WorkbookSource::poll` has no library caller and no path to +`Ledger::ingest`; `Ledger::pull → source_fake::pull` is dynamic and reported UNKNOWN. + +Blind arms graded strictly against the EXO-185 key (12 items): source arm 12 correct; store arm +7 correct, 3 partial, 2 unsupported; 0 wrong in both. The store's misses are configuration +(feature-gated `iam`), targets (test callers) and manifest facts (Cargo.toml). n = 1 per arm. + +#2000 reproduces from its documented commands: rows equal, `machine-recovered.mmd` byte-identical, +Charon recall column identical. + +OPEN: per-configuration stores (features, test targets); recording targets and opaque modules in +the store instead of declaring them. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 6a6e823bb..cf28e5540 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,10 +25,11 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -597 entries, 2026-08-06 .. 2026-11-11. +598 entries, 2026-08-06 .. 2026-11-11. | date | entry id | finding | file | |---|---|---|---| +| 2026-11-11 | `codegraph-recon-2` | | [2026-11-11-codegraph-recon-2.md](2026-11-11-codegraph-recon-2.md) | | 2026-11-11 | `codegraph-recon-1` | | [2026-11-11-codegraph-recon-1.md](2026-11-11-codegraph-recon-1.md) | | 2026-11-10 | `lab-resolve-borrow-all` | | [2026-11-10-lab-resolve-borrow-all.md](2026-11-10-lab-resolve-borrow-all.md) | | 2026-11-10 | `int8-direct-packed-b` | | [2026-11-10-int8-direct-packed-b.md](2026-11-10-int8-direct-packed-b.md) | diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/GRADES.tsv b/.claude/probes/2026-11-11-codegraph-recon-2/GRADES.tsv new file mode 100644 index 000000000..ae87cf288 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/GRADES.tsv @@ -0,0 +1,26 @@ +#version 1 +#schema key arm grade note +K1.1 M CORRECT both identities, source_fake.rs:19 and workbook_delta/source.rs:210 +K1.1 C PARTIAL both identities CONFIRMED; defining lines UNKNOWN (the store records spans, not struct lines) +K1.2 M CORRECT source_fake.rs:29 impl Source +K1.2 C CORRECT IMPLEMENTS rows; witness source_fake.rs:39 (the pull fn, not the impl line) +K1.3 M CORRECT inherent poll, returns Poll, no Source impl +K1.3 C CORRECT no Source impl for the delta type, ABSENT-IN-SCOPE +K1.4 M CORRECT Ledger::pull calls src.pull (333) then ingest (334); projection.rs:409 passes source_fake +K1.4 C CORRECT ingest edge CONFIRMED at source.rs:334; dyn Source call reported UNKNOWN, not CONFIRMED +K1.5 M CORRECT no src caller of poll; callers in tests/p20 and examples/workbook_sync.rs; lands in Workbook::ingest +K1.5 C PARTIAL poll has 0 callers in the lib scope and no edge to Ledger::ingest; test/example callers not named (targets not extracted, reported as a gap) +K1.6 M CORRECT does not claim poll has no callers at all +K1.6 C CORRECT ABSENT-IN-SCOPE with tests/examples UNOBSERVED; never "no callers" +K2.1 M CORRECT iam.rs:250, behind feature iam (lib.rs:22-23) +K2.1 C UNSUPPORTED iam.rs reported unread, feature off, call UNOBSERVED +K2.2 M CORRECT no authorize_scoped anywhere +K2.2 C CORRECT ABSENT-IN-SCOPE, with the iam build UNOBSERVED +K2.3 M CORRECT gating stated; default build does not compile iam +K2.3 C CORRECT does not claim report-rs never authorizes +K3.1 M CORRECT no dt64-lance dependency (Cargo.toml), no MapLog in any file +K3.1 C PARTIAL no MapLog symbol in scope; the dependency fact is outside the store and not stated; lance-feature build left UNOBSERVED +K3.2 M CORRECT IdentityFrame holds MapTable (frame.rs:55-57), advanced in commit (189-203) +K3.2 C CORRECT MapTable::new frame.rs:69, advance frame.rs:195 in IdentityFrame::commit, called from ingest.rs:264 +K3.3 M CORRECT absence stated over every file and Cargo.toml, independent of features +K3.3 C UNSUPPORTED did not frame it as a dependency-scope fact diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/REPORT.md b/.claude/probes/2026-11-11-codegraph-recon-2/REPORT.md new file mode 100644 index 000000000..e6376d14b --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/REPORT.md @@ -0,0 +1,152 @@ +# D-CODEGRAPH-RECON-2: coverage-aware impact, and report-rs #33 from compiler facts + +D-CODEGRAPH-RECON-1 (#2000) showed that `Codegraph::impact` returns an empty set for a public +symbol whose callers live in crates the store does not hold. This probe keeps `impact` as it is +and adds `Codegraph::impact_report`, which returns the same masks plus a typed list of what the +answer could not see. It then answers three questions about report-rs PR #33 from a Charon store +and grades the answers against the manual EXO-185 findings, which were held out. + +Result: the store recovers the first #33 finding (the SharePoint drive source never reaches +`Ledger::ingest` from library code), explains it correctly, and names every region it could not +see. Both arms made no wrong statement. The source-reading arm was more complete, because the +store sees one build configuration and one target. + +## 1. `impact_report` (Gate A) + +`crates/lance-graph-codegraph/src/impact_report.rs`. `Codegraph::impact` is unchanged and +`ImpactReport.graded` is exactly its output. Missing coverage is never written into +`Graded.unknown`, which stays "observed functions a dynamic call may reach". + +| gap | source of the fact | +|---|---| +| `ExternalConsumersUnobserved` | the symbol or anything that reaches it is `PUBLIC`, and the consumer set is not declared closed; when it is declared closed, every stored crate's coverage is checked | +| `TargetsNotExtracted` / `TargetsUndeclared` | declared per crate (the store does not record targets) | +| `RegionsExcluded` | declared: opaque modules, features left off | +| `UnresolvedDispatch` | `UNRESOLVED_CALL` rows that may reach the symbol | +| `HarvestIncomplete` | residuals file, CRATE status | +| `StaleSource` / `FilesUnrecorded` / `FreshnessUnchecked` | `.files.tsv` digests against the source root | +| `SourceFilesUnread` | `.rs` files below a directory the extraction read from, absent from `files.tsv` | + +A missing symbol in a stored crate carries its crate's target, region and file gaps, because each +is a place it may still be defined. `closed_in_scope()` is true only for a found symbol with no +gap, and it claims nothing about code outside the scope. `Coverage::no_known_gap()` alone is not +treated as closure: test 2 asserts it is true while the report is not closed. + +`tests/impact_coverage.rs`, 14 tests: one per case in the brief, three found while running +Gate B (excluded regions, target gaps of a missing symbol, unread files), and three from review +(a private symbol behind a public caller, a closed consumer set checks every stored crate, a +missing symbol's harvest gap). Every guard was disabled +and its test went red: external consumers, missing targets, undeclared targets, dispatch fire, +dispatch silence, stale source, owner stored, observed consumers, closed symbol, harvest, +missing-symbol scope gaps, excluded regions, unread files (fire and silence), missing-symbol file +gaps, public frontier, closed consumer set, missing-symbol harvest. + +## 2. The report-rs store (Gate B) + +Inputs: report-rs `81705d9` (#33 head). Charon `c69e231`, nightly-2026-09-17, library target, +default features, `--opaque 'crate::app'` (the full crate ran out of memory at 15 GB). ruff_charon +from ruff `9752608`. + +| step | time (µs, reported, not gates) | result | +|---|---|---| +| charon | 42,192,655 | exit 0 | +| ruff_charon import | 25,202,579 | 29,542 harvested, 1 residual (`REFERENCE_NOT_NAMED view::Scope::only`) | +| six cg_query runs (cold open each) | 435,149 | | + +The CRATE row says `COMPLETE`, yet 14 of 59 files under `src/` were never read: `app.rs` and +`app/plan_routes.rs` (opaque), `iam.rs`, `login.rs`, `flow_scratch.rs`, `project_plan/*` (features +off), `main.rs` (binary target), `workbook_delta/dt64/p21_lane_socket_lab.rs`. That is what +`SourceFilesUnread` reports, from `files.tsv` alone. Nothing was inserted into the store by hand. + +Raw query output is in `store-output/`. + +### Q1: the two `WorkbookSource` types + +```mermaid +flowchart LR + load["Projection::load_v1"] -->|"CONFIRMED projection.rs:409"| new["source_fake::WorkbookSource::new"] + load -->|"CONFIRMED projection.rs:408"| lpull["Ledger::pull"] + into["source_graph::pull_into"] -->|"CONFIRMED source_graph.rs:357"| lpull + lpull -->|"UNKNOWN dyn Source, source.rs:333"| fpull["source_fake impl Source::pull"] + fpull -.->|IMPLEMENTS| spull["Source::pull"] + lpull -->|"CONFIRMED source.rs:334"| ingest["Ledger::ingest"] + poll["workbook_delta WorkbookSource::poll"] -.-|"0 callers in lib; tests, examples, app, main unread"| gap(("UNOBSERVED")) +``` + +- Confirmed: two identities, `report_rs::source_fake::WorkbookSource` and + `report_rs::workbook_delta::source::WorkbookSource`; only the first implements `Source`. + `Ledger::pull` calls `Ledger::ingest` (source.rs:334). `Projection::load_v1` builds the + `source_fake` source (projection.rs:409) and passes it to `Ledger::pull`. +- Possible / unknown: `Ledger::pull` reaches `source_fake::pull` only through `&mut dyn Source` + (source.rs:333). The compiler does not name that target, so the store reports UNKNOWN, not an edge. +- Absent in scope: `poll` has no caller in the library target with default features, and no path + from it reaches `Ledger::ingest`. Gaps: tests and examples not extracted, `crate::app` opaque, + `main.rs` unread, the symbol is public. +- Falsifier: one `src/` call of `WorkbookSource::poll` whose result reaches `Ledger::ingest` + (for example an `impl Source` for the delta type) turns this into a confirmed edge on re-import. + +### Q2: authorization + +`lance_graph_rbac` symbols are missing with `owner_stored: false`; `report_rs::iam::*` is missing +with `SourceFilesUnread` naming `src/iam.rs`. The store therefore cannot say whether report-rs +authorizes: the module that would do it was not compiled. Falsifier: re-extract with +`--features iam` and query `iam` callers. + +### Q3: map persistence + +No `lance_graph_dt64_lance` symbol in scope. `IdentityFrame::commit` calls +`lance_graph_dt64::dr::MapTable::advance` (frame.rs:195), CONFIRMED. Whether report-rs depends on +`lance-graph-dt64-lance` is a manifest fact the store does not hold; the store answer is +"absent in scope". Falsifier: a `MapLog` call in any compiled file. + +## 3. Graded comparison (Gate D) + +Two blind arms on the same model, the same questions (`questions.md`) and the same revision. +Arm M read source only. Arm C queried the store with `cg_query` and read source only at lines the +store printed. Grading against `answer-key.md`, strict: a materially false statement is WRONG even +with a coverage disclaimer. Full grades in `GRADES.tsv`; answers in `answers/`. + +| | correct | partial | unsupported | wrong | tool calls | elapsed s | tokens | +|---|---|---|---|---|---|---|---| +| M (source) | 12 | 0 | 0 | 0 | 13 | 71.0 | 456,784 | +| C (store) | 7 | 3 | 2 | 0 | 8 | 59.8 | 456,309 | + +The token counts are dominated by the shared session context both arms load, so they do not +separate the arms. n = 1 per arm; this is an observation, not a ranking. + +Where the store was weaker, and why: + +- **Build configuration.** Source text includes `#[cfg(feature = "iam")]` code; the store holds + one configuration. K2.1 (the `authorize_memberships` call) is visible only to arm M. +- **Targets.** The store holds the library target, so the test and example callers of `poll` + (K1.5) are unobserved. Arm C reported the gap; it did not name the callers. +- **Manifest facts.** "report-rs does not depend on dt64-lance" (K3.1, K3.3) comes from + Cargo.toml, which the store does not read. +- **Definition lines.** The store records function spans, not struct lines (K1.1). + +Where the store was stronger: arm C's `Ledger::pull → source_fake::pull` is reported UNKNOWN +(dynamic dispatch) instead of asserted, and every absence it states carries its scope. Arm M's +text search is feature-blind in both directions: it saw the `iam` call, and it would equally have +reported a cfg-dead call as live. + +Acceptance (brief): the store independently recovers the first #33 missing-integration finding, +explains it correctly, and reports what it cannot prove. Met. + +## 4. #2000 checks + +- The PR description, REPORT.md §4 and `recon.py --self-test` all give 15 tests; the self-test + passes. +- CI at the head (`90fc5a7`) and the merge (`317c4ff`) is green on every workflow. +- Reproduction from the documented commands, in a fresh worktree at `317c4ff` with sibling ndarray + at `fd3d2e7`: rows per crate equal REPORT.md's table (represented + 3), `machine-recovered.mmd` + is byte-identical, and the Charon column of `score.tsv` is identical (61 HIT, 26 MISS, + 32 UNOBSERVED). The rust-analyzer column was not re-run. + +## 5. Open + +- Feature and target matrices: one store per configuration, merged, would close K1.5 and K2.1. + Charon needs `crate::app` opaque at 15 GB. +- `RegionsExcluded` and `Targets` are declared by the caller. The extractor could record both in + the store (they are its own arguments), which would turn them into store facts. +- `SourceFilesUnread` scans the top directory of each recorded path; files recorded at the source + root trigger no scan. diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/answer-key.md b/.claude/probes/2026-11-11-codegraph-recon-2/answer-key.md new file mode 100644 index 000000000..3a86f7b21 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/answer-key.md @@ -0,0 +1,45 @@ +# Held-out answer key — D-CODEGRAPH-RECON-2 Gate B/D + +Source: EXO-185 manual findings (2026-11-10/11), re-checked by hand against +report-rs `81705d9` (PR #33 head). This file is NOT an input to any store and +is never shown to an arm before grading. + +## Q1 — the two `WorkbookSource` types (EXO-185 loose end A) + +K1.1 Two distinct identities: + - `report_rs::source_fake::WorkbookSource` (src/source_fake.rs:19) + - `report_rs::workbook_delta::source::WorkbookSource` (src/workbook_delta/source.rs:210) +K1.2 Only `source_fake::WorkbookSource` implements `report_rs::source::Source` + (src/source_fake.rs:29); its `pull` builds an `IngestBatch` (source_fake.rs:39, :61). +K1.3 `workbook_delta::source::WorkbookSource` has an inherent `poll` + (workbook_delta/source.rs:292) returning `Poll` (`Unchanged` | `Changed(VerifiedSnapshot)`); + it has no `Source` impl and builds no `IngestBatch`. +K1.4 `Ledger::pull(&mut dyn Source, _)` (src/source.rs:331) calls `Source::pull` (dynamic) + and `Ledger::ingest` (source.rs:334). The lib's only `Ledger::pull` caller with a + workbook source is `projection.rs:409`, passing `source_fake::WorkbookSource::new`. +K1.5 Missing integration: no lib (`src/`) code calls `workbook_delta::...::WorkbookSource::poll`. + Its only caller is `tests/p20_workbook_delta.rs:304`, which feeds `Workbook::ingest` + (tests/p20:308), not the ledger. So the real SharePoint puller never reaches + `Ledger::ingest`. Absence scope: all of `src/` and `tests/` at 81705d9, default features. +K1.6 Correct framing: the edge `poll → IngestBatch/Ledger::ingest` is ABSENT within the + lib target; test callers exist (p20). Claiming "poll has no callers at all" is FALSE. + +## Q2 — reader scope (EXO-185 loose end B, ledger item 3) + +K2.1 report-rs calls `lance_graph_rbac::authorize::authorize_memberships` only from + `src/iam.rs:250`, and `iam` is behind feature `iam` (src/lib.rs:22-23; Cargo.toml:107), + OFF by default. +K2.2 No call to `authorize_scoped` anywhere in report-rs `src/` or `tests/` at 81705d9. +K2.3 Correct framing for a default-features extraction: the `iam` module is UNOBSERVED + (not compiled), so "report-rs never authorizes" is FALSE; "no `authorize_scoped` call" + needs either the iam feature extracted or a source scope check. + +## Q3 — MapLog / value persistence (EXO-185 loose end C, ledger 5a/5b) + +K3.1 report-rs does not depend on `lance-graph-dt64-lance` (Cargo.toml: only + `lance-graph-dt64`, line 46); no `MapLog` use in src/ or tests/. +K3.2 DR identity lives in memory: `IdentityFrame` holds a `MapTable` + (src/workbook_delta/frame.rs:56), advanced in `IdentityFrame::commit` + (frame.rs:189, `self.table.advance(` at :195). +K3.3 Correct framing: the store cannot see crates report-rs does not depend on; "no + MapLog call" is a dependency-scope fact (Cargo.toml), not a call-graph absence. diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/answers/armC.md b/.claude/probes/2026-11-11-codegraph-recon-2/answers/armC.md new file mode 100644 index 000000000..0bfac3131 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/answers/armC.md @@ -0,0 +1,29 @@ +# Arm C answers (Charon graph, report-rs 81705d9; scope S = lib target, default features, crate::app opaque) +Scope S, stated once: report_rs lib target only (tests/examples/benches NOT extracted); region crate::app opaque; features lance,iam,flow,oidc,projects,projects-pg off. Unread files per GAP: src/app.rs, src/app/plan_routes.rs, src/flow_scratch.rs, src/iam.rs, src/login.rs, src/main.rs, src/project_plan/*, src/workbook_delta/dt64/p21_lane_socket_lab.rs. External consumers of public items are UNOBSERVED. Harvest has 1 residual (HarvestIncomplete). + +## Q1 +a. Two types, identified by graph module paths: + - report_rs::source_fake::WorkbookSource (non-generic; constructor `source_fake::WorkbookSource::new`) + - report_rs::workbook_delta::source::WorkbookSource (generic over a transport T; has new/into_transport/token/meta/poll) + Defining file:line: UNKNOWN from the graph (it prints no def lines; I did not read source at unprinted locations). Files by module path: src/source_fake.rs and src/workbook_delta/source.rs. Witness inside the first: src/source_fake.rs:39 (the `fn pull` in the Source impl). + CONFIRMED (identities), UNKNOWN (def lines). +b. source_fake::WorkbookSource implements Source (impl_Source_for_WorkbookSource::{id,name,lanes,pull} + vtable shim; src/source_fake.rs:39). The workbook_delta WorkbookSource has NO impl_Source_for_* symbol in scope S: ABSENT-IN-SCOPE (scope S). +c. Edges (all CONFIRMED, scope S): + - Ledger::pull -> Ledger::ingest: src/source.rs:334 (`self.ingest(batch)` on Ok). + - Ledger::replay -> Ledger::ingest: src/source.rs:357. + - projection::record_artifact -> Ledger::ingest: src/projection.rs:845, :852. + - Projection::load_v1 -> Ledger::pull: src/projection.rs:408, :413, :416; load_v1 -> source_fake::WorkbookSource::new: src/projection.rs:409. + - source_graph::pull_into -> Ledger::pull: src/source_graph.rs:357; load_v1 -> pull_into: src/projection.rs:429. + - Source::pull for source_fake::WorkbookSource: only edge is its vtable method (src/source_fake.rs:39); callers are dynamic dispatch via Ledger::pull, reported UNKNOWN by the graph (trait-object call, not resolved to the impl). + - IngestBatch: constructed/consumed by pull (return type), ingest, status/last_watermark/values closures and rules::source_basis closures; no separate "IngestBatch edge" witnessed beyond those symbols. + - Separate, different ingest: workbook_delta::ingest::Workbook::ingest, which calls IdentityFrame::commit (src/workbook_delta/ingest.rs:264); IdentityFrame::new called from Workbook::open (src/workbook_delta/ingest.rs:117). This is NOT Ledger::ingest. + CONFIRMED. +d. workbook_delta WorkbookSource::poll has 0 callers in scope S (sites=0); its callees are meta/token/item_url/sha256_hex/status_class and ReqwestDrive::get (POSSIBLE). No edge from poll (or from WorkbookSource::new, 0 refs) to Ledger::ingest or Workbook::ingest; Workbook::ingest also has 0 callers in S. Answer: ABSENT-IN-SCOPE for library code in S. Cannot say absent overall: poll/new/Workbook::ingest are PUBLIC (external callers UNOBSERVED), tests/examples not extracted, src/app.rs (opaque) and src/main.rs unread, and the p21 lab file unread, so a caller there is UNOBSERVED. +e. Scopes: as per header S for every "no caller/no edge" statement (Q1b, Q1d). + +## Q2 +Graph has no symbol containing authoriz, rbac, memberships, or lance_graph_rbac in the extracted scope, so no call to authorize_memberships / authorize_scoped appears: ABSENT-IN-SCOPE under scope S. Only unrelated names found (Ledger::register_scoped, Projection::scoped). The most likely home, src/iam.rs, is unread and feature iam is off, so under the `iam` feature (or in src/app.rs, opaque) the answer is UNOBSERVED. Witnesses: none (absence). Build configuration with a CONFIRMED call: none observed. + +## Q3 +Part 1, persistence through lance-graph-dt64-lance / MapLog: no symbol matching dt64_lance, lance_graph_dt64_lance, or MapLog: ABSENT-IN-SCOPE (scope S; features lance and others off, tests/examples not extracted, p21 lab file unread). Whether it happens under feature `lance` is UNOBSERVED. +Part 2, where the MapTable is held/advanced (CONFIRMED, scope S): lance_graph_dt64::dr::MapTable is held in the identity frame, workbook_delta::frame::IdentityFrame: MapTable::new(0,0) at src/workbook_delta/frame.rs:69 (via IdentityFrame::new, also from Default at :62), seal at src/workbook_delta/frame.rs:101, advance at src/workbook_delta/frame.rs:195 inside IdentityFrame::commit. commit is called by Workbook::ingest (src/workbook_delta/ingest.rs:264); Workbook::open builds the frame (src/workbook_delta/ingest.rs:117). The in-memory table is not persisted by any edge in S. Callers of Workbook::ingest: none in S (see Q1d), so the advance path is reached from library code only if an unobserved caller exists. diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/answers/armM.md b/.claude/probes/2026-11-11-codegraph-recon-2/answers/armM.md new file mode 100644 index 000000000..600356ce3 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/answers/armM.md @@ -0,0 +1,36 @@ +# Arm M answers (report-rs @ /home/user/rr-81705d9) + +Scope notes: default features = `default = []` (Cargo.toml `[features]`). Searched all `*.rs` under src/, tests/, examples/ (and Cargo.toml, Cargo.lock, Dockerfiles, docs/*.md for Q2/Q3). Only lib crate (src/lib.rs) and bin src/main.rs exist (no src/bin/); no workspace members. + +## Q1 +a. Two `WorkbookSource` types: + - `report_rs::source_fake::WorkbookSource` — src/source_fake.rs:19 (`pub struct WorkbookSource { fixture: Fixture }`). + - `report_rs::workbook_delta::source::WorkbookSource` — src/workbook_delta/source.rs:210 (`pub struct WorkbookSource { cfg, transport }`). Module declared at src/lib.rs:48 (`pub mod workbook_delta;`), `pub mod source;` in src/workbook_delta/mod.rs. + CONFIRMED. + +b. Only `source_fake::WorkbookSource` implements `report_rs::source::Source`: src/source_fake.rs:29 `impl Source for WorkbookSource`. The trait is src/source.rs:171. The workbook_delta type has only inherent impls (src/workbook_delta/source.rs:215 `impl WorkbookSource`); grep of "Source for" / "IngestBatch" / "Ledger" across src/workbook_delta/** found no `Source` trait impl (only an unrelated `LaneSource` in src/workbook_delta/dt64/p21_lane_socket_lab.rs:188 and dt64.rs). CONFIRMED (the delta type is not a `Source`); scope: src/workbook_delta/*.rs, src/workbook_delta/dt64/*.rs, all of src/. + +c. Edges: + - `Source::pull` declared src/source.rs:180 (`fn pull(&mut self, since: Option, now_ms: i64) -> Result`); returns `IngestBatch` (struct src/source.rs:135). Implemented at src/source_fake.rs:39 (workbook fake; builds `IngestBatch{..}`), 107, 188 (other fakes), src/source_graph.rs:257. + - `Ledger` struct src/source.rs:259; `Ledger::ingest(&mut self, batch: IngestBatch)` src/source.rs:302. + - `Ledger::pull(&mut self, src: &mut dyn Source, now_ms)` src/source.rs:330 calls `src.pull(since, now_ms)` (333) and on Ok `self.ingest(batch)` (334). This is the pull->IngestBatch->ingest edge. + - Callers of `Ledger::pull`: src/projection.rs:409 (`.pull(&mut WorkbookSource::new(base.clone()), now_ms)` using source_fake::WorkbookSource, import at projection.rs:10), 414, 417 (fake sharepoint/spear); src/source_graph.rs:357 (`ledger.pull(src, now_ms)` in `pull_into`); many tests (e.g. tests/p2_scope.rs:32). + - Other direct `Ledger::ingest` callers: src/projection.rs:845, 852 (mapping state batches); src/source.rs:357. (src/gov/mod.rs:48 / src/gov/observation.rs:263 are a different `ingest` on a different gov ledger type with `LicSnapshot`, not `source::Ledger`.) + - `poll`: only defined at src/workbook_delta/source.rs:292 (`WorkbookSource::poll(&mut self, last_etag, now_ms) -> Result`); it returns `Poll`, not `IngestBatch`. + - Delta-side landing is `workbook_delta::ingest::Workbook::ingest(&mut self, snap: &VerifiedSnapshot) -> Outcome` (src/workbook_delta/ingest.rs:161), a distinct method, not `Ledger::ingest`. + CONFIRMED. + +d. Does workbook_delta source reach `Ledger::ingest` from library code? No edge found. Callers of the delta `poll`: examples/workbook_sync.rs:37 (`src.poll(wb.last_etag(), now)`, then `wb.ingest(&snap)` at :46 which is `Workbook::ingest`), tests/p20_workbook_delta.rs:304,311,331,350. No call of `.poll(` anywhere in src/ outside its definition. Nothing in src/ outside src/workbook_delta references `workbook_delta` except `pub mod workbook_delta;` (src/lib.rs:48), and nothing in src/workbook_delta references `IngestBatch`/`source::Ledger`. So library code never calls delta `poll` and the delta source never reaches `source::Ledger::ingest`. ABSENT-IN-SCOPE. + +e. Scope for each "no edge / no caller": grep `-rn "poll("`, `"IngestBatch"` (files containing it: src/source_graph.rs, source_fake.rs, projection.rs, source.rs, tests/p3_evidence.rs, tests/p3b_delta.rs), `"workbook_delta"`, `"Workbook::open"` over all *.rs in src/, tests/, examples/ (src/main.rs, src/app.rs, src/app/** included); features: default (none) — and the grep is feature-agnostic (cfg-gated code is still text-searched, none of these hits are cfg-gated). Not examined: external crates (git deps), dynamic dispatch/macros beyond text grep. A grep with no hits is navigation only; I opened src/workbook_delta/mod.rs, source.rs (210-300), ingest.rs (1-125,150-165,260) to confirm the doc says the delta source "returns a verified snapshot" landed via `Workbook::ingest`. + +## Q2 +Yes, but only when feature `iam` is on. `authorize_memberships`: src/iam.rs:21 `use lance_graph_rbac::authorize::authorize_memberships;` and call at src/iam.rs:250 inside `LanceGraphScope::decide_in` (impl at src/iam.rs:243). `authorize_scoped`: no occurrence anywhere (grep of whole repo, *.rs/*.toml/*.md): ABSENT. +Build gating: `pub mod iam;` is `#[cfg(feature = "iam")]` (src/lib.rs:22-23); `lance-graph-rbac` is `optional = true` and enabled only via `iam = ["dep:lance-graph-rbac", ...]`; `lance = ["iam","oidc"]` (Cargo.toml [features]). Reach from app: src/scope.rs:563-566 `authority()` under `#[cfg(feature = "iam")]` constructs `crate::iam::LanceGraphScope::new` (src/scope.rs:566); `#[cfg(not(feature="iam"))]` arm (568) uses `StaticScope`. `authority` is called at src/app.rs:562, 752 etc. Dockerfile:36 builds `--features lance`; Dockerfile.standalone:18 has no rbac. +- authorize_memberships: CONFIRMED under `--features iam` (or `lance`); ABSENT in default-feature build (module not compiled). +- authorize_scoped: ABSENT-IN-SCOPE (all *.rs, Cargo.toml, docs, tests, examples searched; features irrelevant as no text hit). +Also tests/p33_intake.rs:263 only mentions lance_graph_rbac in a test name. + +## Q3 +No. There is no use of `lance-graph-dt64-lance` or `MapLog` anywhere: grep for "dt64-lance|dt64_lance|MapLog" over *.rs, *.toml, *.md, Dockerfiles, Cargo.lock found nothing (Cargo.toml dependencies list only `lance-graph-dt64` (git, main), not a `-lance` crate; Cargo.lock has `lance-graph-dt64` at line 1366 only). ABSENT-IN-SCOPE (all features; text-wide). +Identity `MapTable` (from `lance_graph_dt64::dr`) is held in memory in `IdentityFrame { table: MapTable, tiles }` (src/workbook_delta/frame.rs:55-57, constructed `MapTable::new(0, 0)` at :69) and advanced by `IdentityFrame::commit` calling `self.table.advance(source, 0, ...)` (src/workbook_delta/frame.rs:189-203). `IdentityFrame` is a field of `workbook_delta::ingest::Workbook` (src/workbook_delta/ingest.rs:99, built at :117 in `Workbook::open`); advance occurs at ingest.rs:264 `self.frame.commit(u64::from(number), fplan)`. Planning (`plan`, frame.rs:131) advances nothing. Persistence explicitly absent: src/workbook_delta/ingest.rs:11-16 ("Persistence is not here ... It writes no file and opens no dataset"). `Workbook::open` callers are only examples/ and tests/ (examples/workbook_sync.rs:26, workbook_head_to_head.rs:183, workbook_bench.rs:21, tests/p20_workbook_delta.rs:47,635,651); no src/ caller outside the module. CONFIRMED (in-memory only) / persistence ABSENT-IN-SCOPE. diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/questions.md b/.claude/probes/2026-11-11-codegraph-recon-2/questions.md new file mode 100644 index 000000000..3210137a5 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/questions.md @@ -0,0 +1,12 @@ +# Questions (report-rs at /home/user/rr-81705d9, commit 81705d9, default cargo features) + +Q1. The crate defines two types named `WorkbookSource`. + a. Give the fully qualified identity and defining file:line of each. + b. Which of them implements `report_rs::source::Source`? + c. Trace `poll`, `Source::pull`, `IngestBatch` and `Ledger::ingest`: which edges exist, with file:line witnesses? + d. Does the workbook_delta (SharePoint drive) source reach `Ledger::ingest` from library code? Who calls its `poll`? + e. For every "no edge / no caller" statement, state the scope you examined (files, targets, features). +Q2. Does report-rs call `lance_graph_rbac::authorize::authorize_memberships` or `authorize_scoped`? Under which build configuration? Give witnesses and scope. +Q3. Does report-rs persist DR identity through `lance-graph-dt64-lance` (`MapLog`)? Where is the identity `MapTable` held and advanced? Give witnesses and scope. + +Answer format: for each sub-question, a short statement, then CONFIRMED / ABSENT-IN-SCOPE / UNOBSERVED, then witnesses (file:line), then scope. Say UNKNOWN rather than guess. diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/fake_new.refs b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/fake_new.refs new file mode 100644 index 000000000..34e097722 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/fake_new.refs @@ -0,0 +1,2 @@ +ref CALLS_RESOLVED report_rs::projection::{Projection}::load_v1 src/projection.rs:409 +sites confirmed=1 possible=0 diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/identityframe_commit.callees b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/identityframe_commit.callees new file mode 100644 index 000000000..6443bc91b --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/identityframe_commit.callees @@ -0,0 +1,10 @@ +callees CONFIRMED alloc::vec::impl_Deref_for_Vec::deref +callees CONFIRMED alloc::vec::impl_IntoIterator_for_Vec::into_iter +callees CONFIRMED alloc::vec::{Vec[TraitClause0, TraitClause1, TraitClause2]}::push +callees CONFIRMED alloc::vec::{impl IntoIterator for &'a Vec[TraitClause0, TraitClause1, TraitClause2]}::into_iter +callees CONFIRMED core::iter::traits::iterator::Iterator::collect +callees CONFIRMED core::iter::traits::iterator::Iterator::map +callees CONFIRMED core::slice::iter::{impl Iterator for core::slice::iter::Iter<'a, T>[TraitClause0]}::next +callees CONFIRMED core::slice::{[T]}::contains +callees CONFIRMED lance_graph_dt64::dr::{MapTable}::advance +sites 9 diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.callees b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.callees new file mode 100644 index 000000000..45aa1a09e --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.callees @@ -0,0 +1,7 @@ +callees CONFIRMED core::result::{Result[TraitClause0, TraitClause1]}::map +callees CONFIRMED report_rs::source::{report_rs::source::Ledger}::ingest +callees CONFIRMED report_rs::source::{report_rs::source::Ledger}::last_watermark +callees CONFIRMED report_rs::source::{report_rs::source::Ledger}::record_failure +callees CONFIRMED report_rs::source::{report_rs::source::Ledger}::register_scoped +callees UNKNOWN ?dynamic +sites 5 diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.callers b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.callers new file mode 100644 index 000000000..d3f09cfee --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.callers @@ -0,0 +1,4 @@ +callers CONFIRMED report_rs::projection::{Projection}::load_v1 +callers CONFIRMED report_rs::source_graph::pull_into +sites 4 +callers UNKNOWN external-callers-unobserved report_rs::source::{report_rs::source::Ledger}::pull is PUBLIC diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.refs b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.refs new file mode 100644 index 000000000..6273aa05d --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/ledger_pull.refs @@ -0,0 +1,5 @@ +ref CALLS_RESOLVED report_rs::source_graph::pull_into src/source_graph.rs:357 +ref CALLS_RESOLVED report_rs::projection::{Projection}::load_v1 src/projection.rs:408 +ref CALLS_RESOLVED report_rs::projection::{Projection}::load_v1 src/projection.rs:413 +ref CALLS_RESOLVED report_rs::projection::{Projection}::load_v1 src/projection.rs:416 +sites confirmed=4 possible=0 diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.authorize_memberships.report b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.authorize_memberships.report new file mode 100644 index 000000000..72e2a85f8 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.authorize_memberships.report @@ -0,0 +1,2 @@ +symbol MISSING owner_stored=false lance_graph_rbac::authorize::authorize_memberships +closed_in_scope false diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.maplog.report b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.maplog.report new file mode 100644 index 000000000..42f51924e --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.maplog.report @@ -0,0 +1,2 @@ +symbol MISSING owner_stored=false lance_graph_dt64_lance::MapLog +closed_in_scope false diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.report_rs_iam_authorize.report b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.report_rs_iam_authorize.report new file mode 100644 index 000000000..ed64b7a1b --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/missing.report_rs_iam_authorize.report @@ -0,0 +1,5 @@ +symbol MISSING owner_stored=true report_rs::iam::authorize +GAP TargetsNotExtracted { krate: "report_rs", missing: Targets { lib: false, tests: true, examples: true, benches: true } } +GAP RegionsExcluded { krate: "report_rs", regions: ["opaque:crate::app", "features-off:lance,iam,flow,oidc,projects,projects-pg"] } +GAP SourceFilesUnread { krate: "report_rs", files: ["src/app.rs", "src/app/plan_routes.rs", "src/flow_scratch.rs", "src/iam.rs", "src/login.rs", "src/main.rs", "src/project_plan/calendar.rs", "src/project_plan/engine.rs", "src/project_plan/mod.rs", "src/project_plan/pg.rs", "src/project_plan/projection.rs", "src/project_plan/store.rs", "src/project_plan/view.rs", "src/workbook_delta/dt64/p21_lane_socket_lab.rs"] } +closed_in_scope false diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/poll.callers b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/poll.callers new file mode 100644 index 000000000..7d615582b --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/poll.callers @@ -0,0 +1,2 @@ +sites 0 +callers UNKNOWN external-callers-unobserved report_rs::workbook_delta::source::{report_rs::workbook_delta::source::WorkbookSource[TraitClause0, TraitClause1]}::poll is PUBLIC diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/poll.report b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/poll.report new file mode 100644 index 000000000..b0bc6a00f --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/poll.report @@ -0,0 +1,7 @@ +symbol FOUND 3615 report_rs::workbook_delta::source::{report_rs::workbook_delta::source::WorkbookSource[TraitClause0, TraitClause1]}::poll +GAP ExternalConsumersUnobserved { owner: "report_rs", observed_consumers: [] } +GAP TargetsNotExtracted { krate: "report_rs", missing: Targets { lib: false, tests: true, examples: true, benches: true } } +GAP RegionsExcluded { krate: "report_rs", regions: ["opaque:crate::app", "features-off:lance,iam,flow,oidc,projects,projects-pg"] } +GAP HarvestIncomplete { krate: "report_rs", residuals: ResidualCounts([0, 0, 1, 0, 0]), partial: false, no_residuals_file: false } +GAP SourceFilesUnread { krate: "report_rs", files: ["src/app.rs", "src/app/plan_routes.rs", "src/flow_scratch.rs", "src/iam.rs", "src/login.rs", "src/main.rs", "src/project_plan/calendar.rs", "src/project_plan/engine.rs", "src/project_plan/mod.rs", "src/project_plan/pg.rs", "src/project_plan/projection.rs", "src/project_plan/store.rs", "src/project_plan/view.rs", "src/workbook_delta/dt64/p21_lane_socket_lab.rs"] } +closed_in_scope false diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/pull.callers b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/pull.callers new file mode 100644 index 000000000..72bd19dca --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/pull.callers @@ -0,0 +1,10 @@ +callers CONFIRMED report_rs::source_fake::impl_Source_for_WorkbookSource::pull::{vtable_method} +callers UNKNOWN report_rs::mapping_hydrate::hydrate_artifact +callers UNKNOWN report_rs::mapping_hydrate::publish_artifact +callers UNKNOWN report_rs::mapping_hydrate::publish_artifact::{impl Fn<(&'_2 str, &'_3 [u8], &'_4 str)> for report_rs::mapping_hydrate::publish_artifact::{closure}<'_0, '_1>}::call +callers UNKNOWN report_rs::mapping_hydrate::repoint +callers UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::fetch_manifest +callers UNKNOWN report_rs::rules::plan::{impl FnMut<(&'_2 Box<(dyn Rule + '_3), Global>[{built_in impl MetaSized for (dyn Rule + '_3)}, {built_in impl Sized for Global}, impl_Allocator_for_Global],)> for report_rs::rules::plan::{closure}<'_0, '_1>}::call_mut +callers UNKNOWN report_rs::source::{report_rs::source::Ledger}::pull +sites 1 +callers UNKNOWN external-callers-unobserved report_rs::source_fake::impl_Source_for_WorkbookSource::pull is PUBLIC diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/pull.report b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/pull.report new file mode 100644 index 000000000..dade573a9 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/pull.report @@ -0,0 +1,110 @@ +symbol FOUND 1717 report_rs::source_fake::impl_Source_for_WorkbookSource::pull +impact CONFIRMED report_rs::source_fake::impl_Source_for_WorkbookSource::pull::{vtable_method} +impact UNKNOWN report_rs::cli::run +impact UNKNOWN report_rs::cli::run::{impl FnOnce<(S3Client,)> for report_rs::cli::run::{closure#3}<'_0>}::call_once +impact UNKNOWN report_rs::cli::store +impact UNKNOWN report_rs::fixture::{ReportType}::within::{impl FnMut<(&'_1 &'_2 str,)> for report_rs::fixture::{ReportType}::within::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::fixture::{ReportType}::within::{impl FnOnce<(&'_1 &'_2 str,)> for report_rs::fixture::{ReportType}::within::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::lance_adapter::parity +impact UNKNOWN report_rs::mapping_hydrate::hydrate +impact UNKNOWN report_rs::mapping_hydrate::hydrate_artifact +impact UNKNOWN report_rs::mapping_hydrate::hydrate_artifact::{impl FnOnce<(Pointer,)> for report_rs::mapping_hydrate::hydrate_artifact::{closure}<'_0, '_1, T>[TraitClause0, TraitClause1]}::call_once +impact UNKNOWN report_rs::mapping_hydrate::hydrate_from_env +impact UNKNOWN report_rs::mapping_hydrate::hydrate_kind_from_env +impact UNKNOWN report_rs::mapping_hydrate::publish +impact UNKNOWN report_rs::mapping_hydrate::publish_artifact +impact UNKNOWN report_rs::mapping_hydrate::publish_artifact::{impl Fn<(&'_2 str, &'_3 [u8], &'_4 str)> for report_rs::mapping_hydrate::publish_artifact::{closure}<'_0, '_1>}::call +impact UNKNOWN report_rs::mapping_hydrate::publish_artifact::{impl FnMut<(&'_2 str, &'_3 [u8], &'_4 str)> for report_rs::mapping_hydrate::publish_artifact::{closure}<'_0, '_1>}::call_mut +impact UNKNOWN report_rs::mapping_hydrate::publish_artifact::{impl FnOnce<(&'_2 str, &'_3 [u8], &'_4 str)> for report_rs::mapping_hydrate::publish_artifact::{closure}<'_0, '_1>}::call_once +impact UNKNOWN report_rs::mapping_hydrate::repoint +impact UNKNOWN report_rs::mapping_hydrate::store_from_env +impact UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::fetch_manifest +impact UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::load_local +impact UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local +impact UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local::{impl Fn<()> for report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local::{closure}<'_0, '_1, '_2, '_3, '_4, '_5, '_6, T>[TraitClause0]}::call +impact UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local::{impl FnMut<()> for report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local::{closure}<'_0, '_1, '_2, '_3, '_4, '_5, '_6, T>[TraitClause0]}::call_mut +impact UNKNOWN report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local::{impl FnOnce<()> for report_rs::mapping_hydrate::{Ctx<'_0, T>[TraitClause0]}::publish_local::{closure}<'_0, '_1, '_2, '_3, '_4, '_5, '_6, T>[TraitClause0]}::call_once +impact UNKNOWN report_rs::mapping_hydrate::{HydrateConfig}::from_vars +impact UNKNOWN report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for +impact UNKNOWN report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{impl Fn<(&'_2 str,)> for report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{closure}<'_0, '_1, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call +impact UNKNOWN report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{impl FnMut<(&'_2 str,)> for report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{closure}<'_0, '_1, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{impl FnOnce<(&'_2 str,)> for report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{closure}<'_0, '_1, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{impl FnOnce<()> for report_rs::mapping_hydrate::{HydrateConfig}::from_vars_for::{closure#1}<'_0, '_1, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::mobile::render +impact UNKNOWN report_rs::objstore::{S3Config}::from_suffixed_env +impact UNKNOWN report_rs::objstore::{S3Config}::from_vars +impact UNKNOWN report_rs::objstore::{S3Config}::from_vars::{impl Fn<(&'_3 str,)> for report_rs::objstore::{S3Config}::from_vars::{closure}<'_0, '_1, '_2, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call +impact UNKNOWN report_rs::objstore::{S3Config}::from_vars::{impl FnMut<(&'_3 str,)> for report_rs::objstore::{S3Config}::from_vars::{closure}<'_0, '_1, '_2, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::objstore::{S3Config}::from_vars::{impl FnOnce<(&'_3 str,)> for report_rs::objstore::{S3Config}::from_vars::{closure}<'_0, '_1, '_2, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::oracle::summary +impact UNKNOWN report_rs::oracle::summary_where +impact UNKNOWN report_rs::oracle::summary_where::{closure}::{impl FnMut<(&'_1 &'_2 report_rs::fixture::Customer,)> for report_rs::oracle::summary_where::{closure}::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::oracle::summary_where::{closure}::{impl FnOnce<(&'_1 &'_2 report_rs::fixture::Customer,)> for report_rs::oracle::summary_where::{closure}::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::projection::labels_for +impact UNKNOWN report_rs::projection::{Projection}::load_v1 +impact UNKNOWN report_rs::projection::{Projection}::parity +impact UNKNOWN report_rs::projection::{Projection}::summary +impact UNKNOWN report_rs::rules::each_owed +impact UNKNOWN report_rs::rules::impl_Rule_for_ConfiguredButNoRun::propose +impact UNKNOWN report_rs::rules::impl_Rule_for_ConfiguredButNoRun::propose::{vtable_method} +impact UNKNOWN report_rs::rules::impl_Rule_for_DeliveredWithoutEvidence::propose +impact UNKNOWN report_rs::rules::impl_Rule_for_DeliveredWithoutEvidence::propose::{vtable_method} +impact UNKNOWN report_rs::rules::impl_Rule_for_EvidenceStale::propose +impact UNKNOWN report_rs::rules::impl_Rule_for_EvidenceStale::propose::{vtable_method} +impact UNKNOWN report_rs::rules::impl_Rule_for_OwedButNotConfigured::propose +impact UNKNOWN report_rs::rules::impl_Rule_for_OwedButNotConfigured::propose::{vtable_method} +impact UNKNOWN report_rs::rules::impl_Rule_for_RunFailed::propose +impact UNKNOWN report_rs::rules::impl_Rule_for_RunFailed::propose::{vtable_method} +impact UNKNOWN report_rs::rules::plan::{impl FnMut<(&'_2 Box<(dyn Rule + '_3), Global>[{built_in impl MetaSized for (dyn Rule + '_3)}, {built_in impl Sized for Global}, impl_Allocator_for_Global],)> for report_rs::rules::plan::{closure}<'_0, '_1>}::call_mut +impact UNKNOWN report_rs::rules::plan::{impl FnOnce<(&'_2 Box<(dyn Rule + '_3), Global>[{built_in impl MetaSized for (dyn Rule + '_3)}, {built_in impl Sized for Global}, impl_Allocator_for_Global],)> for report_rs::rules::plan::{closure}<'_0, '_1>}::call_once +impact UNKNOWN report_rs::rules::validate::{impl FnMut<(&'_6 Change,)> for report_rs::rules::validate::{closure#1}<'_0, '_1, '_2, '_3, '_4, '_5, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::rules::validate::{impl FnOnce<(&'_6 Change,)> for report_rs::rules::validate::{closure#1}<'_0, '_1, '_2, '_3, '_4, '_5, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::scope::decide_with_fallback::{impl FnMut<(&'_1 String,)> for report_rs::scope::decide_with_fallback::{closure#2}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::scope::decide_with_fallback::{impl FnMut<(&'_1 String,)> for report_rs::scope::decide_with_fallback::{closure#3}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::scope::decide_with_fallback::{impl FnOnce<(&'_1 String,)> for report_rs::scope::decide_with_fallback::{closure#2}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::scope::decide_with_fallback::{impl FnOnce<(&'_1 String,)> for report_rs::scope::decide_with_fallback::{closure#3}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::scope::{ActorSource}::from_env +impact UNKNOWN report_rs::scope::{ActorSource}::from_vars +impact UNKNOWN report_rs::scope::{StaticScope}::from_env +impact UNKNOWN report_rs::scope::{StaticScope}::from_vars +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::pull +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnMut<(&'_1 (report_rs::source::SourceId, IngestBatchId), &'_2 mut IngestBatch)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure}<'_0, T0>[TraitClause0, TraitClause1]}::call_mut +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnMut<(&'_1 SourceFailure,)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#1}<'_0, T0>[TraitClause0, TraitClause1]}::call_mut +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnMut<(&'_1 report_rs::source::SourceId, &'_2 mut BTreeSet[{built_in impl Sized for ObservationLane}, {built_in impl Sized for Global}, impl_AllocatorClone_for_Global])> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#2}<'_0, T0>[TraitClause0, TraitClause1]}::call_mut +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnMut<(&'_1 report_rs::source::SourceId, &'_2 mut SourceScope)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#3}<'_0, T0>[TraitClause0, TraitClause1]}::call_mut +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnMut<(&'_1 report_rs::source::SourceId, &'_2 mut String)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#4}<'_0, T0>[TraitClause0, TraitClause1]}::call_mut +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnOnce<(&'_1 (report_rs::source::SourceId, IngestBatchId), &'_2 mut IngestBatch)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure}<'_0, T0>[TraitClause0, TraitClause1]}::call_once +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnOnce<(&'_1 SourceFailure,)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#1}<'_0, T0>[TraitClause0, TraitClause1]}::call_once +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnOnce<(&'_1 report_rs::source::SourceId, &'_2 mut BTreeSet[{built_in impl Sized for ObservationLane}, {built_in impl Sized for Global}, impl_AllocatorClone_for_Global])> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#2}<'_0, T0>[TraitClause0, TraitClause1]}::call_once +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnOnce<(&'_1 report_rs::source::SourceId, &'_2 mut SourceScope)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#3}<'_0, T0>[TraitClause0, TraitClause1]}::call_once +impact UNKNOWN report_rs::source::{report_rs::source::Ledger}::retain_sources::{impl FnOnce<(&'_1 report_rs::source::SourceId, &'_2 mut String)> for report_rs::source::{report_rs::source::Ledger}::retain_sources::{closure#4}<'_0, T0>[TraitClause0, TraitClause1]}::call_once +impact UNKNOWN report_rs::source_graph::pull_into +impact UNKNOWN report_rs::source_graph::{GraphConfig}::from_env +impact UNKNOWN report_rs::source_graph::{GraphConfig}::from_vars +impact UNKNOWN report_rs::source_graph::{GraphConfig}::from_vars::{impl Fn<(&'_1 str,)> for report_rs::source_graph::{GraphConfig}::from_vars::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call +impact UNKNOWN report_rs::source_graph::{GraphConfig}::from_vars::{impl FnMut<(&'_1 str,)> for report_rs::source_graph::{GraphConfig}::from_vars::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::source_graph::{GraphConfig}::from_vars::{impl FnOnce<(&'_1 str,)> for report_rs::source_graph::{GraphConfig}::from_vars::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::source_graph::{GraphConfig}::lab_from_vars +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed::{impl Fn<(&'_4 Tool, &'_5 str)> for report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed::{closure}<'_0, '_1, '_2, '_3, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed::{impl FnMut<(&'_4 Tool, &'_5 str)> for report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed::{closure}<'_0, '_1, '_2, '_3, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed::{impl FnOnce<(&'_4 Tool, &'_5 str)> for report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_addressed::{closure}<'_0, '_1, '_2, '_3, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::rail_html_with +impact UNKNOWN report_rs::surface_fixture::{report_rs::surface_fixture::Surface}::tools_html +impact UNKNOWN report_rs::view::project::{impl FnMut<(&'_1 report_rs::view::Column,)> for report_rs::view::project::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::view::project::{impl FnOnce<(&'_1 report_rs::view::Column,)> for report_rs::view::project::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::view::{Actor}::from_vars +impact UNKNOWN report_rs::workbook_delta::source::{DriveConfig}::from_vars +impact UNKNOWN report_rs::workbook_delta::source::{DriveConfig}::from_vars::{impl Fn<(&'_1 str,)> for report_rs::workbook_delta::source::{DriveConfig}::from_vars::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call +impact UNKNOWN report_rs::workbook_delta::source::{DriveConfig}::from_vars::{impl FnMut<(&'_1 str,)> for report_rs::workbook_delta::source::{DriveConfig}::from_vars::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_mut +impact UNKNOWN report_rs::workbook_delta::source::{DriveConfig}::from_vars::{impl FnOnce<(&'_1 str,)> for report_rs::workbook_delta::source::{DriveConfig}::from_vars::{closure}<'_0, T0>[TraitClause0, for<'_0_1> TraitClause1<'_>]}::call_once +impact UNKNOWN report_rs::xlsx::export +impact UNKNOWN report_rs::xlsx::workbook +GAP ExternalConsumersUnobserved { owner: "report_rs", observed_consumers: [] } +GAP TargetsNotExtracted { krate: "report_rs", missing: Targets { lib: false, tests: true, examples: true, benches: true } } +GAP RegionsExcluded { krate: "report_rs", regions: ["opaque:crate::app", "features-off:lance,iam,flow,oidc,projects,projects-pg"] } +GAP UnresolvedDispatch { dynamic_calls: 17 } +GAP HarvestIncomplete { krate: "report_rs", residuals: ResidualCounts([0, 0, 1, 0, 0]), partial: false, no_residuals_file: false } +GAP SourceFilesUnread { krate: "report_rs", files: ["src/app.rs", "src/app/plan_routes.rs", "src/flow_scratch.rs", "src/iam.rs", "src/login.rs", "src/main.rs", "src/project_plan/calendar.rs", "src/project_plan/engine.rs", "src/project_plan/mod.rs", "src/project_plan/pg.rs", "src/project_plan/projection.rs", "src/project_plan/store.rs", "src/project_plan/view.rs", "src/workbook_delta/dt64/p21_lane_socket_lab.rs"] } +closed_in_scope false diff --git a/.claude/probes/2026-11-11-codegraph-recon-2/store-output/srcpull.report b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/srcpull.report new file mode 100644 index 000000000..145a5bdd9 --- /dev/null +++ b/.claude/probes/2026-11-11-codegraph-recon-2/store-output/srcpull.report @@ -0,0 +1,6 @@ +symbol FOUND 1718 report_rs::source::Source::pull +GAP TargetsNotExtracted { krate: "report_rs", missing: Targets { lib: false, tests: true, examples: true, benches: true } } +GAP RegionsExcluded { krate: "report_rs", regions: ["opaque:crate::app", "features-off:lance,iam,flow,oidc,projects,projects-pg"] } +GAP HarvestIncomplete { krate: "report_rs", residuals: ResidualCounts([0, 0, 1, 0, 0]), partial: false, no_residuals_file: false } +GAP SourceFilesUnread { krate: "report_rs", files: ["src/app.rs", "src/app/plan_routes.rs", "src/flow_scratch.rs", "src/iam.rs", "src/login.rs", "src/main.rs", "src/project_plan/calendar.rs", "src/project_plan/engine.rs", "src/project_plan/mod.rs", "src/project_plan/pg.rs", "src/project_plan/projection.rs", "src/project_plan/store.rs", "src/project_plan/view.rs", "src/workbook_delta/dt64/p21_lane_socket_lab.rs"] } +closed_in_scope false 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..bad656d91 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 be1efc44d1d322ae 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..c5e83d782 100644 --- a/.codegraph/crates/lance-graph-codegraph.index.md +++ b/.codegraph/crates/lance-graph-codegraph.index.md @@ -3,7 +3,7 @@ crate: lance-graph-codegraph path: crates/lance-graph-codegraph workspace: excluded -digest: bd209bed318ffbbc +digest: be1efc44d1d322ae evidence legend: ../index.md#evidence-legend Generated; the code is the truth. See ../index.md. @@ -39,52 +39,53 @@ Generated; the code is the truth. See ../index.md. - const P_OTHER [pub] — crates/lance-graph-codegraph/src/artifact.rs:62 CONFIRMED - fn pred_code [pub] — crates/lance-graph-codegraph/src/artifact.rs:78 CONFIRMED - fn digest [pub] — crates/lance-graph-codegraph/src/artifact.rs:98 CONFIRMED -- struct FastHasher [pub] — crates/lance-graph-codegraph/src/artifact.rs:112 CONFIRMED -- type FastBuild [pub] — crates/lance-graph-codegraph/src/artifact.rs:143 CONFIRMED -- struct Symbols [pub] — crates/lance-graph-codegraph/src/artifact.rs:148 CONFIRMED -- fn Symbols::intern [pub] — crates/lance-graph-codegraph/src/artifact.rs:155 CONFIRMED -- fn Symbols::get [pub] — crates/lance-graph-codegraph/src/artifact.rs:166 CONFIRMED -- fn Symbols::name [pub] — crates/lance-graph-codegraph/src/artifact.rs:171 CONFIRMED -- fn Symbols::len [pub] — crates/lance-graph-codegraph/src/artifact.rs:176 CONFIRMED -- fn Symbols::is_empty [pub] — crates/lance-graph-codegraph/src/artifact.rs:181 CONFIRMED -- fn Symbols::absorb [pub] — crates/lance-graph-codegraph/src/artifact.rs:188 CONFIRMED -- trait Interner [pub] — crates/lance-graph-codegraph/src/artifact.rs:204 CONFIRMED -- struct SymbolStage [pub] — crates/lance-graph-codegraph/src/artifact.rs:238 CONFIRMED -- struct StagedNames [pub] — crates/lance-graph-codegraph/src/artifact.rs:245 CONFIRMED -- fn SymbolStage<'a>::new [pub] — crates/lance-graph-codegraph/src/artifact.rs:252 CONFIRMED -- fn SymbolStage<'a>::added [pub] — crates/lance-graph-codegraph/src/artifact.rs:261 CONFIRMED -- fn SymbolStage<'a>::into_names [pub] — crates/lance-graph-codegraph/src/artifact.rs:266 CONFIRMED -- struct Lanes [pub] — crates/lance-graph-codegraph/src/artifact.rs:303 CONFIRMED -- fn Lanes::len [pub] — crates/lance-graph-codegraph/src/artifact.rs:335 CONFIRMED -- fn Lanes::is_empty [pub] — crates/lance-graph-codegraph/src/artifact.rs:340 CONFIRMED -- fn Lanes::predicate_name [pub] — crates/lance-graph-codegraph/src/artifact.rs:345 CONFIRMED -- fn Lanes::digest_of [pub] — crates/lance-graph-codegraph/src/artifact.rs:357 CONFIRMED -- fn Lanes::residuals_of [pub] — crates/lance-graph-codegraph/src/artifact.rs:370 CONFIRMED -- fn Lanes::set_residuals [pub] — crates/lance-graph-codegraph/src/artifact.rs:375 CONFIRMED -- fn Lanes::crates [pub] — crates/lance-graph-codegraph/src/artifact.rs:383 CONFIRMED -- fn Lanes::drop_crate [pub] — crates/lance-graph-codegraph/src/artifact.rs:389 CONFIRMED -- fn Lanes::append [pub] — crates/lance-graph-codegraph/src/artifact.rs:434 CONFIRMED -- enum ResidualKind [pub] — crates/lance-graph-codegraph/src/artifact.rs:460 CONFIRMED -- const ResidualKind::ALL [pub] — crates/lance-graph-codegraph/src/artifact.rs:477 CONFIRMED -- fn ResidualKind::name [pub] — crates/lance-graph-codegraph/src/artifact.rs:486 CONFIRMED -- struct ResidualCounts [pub] — crates/lance-graph-codegraph/src/artifact.rs:508 CONFIRMED -- fn ResidualCounts::of [pub] — crates/lance-graph-codegraph/src/artifact.rs:512 CONFIRMED -- fn ResidualCounts::total [pub] — crates/lance-graph-codegraph/src/artifact.rs:517 CONFIRMED -- fn ResidualCounts::add [pub] — crates/lance-graph-codegraph/src/artifact.rs:522 CONFIRMED -- enum ResidualRefusal [pub] — crates/lance-graph-codegraph/src/artifact.rs:531 CONFIRMED -- fn refuse_placeholders [pub] — crates/lance-graph-codegraph/src/artifact.rs:563 CONFIRMED -- const RESIDUAL_SUFFIX [pub] — crates/lance-graph-codegraph/src/artifact.rs:591 CONFIRMED -- fn read_residuals [pub] — crates/lance-graph-codegraph/src/artifact.rs:595 CONFIRMED -- const BIN_SUFFIX [pub] — crates/lance-graph-codegraph/src/artifact.rs:640 CONFIRMED -- enum CrateSource [pub] — crates/lance-graph-codegraph/src/artifact.rs:644 CONFIRMED -- fn crate_source [pub] — crates/lance-graph-codegraph/src/artifact.rs:653 CONFIRMED -- fn read_crate_text [pub] — crates/lance-graph-codegraph/src/artifact.rs:663 CONFIRMED -- fn read_crate [pub] — crates/lance-graph-codegraph/src/artifact.rs:668 CONFIRMED -- fn read_dir [pub] — crates/lance-graph-codegraph/src/artifact.rs:678 CONFIRMED -- fn read_bin_as [pub] — crates/lance-graph-codegraph/src/artifact.rs:727 CONFIRMED -- fn dispatch_target [pub] — crates/lance-graph-codegraph/src/artifact.rs:819 CONFIRMED -- fn read_text [pub] — crates/lance-graph-codegraph/src/artifact.rs:857 CONFIRMED -- fn read_text_as [pub] — crates/lance-graph-codegraph/src/artifact.rs:867 CONFIRMED +- fn fnv64_hex [pub] — crates/lance-graph-codegraph/src/artifact.rs:110 CONFIRMED +- struct FastHasher [pub] — crates/lance-graph-codegraph/src/artifact.rs:122 CONFIRMED +- type FastBuild [pub] — crates/lance-graph-codegraph/src/artifact.rs:153 CONFIRMED +- struct Symbols [pub] — crates/lance-graph-codegraph/src/artifact.rs:158 CONFIRMED +- fn Symbols::intern [pub] — crates/lance-graph-codegraph/src/artifact.rs:165 CONFIRMED +- fn Symbols::get [pub] — crates/lance-graph-codegraph/src/artifact.rs:176 CONFIRMED +- fn Symbols::name [pub] — crates/lance-graph-codegraph/src/artifact.rs:181 CONFIRMED +- fn Symbols::len [pub] — crates/lance-graph-codegraph/src/artifact.rs:186 CONFIRMED +- fn Symbols::is_empty [pub] — crates/lance-graph-codegraph/src/artifact.rs:191 CONFIRMED +- fn Symbols::absorb [pub] — crates/lance-graph-codegraph/src/artifact.rs:198 CONFIRMED +- trait Interner [pub] — crates/lance-graph-codegraph/src/artifact.rs:214 CONFIRMED +- struct SymbolStage [pub] — crates/lance-graph-codegraph/src/artifact.rs:248 CONFIRMED +- struct StagedNames [pub] — crates/lance-graph-codegraph/src/artifact.rs:255 CONFIRMED +- fn SymbolStage<'a>::new [pub] — crates/lance-graph-codegraph/src/artifact.rs:262 CONFIRMED +- fn SymbolStage<'a>::added [pub] — crates/lance-graph-codegraph/src/artifact.rs:271 CONFIRMED +- fn SymbolStage<'a>::into_names [pub] — crates/lance-graph-codegraph/src/artifact.rs:276 CONFIRMED +- struct Lanes [pub] — crates/lance-graph-codegraph/src/artifact.rs:313 CONFIRMED +- fn Lanes::len [pub] — crates/lance-graph-codegraph/src/artifact.rs:345 CONFIRMED +- fn Lanes::is_empty [pub] — crates/lance-graph-codegraph/src/artifact.rs:350 CONFIRMED +- fn Lanes::predicate_name [pub] — crates/lance-graph-codegraph/src/artifact.rs:355 CONFIRMED +- fn Lanes::digest_of [pub] — crates/lance-graph-codegraph/src/artifact.rs:367 CONFIRMED +- fn Lanes::residuals_of [pub] — crates/lance-graph-codegraph/src/artifact.rs:380 CONFIRMED +- fn Lanes::set_residuals [pub] — crates/lance-graph-codegraph/src/artifact.rs:385 CONFIRMED +- fn Lanes::crates [pub] — crates/lance-graph-codegraph/src/artifact.rs:393 CONFIRMED +- fn Lanes::drop_crate [pub] — crates/lance-graph-codegraph/src/artifact.rs:399 CONFIRMED +- fn Lanes::append [pub] — crates/lance-graph-codegraph/src/artifact.rs:444 CONFIRMED +- enum ResidualKind [pub] — crates/lance-graph-codegraph/src/artifact.rs:470 CONFIRMED +- const ResidualKind::ALL [pub] — crates/lance-graph-codegraph/src/artifact.rs:487 CONFIRMED +- fn ResidualKind::name [pub] — crates/lance-graph-codegraph/src/artifact.rs:496 CONFIRMED +- struct ResidualCounts [pub] — crates/lance-graph-codegraph/src/artifact.rs:518 CONFIRMED +- fn ResidualCounts::of [pub] — crates/lance-graph-codegraph/src/artifact.rs:522 CONFIRMED +- fn ResidualCounts::total [pub] — crates/lance-graph-codegraph/src/artifact.rs:527 CONFIRMED +- fn ResidualCounts::add [pub] — crates/lance-graph-codegraph/src/artifact.rs:532 CONFIRMED +- enum ResidualRefusal [pub] — crates/lance-graph-codegraph/src/artifact.rs:541 CONFIRMED +- fn refuse_placeholders [pub] — crates/lance-graph-codegraph/src/artifact.rs:573 CONFIRMED +- const RESIDUAL_SUFFIX [pub] — crates/lance-graph-codegraph/src/artifact.rs:601 CONFIRMED +- fn read_residuals [pub] — crates/lance-graph-codegraph/src/artifact.rs:605 CONFIRMED +- const BIN_SUFFIX [pub] — crates/lance-graph-codegraph/src/artifact.rs:650 CONFIRMED +- enum CrateSource [pub] — crates/lance-graph-codegraph/src/artifact.rs:654 CONFIRMED +- fn crate_source [pub] — crates/lance-graph-codegraph/src/artifact.rs:663 CONFIRMED +- fn read_crate_text [pub] — crates/lance-graph-codegraph/src/artifact.rs:673 CONFIRMED +- fn read_crate [pub] — crates/lance-graph-codegraph/src/artifact.rs:678 CONFIRMED +- fn read_dir [pub] — crates/lance-graph-codegraph/src/artifact.rs:688 CONFIRMED +- fn read_bin_as [pub] — crates/lance-graph-codegraph/src/artifact.rs:737 CONFIRMED +- fn dispatch_target [pub] — crates/lance-graph-codegraph/src/artifact.rs:829 CONFIRMED +- fn read_text [pub] — crates/lance-graph-codegraph/src/artifact.rs:867 CONFIRMED +- fn read_text_as [pub] — crates/lance-graph-codegraph/src/artifact.rs:877 CONFIRMED - const HEADER_LEN [pub] — crates/lance-graph-codegraph/src/artifact_bin.rs:32 CONFIRMED - const NO_ID [pub] — crates/lance-graph-codegraph/src/artifact_bin.rs:34 CONFIRMED - mod tag [pub] — crates/lance-graph-codegraph/src/artifact_bin.rs:51 CONFIRMED @@ -171,29 +172,40 @@ Generated; the code is the truth. See ../index.md. - fn Codegraph::pos_of_id [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:991 CONFIRMED - fn Codegraph::lanes [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:996 CONFIRMED - fn Codegraph::partial_crates [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1001 CONFIRMED -- 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::stored_crates [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1010 CONFIRMED +- fn Codegraph::residuals_of_crate [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1020 CONFIRMED +- fn Codegraph::any_partial [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1032 CONFIRMED +- fn Codegraph::words [pub] — crates/lance-graph-codegraph/src/graph.rs:1037 CONFIRMED +- fn Codegraph::mask_of [pub] — crates/lance-graph-codegraph/src/graph.rs:1042 CONFIRMED +- fn Codegraph::crate_status [pub] — crates/lance-graph-codegraph/src/graph.rs:1053 CONFIRMED +- fn Codegraph::rows [pub] — crates/lance-graph-codegraph/src/graph.rs:1059 CONFIRMED +- fn Codegraph::row_predicate [pub] — crates/lance-graph-codegraph/src/graph.rs:1064 CONFIRMED +- fn Codegraph::row_subject [pub] — crates/lance-graph-codegraph/src/graph.rs:1069 CONFIRMED +- fn Codegraph::row_object [pub] — crates/lance-graph-codegraph/src/graph.rs:1074 CONFIRMED +- fn Codegraph::site [pub] — crates/lance-graph-codegraph/src/graph.rs:1079 CONFIRMED +- fn Codegraph::cube [pub] — crates/lance-graph-codegraph/src/graph.rs:1093 CONFIRMED +- fn Codegraph::cube_mut [pub] — crates/lance-graph-codegraph/src/graph.rs:1098 CONFIRMED +- fn Codegraph::cube_and_table_mut [pub(crate)] — crates/lance-graph-codegraph/src/graph.rs:1104 CONFIRMED +- fn Codegraph::table [pub] — crates/lance-graph-codegraph/src/graph.rs:1109 CONFIRMED +- fn Codegraph::fns [pub] — crates/lance-graph-codegraph/src/graph.rs:1114 CONFIRMED +- fn Codegraph::public [pub] — crates/lance-graph-codegraph/src/graph.rs:1118 CONFIRMED +- fn Codegraph::impl_subjects [pub] — crates/lance-graph-codegraph/src/graph.rs:1122 CONFIRMED +- fn Codegraph::synthetic [pub] — crates/lance-graph-codegraph/src/graph.rs:1126 CONFIRMED +- fn Codegraph::referenced [pub] — crates/lance-graph-codegraph/src/graph.rs:1130 CONFIRMED +- fn Codegraph::called [pub] — crates/lance-graph-codegraph/src/graph.rs:1134 CONFIRMED +- fn Codegraph::may_targets [pub] — crates/lance-graph-codegraph/src/graph.rs:1138 CONFIRMED +- fn Codegraph::dynamic_callers [pub] — crates/lance-graph-codegraph/src/graph.rs:1142 CONFIRMED +- fn Codegraph::stored_owner [pub] — crates/lance-graph-codegraph/src/graph.rs:1146 CONFIRMED +- fn Codegraph::closure [pub] — crates/lance-graph-codegraph/src/graph.rs:1152 CONFIRMED +- struct Targets [pub] — crates/lance-graph-codegraph/src/impact_report.rs:26 CONFIRMED +- const Targets::LIB_ONLY [pub] — crates/lance-graph-codegraph/src/impact_report.rs:39 CONFIRMED +- const Targets::ALL [pub] — crates/lance-graph-codegraph/src/impact_report.rs:47 CONFIRMED +- struct Scope [pub] — crates/lance-graph-codegraph/src/impact_report.rs:70 CONFIRMED +- enum SymbolState [pub] — crates/lance-graph-codegraph/src/impact_report.rs:93 CONFIRMED +- enum Gap [pub] — crates/lance-graph-codegraph/src/impact_report.rs:108 CONFIRMED +- struct ImpactReport [pub] — crates/lance-graph-codegraph/src/impact_report.rs:185 CONFIRMED +- fn ImpactReport::closed_in_scope [pub] — crates/lance-graph-codegraph/src/impact_report.rs:198 CONFIRMED +- fn Codegraph::impact_report [pub] — crates/lance-graph-codegraph/src/impact_report.rs:337 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 +217,14 @@ 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 (203 total), see symbols.tsv ## Imports from in-scope crates diff --git a/.codegraph/freshness.tsv b/.codegraph/freshness.tsv index c6f966411..4c14fb2fc 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 be1efc44d1d322ae 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..5e53cf009 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 1172 super::* - use test POSSIBLE +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1173 std::fs - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1174 std::path::PathBuf - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1175 std::sync::atomic::AtomicU32 - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1175 std::sync::atomic::Ordering - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1370 super::* - use test POSSIBLE +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1371 std::collections::BTreeMap - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1372 std::fs - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1373 std::path::PathBuf - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1374 std::sync::atomic::AtomicU32 - use test CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1374 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,15 @@ 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 16 std::collections::BTreeSet - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 17 std::path::Path - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 17 std::path::PathBuf - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 19 crate::artifact::ResidualCounts - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 19 crate::artifact::fnv64_hex - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 20 crate::graph::Codegraph - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 20 crate::graph::Pos - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 21 crate::query::Graded - use - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 21 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 +4829,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/symbols.tsv b/.codegraph/symbols.tsv index bea7437c0..973cd63ec 100644 --- a/.codegraph/symbols.tsv +++ b/.codegraph/symbols.tsv @@ -8545,75 +8545,76 @@ lance-graph-codec-research crates/lance-graph-codec-research/src/zeckbf17.rs 645 lance-graph-codec-research crates/lance-graph-codec-research/src/zeckbf17.rs 80 fn verify_golden_coverage pub - CONFIRMED lance-graph-codec-research crates/lance-graph-codec-research/src/zeckbf17.rs 881 impl std::fmt::Display for FidelityReport - - CONFIRMED lance-graph-codec-research crates/lance-graph-codec-research/src/zeckbf17.rs 95 struct BasePattern pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 112 struct FastHasher pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 116 impl Hasher for FastHasher - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 143 type FastBuild pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 148 struct Symbols pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 153 impl Symbols - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 155 fn Symbols::intern pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 166 fn Symbols::get pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 171 fn Symbols::name pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 176 fn Symbols::len pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 181 fn Symbols::is_empty pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 188 fn Symbols::absorb pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 204 trait Interner pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 219 impl Interner for Symbols - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 110 fn fnv64_hex pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 122 struct FastHasher pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 126 impl Hasher for FastHasher - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 153 type FastBuild pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 158 struct Symbols pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 163 impl Symbols - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 165 fn Symbols::intern pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 176 fn Symbols::get pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 181 fn Symbols::name pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 186 fn Symbols::len pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 191 fn Symbols::is_empty pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 198 fn Symbols::absorb pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 214 trait Interner pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 229 impl Interner for Symbols - - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 23 const ROWS_VERSION pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 238 struct SymbolStage pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 245 struct StagedNames pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 250 impl SymbolStage<'a> - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 252 fn SymbolStage<'a>::new pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 261 fn SymbolStage<'a>::added pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 266 fn SymbolStage<'a>::into_names pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 274 impl Interner for SymbolStage<'_> - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 303 struct Lanes pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 333 impl Lanes - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 335 fn Lanes::len pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 340 fn Lanes::is_empty pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 345 fn Lanes::predicate_name pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 357 fn Lanes::digest_of pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 248 struct SymbolStage pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 255 struct StagedNames pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 260 impl SymbolStage<'a> - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 262 fn SymbolStage<'a>::new pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 271 fn SymbolStage<'a>::added pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 276 fn SymbolStage<'a>::into_names pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 284 impl Interner for SymbolStage<'_> - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 313 struct Lanes pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 343 impl Lanes - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 345 fn Lanes::len pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 350 fn Lanes::is_empty pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 355 fn Lanes::predicate_name pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 367 fn Lanes::digest_of pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 37 const NO_SPAN pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 370 fn Lanes::residuals_of pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 375 fn Lanes::set_residuals pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 383 fn Lanes::crates pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 389 fn Lanes::drop_crate pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 380 fn Lanes::residuals_of pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 385 fn Lanes::set_residuals pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 393 fn Lanes::crates pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 399 fn Lanes::drop_crate pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 40 const NO_ID pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 43 const P_DEFINES pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 434 fn Lanes::append pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 444 fn Lanes::append pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 45 const P_CALLS pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 460 enum ResidualKind pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 47 const P_MAY pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 475 impl ResidualKind - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 477 const ResidualKind::ALL pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 486 fn ResidualKind::name pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 470 enum ResidualKind pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 485 impl ResidualKind - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 487 const ResidualKind::ALL pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 49 const P_UNRESOLVED pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 508 struct ResidualCounts pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 496 fn ResidualKind::name pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 51 const P_PUBLIC pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 510 impl ResidualCounts - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 512 fn ResidualCounts::of pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 517 fn ResidualCounts::total pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 522 fn ResidualCounts::add pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 518 struct ResidualCounts pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 520 impl ResidualCounts - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 522 fn ResidualCounts::of pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 527 fn ResidualCounts::total pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 53 const P_IMPLEMENTS pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 531 enum ResidualRefusal pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 532 fn ResidualCounts::add pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 541 enum ResidualRefusal pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 55 const P_SYNTHETIC pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 563 fn refuse_placeholders pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 57 const P_REFERENCES pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 573 fn refuse_placeholders pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 59 const P_CRATE pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 591 const RESIDUAL_SUFFIX pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 595 fn read_residuals pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 601 const RESIDUAL_SUFFIX pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 605 fn read_residuals pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 62 const P_OTHER pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 640 const BIN_SUFFIX pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 644 enum CrateSource pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 653 fn crate_source pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 663 fn read_crate_text pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 668 fn read_crate pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 678 fn read_dir pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 727 fn read_bin_as pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 650 const BIN_SUFFIX pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 654 enum CrateSource pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 663 fn crate_source pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 673 fn read_crate_text pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 678 fn read_crate pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 688 fn read_dir pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 737 fn read_bin_as pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 78 fn pred_code pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 819 fn dispatch_target pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 833 impl Memo<'a,N> - - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 857 fn read_text pub - CONFIRMED -lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 867 fn read_text_as pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 829 fn dispatch_target pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 843 impl Memo<'a,N> - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 867 fn read_text pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 877 fn read_text_as pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact.rs 98 fn digest pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact_bin.rs 125 enum BinRefusal pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/artifact_bin.rs 192 impl fmt::Display for BinRefusal - - CONFIRMED @@ -8684,29 +8685,31 @@ lance-graph-codegraph crates/lance-graph-codegraph/src/diag.rs 69 enum FindingSt lance-graph-codegraph crates/lance-graph-codegraph/src/diag.rs 79 enum Run pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/diag.rs 98 enum CrateKind pub - CONFIRMED lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1001 fn Codegraph::partial_crates pub(crate) - CONFIRMED -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 1010 fn Codegraph::stored_crates pub(crate) - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1020 fn Codegraph::residuals_of_crate pub(crate) - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1032 fn Codegraph::any_partial pub(crate) - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1037 fn Codegraph::words pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1042 fn Codegraph::mask_of pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1053 fn Codegraph::crate_status pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1059 fn Codegraph::rows pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1064 fn Codegraph::row_predicate pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1069 fn Codegraph::row_subject pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1074 fn Codegraph::row_object pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1079 fn Codegraph::site pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1093 fn Codegraph::cube pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1098 fn Codegraph::cube_mut pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1104 fn Codegraph::cube_and_table_mut pub(crate) - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1109 fn Codegraph::table pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1114 fn Codegraph::fns pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1118 fn Codegraph::public pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1122 fn Codegraph::impl_subjects pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1126 fn Codegraph::synthetic pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1130 fn Codegraph::referenced pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1134 fn Codegraph::called pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1138 fn Codegraph::may_targets pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1142 fn Codegraph::dynamic_callers pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1146 fn Codegraph::stored_owner pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/graph.rs 1152 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,18 @@ 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 108 enum Gap pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 185 struct ImpactReport pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 194 impl ImpactReport - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 198 fn ImpactReport::closed_in_scope pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 26 struct Targets pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 331 impl Codegraph - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 337 fn Codegraph::impact_report pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 37 impl Targets - - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 39 const Targets::LIB_ONLY pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 47 const Targets::ALL pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 70 struct Scope pub - CONFIRMED +lance-graph-codegraph crates/lance-graph-codegraph/src/impact_report.rs 93 enum SymbolState 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 +8762,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..13506d23e 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:1587 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/examples/cg_query.rs b/crates/lance-graph-codegraph/examples/cg_query.rs index 4b4975ef8..4ae3b8bd7 100644 --- a/crates/lance-graph-codegraph/examples/cg_query.rs +++ b/crates/lance-graph-codegraph/examples/cg_query.rs @@ -4,8 +4,16 @@ //! ```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 -- report SYMBOL \ +//! [--targets CRATE=lib,tests,examples,benches]... [--exclude CRATE=REGION]... [--consumers-closed] //! ``` //! +//! `report` prints [`Codegraph::impact_report`]: the impact masks, whether the +//! symbol has a position, and every coverage gap of the declared scope, one +//! `GAP` line each. A crate without `--targets` is reported as undeclared; +//! `--exclude` names code the extraction did not translate (an opaque module, +//! a feature left off). +//! //! Output is tab-separated, one fact per line. Every result line carries its //! grade (`CONFIRMED`, `POSSIBLE`, `UNKNOWN`); a refusal is printed verbatim //! with `REFUSED` and exit code 3, never as an empty answer. Callers and impact of @@ -17,6 +25,7 @@ use std::path::{Path, PathBuf}; use std::process::ExitCode; +use lance_graph_codegraph::impact_report::{Scope, SymbolState, Targets}; use lance_graph_codegraph::Codegraph; fn line_of(src_root: &Path, file: &str, offset: u32) -> String { @@ -139,6 +148,9 @@ fn main() -> ExitCode { eprintln!("{cmd} needs a SYMBOL"); return ExitCode::from(2); }; + if cmd == "report" { + return report(&g, &store, &src, sym, &args[4..]); + } let Some(pos) = g.pos(sym) else { println!("UNKNOWN\tsymbol-not-in-store\t{sym}"); return ExitCode::from(4); @@ -205,3 +217,89 @@ fn main() -> ExitCode { } } } + +fn parse_targets(list: &str) -> Option { + let mut t = Targets::default(); + for k in list.split(',') { + match k { + "lib" => t.lib = true, + "tests" => t.tests = true, + "examples" => t.examples = true, + "benches" => t.benches = true, + _ => return None, + } + } + Some(t) +} + +fn report(g: &Codegraph, store: &Path, src: &Path, sym: &str, flags: &[String]) -> ExitCode { + let mut scope = Scope { + store: Some(store.to_path_buf()), + source_root: Some(src.to_path_buf()), + ..Scope::default() + }; + let mut it = flags.iter(); + while let Some(f) = it.next() { + let value = |v: Option<&String>| { + v.and_then(|v| v.split_once('=')) + .map(|(a, b)| (a.to_string(), b.to_string())) + }; + match f.as_str() { + "--consumers-closed" => scope.consumers_closed = true, + "--targets" => match value(it.next()) { + Some((k, list)) => match parse_targets(&list) { + Some(t) => scope.targets.push((k, t)), + None => { + eprintln!("bad --targets list {list}"); + return ExitCode::from(2); + } + }, + None => { + eprintln!("--targets needs CRATE=LIST"); + return ExitCode::from(2); + } + }, + "--exclude" => match value(it.next()) { + Some((k, region)) => match scope.excluded.iter_mut().find(|(n, _)| *n == k) { + Some((_, r)) => r.push(region), + None => scope.excluded.push((k, vec![region])), + }, + None => { + eprintln!("--exclude needs CRATE=REGION"); + return ExitCode::from(2); + } + }, + other => { + eprintln!("unknown flag {other}"); + return ExitCode::from(2); + } + } + } + let r = match g.impact_report(sym, &scope) { + Ok(r) => r, + Err(e) => { + println!("REFUSED\treport\t{e:?}"); + return ExitCode::from(3); + } + }; + match r.symbol { + SymbolState::Found(p) => println!("symbol\tFOUND\t{p}\t{sym}"), + SymbolState::Missing { owner_stored } => { + println!("symbol\tMISSING\towner_stored={owner_stored}\t{sym}") + } + } + 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 gap in &r.gaps { + println!("GAP\t{gap:?}"); + } + println!("closed_in_scope\t{}", r.closed_in_scope()); + ExitCode::SUCCESS +} diff --git a/crates/lance-graph-codegraph/src/artifact.rs b/crates/lance-graph-codegraph/src/artifact.rs index a28e2041f..5d75fc47f 100644 --- a/crates/lance-graph-codegraph/src/artifact.rs +++ b/crates/lance-graph-codegraph/src/artifact.rs @@ -104,6 +104,16 @@ pub fn digest(bytes: &[u8]) -> u64 { h.finish() } +/// FNV-1a 64 of `bytes` as 16 lowercase hex digits: the digest ruff_charon +/// writes to `.files.tsv` (`ruff_charon::store::fnv64`, `{:016x}`). +/// Not [`digest`], which is the rows-file change detector. +pub fn fnv64_hex(bytes: &[u8]) -> String { + let h = bytes.iter().fold(0xcbf2_9ce4_8422_2325u64, |h, &b| { + (h ^ u64::from(b)).wrapping_mul(0x0100_0000_01b3) + }); + format!("{h:016x}") +} + /// A multiply-rotate hasher folding eight bytes per step. The interner is /// keyed by short symbol paths and is hit about once per row; SipHash made /// those lookups the dominant cost. Not DoS-resistant, which is fine for a diff --git a/crates/lance-graph-codegraph/src/graph.rs b/crates/lance-graph-codegraph/src/graph.rs index d6a20e156..80cd39639 100644 --- a/crates/lance-graph-codegraph/src/graph.rs +++ b/crates/lance-graph-codegraph/src/graph.rs @@ -1005,6 +1005,29 @@ impl Codegraph { .count() as u32 } + /// Names of the crates with a CRATE row: the first path segment of the + /// symbols each crate defines. + pub(crate) fn stored_crates(&self) -> std::collections::BTreeSet<&str> { + self.crates + .keys() + .map(|&id| self.symbols.name(id)) + .collect() + } + + /// Residual counts of the crate named `krate`, and whether no residuals + /// file was read for it. A name the store did not read under is reported + /// as having no file: unknown, never clean. + pub(crate) fn residuals_of_crate(&self, krate: &str) -> (artifact::ResidualCounts, bool) { + match self + .symbols + .get(krate) + .and_then(|id| self.lanes.residuals_of(id)) + { + Some(Some(r)) => (r, false), + _ => (artifact::ResidualCounts::default(), true), + } + } + /// Whether any stored crate's CRATE row is not `COMPLETE`. pub(crate) fn any_partial(&self) -> bool { self.crates.values().any(|&s| s == RunStatus::Partial) 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..0709c735b --- /dev/null +++ b/crates/lance-graph-codegraph/src/impact_report.rs @@ -0,0 +1,455 @@ +//! Coverage-aware impact: [`Codegraph::impact`] plus a typed account of what +//! the answer could not see. +//! +//! [`Codegraph::impact`] answers over symbol positions. A caller the store +//! never observed has no position, so an empty answer cannot tell "nothing +//! depends on this" from "the dependants were never extracted". This report +//! keeps the impact masks exactly as `impact` returns them and adds a list of +//! [`Gap`]s, each a fact the store or the declared [`Scope`] actually holds. +//! Missing coverage is never written into `Graded.unknown`, which stays the set +//! of observed functions a dynamic call may reach. +//! +//! [`ImpactReport::closed_in_scope`] is the only "nothing else" claim this +//! module makes, and it is local: no gap is known *within the declared scope*. +//! It is never a statement about code outside the stored crates. + +use std::collections::BTreeSet; +use std::path::{Path, PathBuf}; + +use crate::artifact::{fnv64_hex, ResidualCounts}; +use crate::graph::{Codegraph, Pos}; +use crate::query::{Graded, QueryRefusal}; + +/// Which targets of one crate were extracted into the store. The store does +/// not record this; the caller declares it from how the extractor was run. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct Targets { + /// The library target. + pub lib: bool, + /// Integration tests and `#[cfg(test)]` unit tests. + pub tests: bool, + /// Examples. + pub examples: bool, + /// Benches. + pub benches: bool, +} + +impl Targets { + /// The library target only (Charon's default `charon cargo` run). + pub const LIB_ONLY: Targets = Targets { + lib: true, + tests: false, + examples: false, + benches: false, + }; + + /// Every target kind. + pub const ALL: Targets = Targets { + lib: true, + tests: true, + examples: true, + benches: true, + }; + + fn missing(self) -> Targets { + Targets { + lib: !self.lib, + tests: !self.tests, + examples: !self.examples, + benches: !self.benches, + } + } + + fn any(self) -> bool { + self.lib || self.tests || self.examples || self.benches + } +} + +/// What the caller asserts about the analysis beyond the store's own rows. +#[derive(Debug, Clone, Default)] +pub struct Scope { + /// The store directory, for `.files.tsv`. + pub store: Option, + /// The source root the recorded paths are relative to. `None` means + /// freshness was not checked, which is itself a gap. + pub source_root: Option, + /// Extracted targets per stored crate name. A stored crate without an + /// entry is `TargetsUndeclared`. + pub targets: Vec<(String, Targets)>, + /// The caller asserts that every crate which can call the symbol's crate + /// is in the store (for example an unpublished crate whose whole + /// dependent set was extracted). Without this, a public symbol's external + /// callers are unobserved. + pub consumers_closed: bool, + /// Code of a stored crate the extraction did not translate, per crate + /// name: modules passed to Charon as opaque, cargo features left off, cfg + /// branches not taken. The store cannot see what is inside, so a caller, + /// callee or definition there has no position. + pub excluded: Vec<(String, Vec)>, +} + +/// Whether the queried symbol has a position. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum SymbolState { + /// The symbol is in the store. + Found(Pos), + /// No stored row names the symbol. + Missing { + /// The symbol's first path segment names a stored crate: the crate + /// was read and does not define or mention it. When false, the symbol + /// lies outside every stored crate and nothing was looked at. + owner_stored: bool, + }, +} + +/// One reason the impact answer may be incomplete. Every variant comes from +/// a store fact or a declared scope fact; none is inferred. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Gap { + /// The symbol is `PUBLIC` and the consumer set is not declared closed: + /// crates outside the store can call it. `observed_consumers` lists the + /// stored crates other than the owner that already call into it. + ExternalConsumersUnobserved { + /// The symbol's crate. + owner: String, + /// Other stored crates with a confirmed caller in the answer. + observed_consumers: Vec, + }, + /// Targets of the owning crate that were not extracted, so callers there + /// (for example test functions) have no positions. + TargetsNotExtracted { + /// The crate. + krate: String, + /// The target kinds that were not extracted. + missing: Targets, + }, + /// No target declaration for a stored crate the answer depends on. + TargetsUndeclared { + /// The crate. + krate: String, + }, + /// A dynamic call (`UNRESOLVED_CALL`) may reach the symbol or something + /// it reaches; its target was not named by the compiler. + UnresolvedDispatch { + /// `UNRESOLVED_CALL` rows in the store. + dynamic_calls: u32, + }, + /// The owning crate's harvest recorded residuals, did not finish, or has + /// no residuals file. + HarvestIncomplete { + /// The crate. + krate: String, + /// Residual counts (zero when only the run status is the cause). + residuals: ResidualCounts, + /// The CRATE row is not `COMPLETE`. + partial: bool, + /// No `.residuals.tsv` was read. + no_residuals_file: bool, + }, + /// A recorded source file changed or vanished since extraction. + StaleSource { + /// The crate. + krate: String, + /// The changed or missing files, as recorded. + files: Vec, + }, + /// The crate has no `.files.tsv`, so freshness cannot be checked. + FilesUnrecorded { + /// The crate. + krate: String, + }, + /// No source root was given; freshness was not checked. + FreshnessUnchecked, + /// Rust files under a directory the extraction read from that it did not + /// read itself: modules behind a disabled feature or cfg, other targets' + /// roots, files never declared as modules. Their code has no rows. + SourceFilesUnread { + /// The crate. + krate: String, + /// The unread `.rs` files, relative to the source root. + files: Vec, + }, + /// The declared scope excludes regions of the crate from extraction + /// (opaque modules, disabled features). Calls inside them have no rows, + /// and a symbol defined only there is missing without being absent. + RegionsExcluded { + /// The crate. + krate: String, + /// The excluded regions, as declared. + regions: Vec, + }, +} + +/// [`Codegraph::impact`] with its coverage. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ImpactReport { + /// Exactly what [`Codegraph::impact`] returns (empty masks when missing). + pub graded: Graded, + /// Whether the symbol has a position. + pub symbol: SymbolState, + /// Every known reason the answer may be incomplete. + pub gaps: Vec, +} + +impl ImpactReport { + /// The symbol is in the store and no gap is known within the declared + /// scope. This is a local statement: it never claims anything about + /// crates, targets or revisions outside the scope. + pub fn closed_in_scope(&self) -> bool { + matches!(self.symbol, SymbolState::Found(_)) && self.gaps.is_empty() + } +} + +fn owner_of(symbol: &str) -> &str { + symbol.split("::").next().unwrap_or(symbol) +} + +fn has(mask: &[u64], p: Pos) -> bool { + mask.get(p as usize / 64) + .is_some_and(|w| w >> (p % 64) & 1 == 1) +} + +fn bits(mask: &[u64]) -> impl Iterator + '_ { + (0..mask.len() * 64) + .filter(|&p| mask[p / 64] >> (p % 64) & 1 == 1) + .filter_map(|p| Pos::try_from(p).ok()) +} + +/// The stale and the unread files of `krate`, or `None` when the crate has +/// no files table. Stale: a recorded file whose digest differs under `root`. +/// Unread: a `.rs` file below the top directory of a recorded path that the +/// table does not list. A recorded file at the root names no directory, so +/// nothing is scanned for it. +fn file_gaps(store: &Path, root: &Path, krate: &str) -> Option<(Vec, Vec)> { + let table = std::fs::read_to_string(store.join(format!("{krate}.files.tsv"))).ok()?; + let mut stale = Vec::new(); + let mut recorded = BTreeSet::new(); + let mut tops = BTreeSet::new(); + for line in table + .lines() + .filter(|l| !l.starts_with('#') && !l.is_empty()) + { + let mut f = line.split('\t'); + let (Some(path), Some(digest)) = (f.next(), f.next()) else { + stale.push(line.to_owned()); + continue; + }; + recorded.insert(path.to_owned()); + if let Some((top, _)) = path.split_once('/') { + if top != "." && top != ".." { + tops.insert(top.to_owned()); + } + } + match std::fs::read(root.join(path)) { + Ok(bytes) if fnv64_hex(&bytes) == digest => {} + _ => stale.push(path.to_owned()), + } + } + let mut unread = Vec::new(); + for top in &tops { + rust_files(root, top, &mut unread); + } + unread.retain(|f| !recorded.contains(f)); + unread.sort(); + Some((stale, unread)) +} + +/// Every `.rs` file below `root/rel`, as paths relative to `root`. +fn rust_files(root: &Path, rel: &str, out: &mut Vec) { + let Ok(entries) = std::fs::read_dir(root.join(rel)) else { + return; + }; + for e in entries.flatten() { + let name = e.file_name().to_string_lossy().into_owned(); + let path = format!("{rel}/{name}"); + match e.file_type() { + Ok(t) if t.is_dir() => rust_files(root, &path, out), + Ok(t) if t.is_file() && name.ends_with(".rs") => out.push(path), + _ => {} + } + } +} + +/// Freshness and unread-file gaps of `krates` under the declared store and +/// source root; `FreshnessUnchecked` when either is missing. +fn freshness_gaps<'a>( + krates: impl IntoIterator, + scope: &Scope, + gaps: &mut Vec, +) { + match (&scope.store, &scope.source_root) { + (Some(store), Some(root)) => { + for k in krates { + match file_gaps(store, root, k) { + None => gaps.push(Gap::FilesUnrecorded { krate: k.clone() }), + Some((stale, unread)) => { + if !stale.is_empty() { + gaps.push(Gap::StaleSource { + krate: k.clone(), + files: stale, + }); + } + if !unread.is_empty() { + gaps.push(Gap::SourceFilesUnread { + krate: k.clone(), + files: unread, + }); + } + } + } + } + } + _ => gaps.push(Gap::FreshnessUnchecked), + } +} + +/// The declared-scope gaps of one stored crate: its targets and its +/// excluded regions. +fn scope_gaps(k: &str, scope: &Scope, gaps: &mut Vec) { + match scope.targets.iter().find(|(n, _)| n == k) { + None => gaps.push(Gap::TargetsUndeclared { + krate: k.to_owned(), + }), + Some((_, t)) => { + let missing = t.missing(); + if missing.any() { + gaps.push(Gap::TargetsNotExtracted { + krate: k.to_owned(), + missing, + }); + } + } + } + if let Some((_, regions)) = scope.excluded.iter().find(|(n, r)| n == k && !r.is_empty()) { + gaps.push(Gap::RegionsExcluded { + krate: k.to_owned(), + regions: regions.clone(), + }); + } +} + +impl Codegraph { + /// [`Codegraph::impact`] of `symbol`, with the gaps of `scope`. + /// + /// Gaps are reported for the symbol's own crate and for every stored crate + /// holding a function in the answer. The masks are those of `impact`; + /// this method never adds a position for an unobserved caller. + pub fn impact_report(&self, symbol: &str, scope: &Scope) -> Result { + let stored = self.stored_crates(); + let Some(g) = self.pos(symbol) else { + let z = vec![0u64; self.words()]; + // A missing symbol in a stored crate is absent only from what was + // extracted: undeclared or missing targets, excluded regions and + // unread files are each a place it may still be defined. + let mut gaps = Vec::new(); + let owner = owner_of(symbol); + if stored.contains(owner) { + scope_gaps(owner, scope, &mut gaps); + self.harvest_gaps(owner, &mut gaps); + freshness_gaps([&owner.to_owned()], scope, &mut gaps); + } + return Ok(ImpactReport { + graded: Graded { + confirmed: z.clone(), + possible: z.clone(), + unknown: z, + }, + symbol: SymbolState::Missing { + owner_stored: stored.contains(owner), + }, + gaps, + }); + }; + let graded = self.impact(g)?; + let owner = owner_of(symbol).to_owned(); + let mut gaps = Vec::new(); + + // Crates the answer depends on: the owner, plus every stored crate + // holding a graded function. + let mut involved: BTreeSet = BTreeSet::new(); + if stored.contains(owner.as_str()) { + involved.insert(owner.clone()); + } + let mut consumers: BTreeSet = BTreeSet::new(); + for m in [&graded.confirmed, &graded.possible, &graded.unknown] { + for p in bits(m) { + if let Some(s) = self.symbol(p) { + let k = owner_of(s); + if stored.contains(k) { + involved.insert(k.to_owned()); + } + } + } + } + for p in bits(&graded.confirmed) { + if let Some(s) = self.symbol(p) { + let k = owner_of(s); + if k != owner && stored.contains(k) { + consumers.insert(k.to_owned()); + } + } + } + + // The consumer frontier: the symbol, or anything that reaches it, is + // public. External callers of a public caller are affected too. + let frontier_public = has(self.public(), g) + || [&graded.confirmed, &graded.possible, &graded.unknown] + .iter() + .any(|m| m.iter().zip(self.public()).any(|(a, b)| a & b != 0)); + if frontier_public { + if scope.consumers_closed { + // Every stored crate may be a consumer, including one whose + // calls sit in code it did not extract and so have no + // position here; each one's coverage decides the answer. + involved.extend(stored.iter().map(|k| (*k).to_owned())); + } else { + gaps.push(Gap::ExternalConsumersUnobserved { + owner: owner.clone(), + observed_consumers: consumers.into_iter().collect(), + }); + } + } + + for k in &involved { + scope_gaps(k, scope, &mut gaps); + } + + let dynamic_calls = self.coverage().dynamic_calls; + let unknown_reached = graded.unknown.iter().any(|&w| w != 0); + if unknown_reached || (dynamic_calls > 0 && self.dynamic_may_reach(g)) { + gaps.push(Gap::UnresolvedDispatch { dynamic_calls }); + } + + for k in &involved { + self.harvest_gaps(k, &mut gaps); + } + + freshness_gaps(&involved, scope, &mut gaps); + + Ok(ImpactReport { + graded, + symbol: SymbolState::Found(g), + gaps, + }) + } + + /// `HarvestIncomplete` for `k` when its harvest recorded residuals, did + /// not finish, or has no residuals file. + fn harvest_gaps(&self, k: &str, gaps: &mut Vec) { + let (residuals, no_file) = self.residuals_of_crate(k); + let partial = self.crate_status(k) == Some(crate::graph::RunStatus::Partial); + if residuals.total() > 0 || no_file || partial { + gaps.push(Gap::HarvestIncomplete { + krate: k.to_owned(), + residuals, + partial, + no_residuals_file: no_file, + }); + } + } + + /// Whether a dynamic call may reach `g`: `g` is an impl or referenced. + fn dynamic_may_reach(&self, g: Pos) -> bool { + has(self.impl_subjects(), g) || has(self.referenced(), g) + } +} 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..3985590ad --- /dev/null +++ b/crates/lance-graph-codegraph/tests/impact_coverage.rs @@ -0,0 +1,659 @@ +//! Coverage-aware impact (D-CODEGRAPH-RECON-2, Gate A). +//! +//! `Codegraph::impact` answers over symbol positions; a caller the store never +//! extracted has none. These tests pin that `impact_report` keeps the impact +//! masks unchanged and reports each kind of missing coverage as a typed gap, +//! never as a fabricated position in `Graded.unknown`. Each gate has a +//! can-fire test and a can-stay-silent twin on a non-trivial store. + +use std::path::PathBuf; + +use lance_graph_codegraph::artifact::fnv64_hex; +use lance_graph_codegraph::impact_report::{Gap, Scope, SymbolState, Targets}; +use lance_graph_codegraph::Codegraph; + +const HEADER: &str = "#version 2\n#schema predicate\tsubject\tobject\tgrade\tfile\tstart\tend\n"; +const RES_HEADER: &str = "#version 1\n#schema reason\tsubject\n"; +const FILES_HEADER: &str = "#version 1\n#schema path\tfnv64\n"; + +/// One crate of a store: its rows (predicate, subject, object) and the source +/// files it was extracted from (path, contents). +struct Krate<'a> { + name: &'a str, + rows: &'a [(&'a str, &'a str, &'a str)], + files: &'a [(&'a str, &'a str)], +} + +/// A store directory plus a source root holding each crate's files. +struct Fixture { + dir: PathBuf, + store: PathBuf, + src: PathBuf, +} + +impl Fixture { + fn new(name: &str, crates: &[Krate<'_>]) -> Fixture { + let dir = std::env::temp_dir().join(format!("lgcg_impact_{name}_{}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + let (store, src) = (dir.join("store"), dir.join("src")); + std::fs::create_dir_all(&store).unwrap(); + std::fs::create_dir_all(&src).unwrap(); + let fx = Fixture { dir, store, src }; + for k in crates { + fx.add(k); + } + fx + } + + /// Write one crate's rows, empty residuals and files table. + fn add(&self, k: &Krate<'_>) { + let file = k.files.first().map_or("f.rs", |f| f.0); + let mut t = String::from(HEADER); + for (p, s, o) in k.rows { + t += &format!("{p}\t{s}\t{o}\tCOMPILER\t{file}\t1\t2\n"); + } + t += &format!("CRATE\t{}\tCOMPLETE\tCOMPILER\t-\t-\t-\n", k.name); + std::fs::write(self.store.join(format!("{}.rows.tsv", k.name)), t).unwrap(); + std::fs::write( + self.store.join(format!("{}.residuals.tsv", k.name)), + RES_HEADER, + ) + .unwrap(); + let mut f = String::from(FILES_HEADER); + for (path, body) in k.files { + let at = self.src.join(path); + std::fs::create_dir_all(at.parent().unwrap()).unwrap(); + std::fs::write(at, body).unwrap(); + f += &format!("{path}\t{}\n", fnv64_hex(body.as_bytes())); + } + std::fs::write(self.store.join(format!("{}.files.tsv", k.name)), f).unwrap(); + } + + fn open(&self) -> Codegraph { + Codegraph::open(&self.store).unwrap() + } + + /// Every stored crate fully extracted, freshness checked against `src`. + fn scope(&self, crates: &[&str]) -> Scope { + Scope { + store: Some(self.store.clone()), + source_root: Some(self.src.clone()), + targets: crates + .iter() + .map(|c| (c.to_string(), Targets::ALL)) + .collect(), + consumers_closed: false, + excluded: Vec::new(), + } + } +} + +impl Drop for Fixture { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.dir); + } +} + +/// `lib::entry` is public and calls `lib::used`; `lib::helper` is private +/// and has no caller. +const LIB: &[(&str, &str, &str)] = &[ + ("DEFINES", "lib::entry", "lib::entry"), + ("PUBLIC", "lib::entry", "lib::entry"), + ("DEFINES", "lib::used", "lib::used"), + ("DEFINES", "lib::helper", "lib::helper"), + ("CALLS_RESOLVED", "lib::entry", "lib::used"), +]; + +fn lib_crate() -> Krate<'static> { + Krate { + name: "lib", + rows: LIB, + files: &[( + "lib.rs", + "pub fn entry() { used() }\nfn used() {}\nfn helper() {}\n", + )], + } +} + +fn has(g: &Codegraph, mask: &[u64], symbol: &str) -> bool { + g.pos(symbol).is_some_and(|p| { + mask.get(p as usize / 64) + .is_some_and(|w| w >> (p % 64) & 1 == 1) + }) +} + +fn empty(mask: &[u64]) -> bool { + mask.iter().all(|&w| w == 0) +} + +/// Case 1: A private symbol with no caller, in a crate whose every target was +/// extracted, whose harvest left no residual and whose sources are unchanged: +/// the empty answer is closed in scope. Anti-vacuity: `lib::used` does have a +/// caller, so the impact query is live, not merely empty. +#[test] +fn no_callers_in_a_fully_observed_scope_is_closed() { + let fx = Fixture::new("closed", &[lib_crate()]); + let g = fx.open(); + let r = g.impact_report("lib::helper", &fx.scope(&["lib"])).unwrap(); + assert!(empty(&r.graded.confirmed) && empty(&r.graded.possible) && empty(&r.graded.unknown)); + assert_eq!(r.gaps, Vec::::new()); + assert!(r.closed_in_scope()); + + let used = g.impact_report("lib::used", &fx.scope(&["lib"])).unwrap(); + assert!(has(&g, &used.graded.confirmed, "lib::entry")); +} + +/// Case 2: A public symbol with no observed caller: the masks stay exactly what +/// `impact` returns (no fabricated unknown), and the missing external +/// callers are a typed gap. `Coverage::no_known_gap()` is true for this +/// store, and the report is still not closed: no-known-gap is not global +/// completeness. +#[test] +fn a_public_symbol_reports_its_unobserved_external_consumers() { + let fx = Fixture::new("public", &[lib_crate()]); + let g = fx.open(); + assert!(g.coverage().no_known_gap()); + let pos = g.pos("lib::entry").unwrap(); + let r = g.impact_report("lib::entry", &fx.scope(&["lib"])).unwrap(); + assert_eq!(r.graded, g.impact(pos).unwrap()); + assert!( + empty(&r.graded.unknown), + "missing coverage must not become a position" + ); + assert_eq!( + r.gaps, + vec![Gap::ExternalConsumersUnobserved { + owner: "lib".into(), + observed_consumers: vec![], + }] + ); + assert!(!r.closed_in_scope()); + + // Silence twin: the caller declares the consumer set closed. + let closed = Scope { + consumers_closed: true, + ..fx.scope(&["lib"]) + }; + assert!(g + .impact_report("lib::entry", &closed) + .unwrap() + .closed_in_scope()); +} + +/// Case 3: Test-target callers: with only the lib target extracted, the +/// test-only caller has no position, so the report names the missing +/// targets. With the test target extracted (its rows present, declared ALL), +/// the caller is confirmed and the gap disappears. +#[test] +fn test_callers_absent_from_a_lib_extraction_are_a_gap() { + let fx = Fixture::new("tests", &[lib_crate()]); + let lib_only = Scope { + targets: vec![("lib".into(), Targets::LIB_ONLY)], + ..fx.scope(&["lib"]) + }; + let r = fx.open().impact_report("lib::helper", &lib_only).unwrap(); + assert!(empty(&r.graded.confirmed)); + assert_eq!( + r.gaps, + vec![Gap::TargetsNotExtracted { + krate: "lib".into(), + missing: Targets { + lib: false, + tests: true, + examples: true, + benches: true, + }, + }] + ); + + // An undeclared crate is not assumed complete. + let undeclared = Scope { + targets: vec![], + ..fx.scope(&["lib"]) + }; + let r = fx.open().impact_report("lib::helper", &undeclared).unwrap(); + assert_eq!( + r.gaps, + vec![Gap::TargetsUndeclared { + krate: "lib".into() + }] + ); + + // The test target extracted: the caller is a confirmed position. + let mut rows = LIB.to_vec(); + rows.push(( + "DEFINES", + "lib::tests::helper_works", + "lib::tests::helper_works", + )); + rows.push(("CALLS_RESOLVED", "lib::tests::helper_works", "lib::helper")); + let fx2 = Fixture::new( + "tests_all", + &[Krate { + name: "lib", + rows: &rows, + files: lib_crate().files, + }], + ); + let g = fx2.open(); + let r = g + .impact_report("lib::helper", &fx2.scope(&["lib"])) + .unwrap(); + assert!(has(&g, &r.graded.confirmed, "lib::tests::helper_works")); + assert_eq!(r.gaps, Vec::::new()); +} + +/// Case 4: Unresolved dispatch: `lib::cb` is referenced (its address is taken) and +/// `lib::runner` makes a call the compiler could not name, so a dynamic call +/// may reach `cb`. Silence twin: `lib::used` is neither an impl nor +/// referenced, so the same dynamic call is not a gap for it. +#[test] +fn an_unresolved_dispatch_that_may_reach_the_symbol_is_a_gap() { + let mut rows = LIB.to_vec(); + rows.extend([ + ("DEFINES", "lib::cb", "lib::cb"), + ("DEFINES", "lib::runner", "lib::runner"), + ("REFERENCES", "lib::entry", "lib::cb"), + ("UNRESOLVED_CALL", "lib::runner", "dynamic"), + ]); + let fx = Fixture::new( + "dyn", + &[Krate { + name: "lib", + rows: &rows, + files: lib_crate().files, + }], + ); + let g = fx.open(); + let r = g.impact_report("lib::cb", &fx.scope(&["lib"])).unwrap(); + assert!( + r.gaps + .contains(&Gap::UnresolvedDispatch { dynamic_calls: 1 }), + "{:?}", + r.gaps + ); + + let quiet = g.impact_report("lib::used", &fx.scope(&["lib"])).unwrap(); + assert!(!quiet + .gaps + .iter() + .any(|x| matches!(x, Gap::UnresolvedDispatch { .. }))); +} + +/// Case 5: Stale source: a recorded file changed after extraction. Twins: the +/// unchanged tree has no gap; a missing files table and a missing source +/// root are their own gaps, never "fresh". +#[test] +fn a_stale_source_revision_is_a_gap() { + let fx = Fixture::new("stale", &[lib_crate()]); + let g = fx.open(); + assert!(g + .impact_report("lib::helper", &fx.scope(&["lib"])) + .unwrap() + .gaps + .is_empty()); + + std::fs::write( + fx.src.join("lib.rs"), + "pub fn entry() { used(); helper() }\n", + ) + .unwrap(); + let r = g.impact_report("lib::helper", &fx.scope(&["lib"])).unwrap(); + assert_eq!( + r.gaps, + vec![Gap::StaleSource { + krate: "lib".into(), + files: vec!["lib.rs".into()], + }] + ); + + let unchecked = Scope { + source_root: None, + ..fx.scope(&["lib"]) + }; + assert_eq!( + g.impact_report("lib::helper", &unchecked).unwrap().gaps, + vec![Gap::FreshnessUnchecked] + ); + + std::fs::remove_file(fx.store.join("lib.files.tsv")).unwrap(); + assert_eq!( + g.impact_report("lib::helper", &fx.scope(&["lib"])) + .unwrap() + .gaps, + vec![Gap::FilesUnrecorded { + krate: "lib".into() + }] + ); +} + +/// Case 6: A truly missing symbol is not "no callers": it is `Missing`, never +/// closed, and says whether its crate was read at all. +#[test] +fn a_missing_symbol_is_missing_not_unaffected() { + let fx = Fixture::new("missing", &[lib_crate()]); + let g = fx.open(); + let scope = fx.scope(&["lib"]); + let r = g.impact_report("lib::nope", &scope).unwrap(); + assert_eq!(r.symbol, SymbolState::Missing { owner_stored: true }); + assert!(!r.closed_in_scope()); + let r = g.impact_report("other::thing", &scope).unwrap(); + assert_eq!( + r.symbol, + SymbolState::Missing { + owner_stored: false + } + ); + assert!(!r.closed_in_scope()); + // Twin: a present symbol with no callers is Found. + assert!(matches!( + g.impact_report("lib::helper", &scope).unwrap().symbol, + SymbolState::Found(_) + )); +} + +/// Case 7: Adding a consumer crate upgrades the answer: before, `lib::entry` has no +/// confirmed caller and the external callers are unobserved; after the `app` +/// crate's compiler facts are stored, `app::main` is a confirmed position and +/// the gap names `app` as an observed consumer. The gap stays until the +/// consumer set is declared closed, and `app` must itself be declared. +#[test] +fn adding_a_consumer_crate_confirms_its_callers() { + let fx = Fixture::new("consumer", &[lib_crate()]); + let before = fx + .open() + .impact_report("lib::entry", &fx.scope(&["lib"])) + .unwrap(); + assert!(empty(&before.graded.confirmed)); + + fx.add(&Krate { + name: "app", + rows: &[ + ("DEFINES", "app::main", "app::main"), + ("CALLS_RESOLVED", "app::main", "lib::entry"), + ], + files: &[("main.rs", "fn main() { lib::entry() }\n")], + }); + let g = fx.open(); + let after = g + .impact_report("lib::entry", &fx.scope(&["lib", "app"])) + .unwrap(); + assert!(has(&g, &after.graded.confirmed, "app::main")); + assert_eq!( + after.gaps, + vec![Gap::ExternalConsumersUnobserved { + owner: "lib".into(), + observed_consumers: vec!["app".into()], + }] + ); + + let closed = Scope { + consumers_closed: true, + ..fx.scope(&["lib", "app"]) + }; + assert!(g + .impact_report("lib::entry", &closed) + .unwrap() + .closed_in_scope()); + + let app_undeclared = Scope { + consumers_closed: true, + ..fx.scope(&["lib"]) + }; + assert_eq!( + g.impact_report("lib::entry", &app_undeclared).unwrap().gaps, + vec![Gap::TargetsUndeclared { + krate: "app".into() + }] + ); +} + +/// Case 8: An incomplete harvest of the owning crate (a residual, a missing +/// residuals file, or a PARTIAL crate row) is a gap: absent rows prove +/// nothing. Twin: the same store with empty residuals has no such gap (test 1). +#[test] +fn an_incomplete_harvest_of_the_owner_is_a_gap() { + let fx = Fixture::new("harvest", &[lib_crate()]); + std::fs::write( + fx.store.join("lib.residuals.tsv"), + format!("{RES_HEADER}BODY_NOT_STRUCTURED\tlib::entry\n"), + ) + .unwrap(); + let r = fx + .open() + .impact_report("lib::helper", &fx.scope(&["lib"])) + .unwrap(); + assert!( + matches!(r.gaps.as_slice(), [Gap::HarvestIncomplete { krate, residuals, partial: false, no_residuals_file: false }] + if krate == "lib" && residuals.total() == 1), + "{:?}", + r.gaps + ); + + std::fs::remove_file(fx.store.join("lib.residuals.tsv")).unwrap(); + let r = fx + .open() + .impact_report("lib::helper", &fx.scope(&["lib"])) + .unwrap(); + assert!( + matches!( + r.gaps.as_slice(), + [Gap::HarvestIncomplete { + no_residuals_file: true, + .. + }] + ), + "{:?}", + r.gaps + ); +} + +/// Case 9: Regions the extraction did not translate (an opaque module, a +/// cargo feature left off) are a gap for a found symbol and for a missing +/// one. A symbol defined only in an uncompiled feature module is missing from +/// the store without being absent from the crate. +#[test] +fn excluded_regions_are_a_gap_for_found_and_missing_symbols() { + let fx = Fixture::new("excluded", &[lib_crate()]); + let g = fx.open(); + let excluded = Scope { + excluded: vec![("lib".into(), vec!["feature iam".into()])], + ..fx.scope(&["lib"]) + }; + let gap = Gap::RegionsExcluded { + krate: "lib".into(), + regions: vec!["feature iam".into()], + }; + let r = g.impact_report("lib::helper", &excluded).unwrap(); + assert_eq!(r.gaps, vec![gap.clone()]); + assert!(!r.closed_in_scope()); + let r = g.impact_report("lib::authorize", &excluded).unwrap(); + assert_eq!(r.symbol, SymbolState::Missing { owner_stored: true }); + assert_eq!(r.gaps, vec![gap]); + // Silence twins: no exclusion for this crate, or an empty list, leaves the + // found symbol closed and the missing one without gaps. + for silent in [ + fx.scope(&["lib"]), + Scope { + excluded: vec![ + ("lib".into(), Vec::new()), + ("other".into(), vec!["x".into()]), + ], + ..fx.scope(&["lib"]) + }, + ] { + assert!(g + .impact_report("lib::helper", &silent) + .unwrap() + .closed_in_scope()); + assert!(g + .impact_report("lib::authorize", &silent) + .unwrap() + .gaps + .is_empty()); + } +} + +/// Case 10: A missing symbol carries its crate's target gaps. Extracting +/// only the library cannot show that a symbol is absent from the tests. +#[test] +fn a_missing_symbol_carries_its_crate_target_gaps() { + let fx = Fixture::new("missing-targets", &[lib_crate()]); + let g = fx.open(); + let lib_only = Scope { + targets: vec![("lib".into(), Targets::LIB_ONLY)], + ..fx.scope(&["lib"]) + }; + let r = g.impact_report("lib::only_in_tests", &lib_only).unwrap(); + assert!( + matches!( + r.gaps.as_slice(), + [Gap::TargetsNotExtracted { krate, missing }] if krate == "lib" && missing.tests + ), + "{:?}", + r.gaps + ); + // A symbol outside every stored crate reports no crate gap: nothing of + // its crate was read, which `owner_stored: false` already says. + assert!(g + .impact_report("other::x", &lib_only) + .unwrap() + .gaps + .is_empty()); +} + +/// Case 11: A `.rs` file under a directory the extraction read from, but not +/// itself recorded, is a gap: its code (a feature-gated module, a binary +/// root) has no rows. Files in the root and non-Rust files are not scanned. +#[test] +fn unread_source_files_under_a_read_directory_are_a_gap() { + let k = Krate { + name: "lib", + rows: &[ + ("DEFINES", "lib::entry", "lib::entry"), + ("DEFINES", "lib::helper", "lib::helper"), + ], + files: &[("crate/lib.rs", "fn entry() {}\nfn helper() {}\n")], + }; + let fx = Fixture::new("unread", &[k]); + let g = fx.open(); + let scope = fx.scope(&["lib"]); + // Silence twin: everything under crate/ is recorded; a non-Rust file and a + // root-level file are not scanned. + std::fs::write(fx.src.join("crate/data.json"), "{}").unwrap(); + std::fs::write(fx.src.join("top.rs"), "fn x() {}").unwrap(); + assert!(g + .impact_report("lib::helper", &scope) + .unwrap() + .closed_in_scope()); + std::fs::create_dir_all(fx.src.join("crate/gated")).unwrap(); + std::fs::write(fx.src.join("crate/iam.rs"), "pub fn authorize() {}").unwrap(); + std::fs::write(fx.src.join("crate/gated/deep.rs"), "fn d() {}").unwrap(); + let r = g.impact_report("lib::helper", &scope).unwrap(); + assert_eq!( + r.gaps, + vec![Gap::SourceFilesUnread { + krate: "lib".into(), + files: vec!["crate/gated/deep.rs".into(), "crate/iam.rs".into()], + }] + ); + // A symbol missing from the store may be defined in an unread file. + let r = g.impact_report("lib::authorize", &scope).unwrap(); + assert_eq!(r.symbol, SymbolState::Missing { owner_stored: true }); + assert!( + matches!(r.gaps.as_slice(), [Gap::SourceFilesUnread { files, .. }] if files.len() == 2), + "{:?}", + r.gaps + ); +} + +/// Case 12: A private symbol reached by a public caller is affected by that +/// caller's external consumers, so the external-consumer gap fires for it +/// too. A private symbol no public function reaches stays closed. +#[test] +fn a_private_symbol_behind_a_public_caller_has_unobserved_consumers() { + let fx = Fixture::new("frontier", &[lib_crate()]); + let g = fx.open(); + let r = g.impact_report("lib::used", &fx.scope(&["lib"])).unwrap(); + assert!(has(&g, &r.graded.confirmed, "lib::entry")); + assert!( + matches!(r.gaps.as_slice(), [Gap::ExternalConsumersUnobserved { owner, .. }] if owner == "lib"), + "{:?}", + r.gaps + ); + assert!(!r.closed_in_scope()); + // Silence twins: nothing public reaches `lib::helper`; and a closed + // consumer set closes `lib::used`. + assert!(g + .impact_report("lib::helper", &fx.scope(&["lib"])) + .unwrap() + .closed_in_scope()); + let closed = Scope { + consumers_closed: true, + ..fx.scope(&["lib"]) + }; + assert!(g + .impact_report("lib::used", &closed) + .unwrap() + .closed_in_scope()); +} + +/// Case 13: With the consumer set declared closed, every stored crate is a +/// possible consumer. One whose call into the symbol sits in an excluded +/// region contributes no position, and its exclusion must still be reported. +#[test] +fn a_closed_consumer_set_checks_consumers_without_observed_edges() { + let app = Krate { + name: "app", + rows: &[("DEFINES", "app::main", "app::main")], + files: &[("app.rs", "fn main() {}\n")], + }; + let fx = Fixture::new("closed-consumers", &[lib_crate(), app]); + let g = fx.open(); + let base = Scope { + consumers_closed: true, + ..fx.scope(&["lib", "app"]) + }; + // Silence twin: every stored crate fully covered. + assert!(g + .impact_report("lib::entry", &base) + .unwrap() + .closed_in_scope()); + let excluded = Scope { + excluded: vec![("app".into(), vec!["feature plugins".into()])], + ..base + }; + let r = g.impact_report("lib::entry", &excluded).unwrap(); + assert_eq!( + r.gaps, + vec![Gap::RegionsExcluded { + krate: "app".into(), + regions: vec!["feature plugins".into()], + }] + ); +} + +/// Case 14: A missing symbol in a crate whose harvest is incomplete carries +/// `HarvestIncomplete`: the failed harvest may have dropped its definition. +#[test] +fn a_missing_symbol_carries_its_crate_harvest_gap() { + let fx = Fixture::new("missing-harvest", &[lib_crate()]); + let scope = fx.scope(&["lib"]); + assert!(fx + .open() + .impact_report("lib::nope", &scope) + .unwrap() + .gaps + .is_empty()); + std::fs::write( + fx.store.join("lib.residuals.tsv"), + format!("{RES_HEADER}BODY_NOT_STRUCTURED\tlib::nope\n"), + ) + .unwrap(); + let r = fx.open().impact_report("lib::nope", &scope).unwrap(); + assert!( + matches!(r.gaps.as_slice(), [Gap::HarvestIncomplete { krate, .. }] if krate == "lib"), + "{:?}", + r.gaps + ); +}