Skip to content

Commit 13bc2c6

Browse files
Your Nameclaude
andcommitted
docs+test(pipeline): PR#9 final polish -- CallSiteKey completeness + identity_migration design note
Two small, low-risk finishing touches now that slices A-D + the churn regression test have all landed and been verified: - golden_graph_equivalence.rs's CallSiteKey gains callee_start_rel/ callee_end_rel alongside the pre-existing absolute byte fields, per the plan's own explicit instruction to update this struct in lockstep with the v3 schema. The existing suite already passed without this (slice D's position-refresh fix keeps callee_start_byte/callee_end_byte always current, which was sufficient for the mutation-round tests to catch the real bug they caught), but comparing the relative columns too closes a theoretical gap: a hypothetical divergence in relative-offset computation specifically, decoupled from the absolute one. - identity_migration.rs::needs_call_site_identity_baseline gains a doc comment explaining why it deliberately does NOT gain a v2-vs-v3 check the way it already has one for v1-vs-v2: a permanent, by-design mix of v2 (module-level calls, no real enclosing symbol to be relative to) and v3 (calls inside a real function/method) is the correct steady state, and the churn v3 fixes only matters for files that actually get reindexed -- reconcile_call_sites already upgrades a v2 row to v3 organically on the next edit to its file, at the cost of exactly one identity transition, cheaper and lower-risk than a global forced rebuild that would churn every proof in the database at once for files that may never be touched again anyway. No code/behavior change. This closes out PR#9 (docs/plans/2026-08-19-evidence-architecture- execution-plan.md Part E): position-independent call-site identity (v3), upsert-by-identity reconciliation fixing the actual proof-churn root cause, and a regression test proving the plan's own DoD is met. Verified: cargo build/clippy -p calm-core --all-targets clean, cargo test -p calm-core 1249 passed/0 failed/12 ignored including both golden_equivalence_{continued,incremental}_vs_fresh_across_mutation_rounds, cargo fmt clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent ab0f161 commit 13bc2c6

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

crates/calm-core/src/indexer/pipeline/identity_migration.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ use super::{GraphMode, ReindexSummary, now_secs};
4242
/// identity predates D4. Incremental indexing cannot repair these rows because
4343
/// their file hashes are unchanged, so it must take the full transactional
4444
/// baseline path instead of reporting a no-op.
45+
///
46+
/// PR#9 (docs/plans/2026-08-19-evidence-architecture-execution-plan.md Part
47+
/// E, position-independent v3 identity) deliberately does NOT extend this
48+
/// predicate to force a v2->v3 baseline the same way. Two reasons: (1) a
49+
/// permanent, by-design mix of v2 (module-level calls with no real
50+
/// enclosing symbol to be relative to) and v3 (calls inside a real
51+
/// function/method) rows is the correct steady state, not incomplete
52+
/// migration -- there is no "fully migrated" endpoint to detect the way
53+
/// v1->v2 has one; (2) the churn v3 fixes only matters for a call_sites
54+
/// row that actually gets RECONCILED (i.e. its file gets reindexed) --
55+
/// `extraction::reconcile_call_sites` already upgrades a v2 row to v3
56+
/// organically the next time its file changes, at the cost of exactly one
57+
/// identity transition (the old v2-keyed row won't match the new v3-keyed
58+
/// extraction, so it's replaced once) -- cheaper and lower-risk than a
59+
/// global forced rebuild that would churn every proof in the database in
60+
/// one pass on upgrade, for files that may never be touched again anyway.
61+
/// A file that's never reindexed was never going to churn regardless of
62+
/// which identity version its rows carry.
4563
pub(super) fn needs_call_site_identity_baseline(conn: &Connection) -> rusqlite::Result<bool> {
4664
conn.query_row(
4765
"SELECT EXISTS(

crates/calm-core/tests/golden_graph_equivalence.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ struct CallSiteKey {
2828
identity_version: i64,
2929
callee_start_byte: Option<i64>,
3030
callee_end_byte: Option<i64>,
31+
// PR#9 (docs/plans/2026-08-19-evidence-architecture-execution-plan.md
32+
// Part E): v3's relative-to-enclosing-symbol offsets, alongside the
33+
// pre-existing absolute ones above -- both compared, so equivalence
34+
// catches a divergence in EITHER identity scheme, not just the
35+
// absolute one v2 already covered.
36+
callee_start_rel: Option<i64>,
37+
callee_end_rel: Option<i64>,
3138
source_file_hash: Option<String>,
3239
}
3340

@@ -78,7 +85,7 @@ fn graph_fingerprint(conn: &Connection) -> (BTreeSet<EdgeKey>, BTreeMap<String,
7885
ep.definition_snapshot, ep.call_site_identity_version, \
7986
CASE WHEN ep.id IS NULL THEN NULL \
8087
WHEN ep.graph_generation = graph.generation THEN 1 ELSE 0 END, \
81-
ep.status \
88+
ep.status, cs.callee_start_rel, cs.callee_end_rel \
8289
FROM call_edges ce \
8390
LEFT JOIN call_sites cs ON cs.id = ce.call_site_id \
8491
LEFT JOIN file_index fi ON fi.path = cs.from_path \
@@ -100,6 +107,8 @@ fn graph_fingerprint(conn: &Connection) -> (BTreeSet<EdgeKey>, BTreeMap<String,
100107
let callee_start_byte: Option<i64> = r.get(15)?;
101108
let callee_end_byte: Option<i64> = r.get(16)?;
102109
let call_site_source_file_hash: Option<String> = r.get(17)?;
110+
let call_site_start_rel: Option<i64> = r.get(28)?;
111+
let call_site_end_rel: Option<i64> = r.get(29)?;
103112
let call_site = call_site_path.map(|path| CallSiteKey {
104113
path,
105114
enclosing_symbol: enclosing_symbol.unwrap_or_default(),
@@ -108,6 +117,8 @@ fn graph_fingerprint(conn: &Connection) -> (BTreeSet<EdgeKey>, BTreeMap<String,
108117
identity_version: call_site_identity_version.unwrap_or_default(),
109118
callee_start_byte,
110119
callee_end_byte,
120+
callee_start_rel: call_site_start_rel,
121+
callee_end_rel: call_site_end_rel,
111122
source_file_hash: call_site_source_file_hash,
112123
});
113124
let provider: Option<String> = r.get(18)?;

0 commit comments

Comments
 (0)