Skip to content

APIDRIFT-12: similarity metric evaluated + rejected (cosine-over-counts) - #7

Open
nixpt wants to merge 4 commits into
mainfrom
claude/status-check-zaai3m
Open

nixpt wants to merge 4 commits into
mainfrom
claude/status-check-zaai3m

Conversation

@nixpt

@nixpt nixpt commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Evaluated cosine-over-word-counts (genome::Anatomy::structural_similarity
pattern) against the two-tier rename detector (sigs_match_modulo_rename +
edit_distance ≤ 8). Decision: reject.

sigs_match_modulo_rename already handles every pure-rename case at any sig
length. edit_distance ≤ 8 covers the remaining short co-change cases. The
only gap where cosine would differ—name change paired with a large sig
co-change (edit_dist > 8)—is intentionally left as two separate items: a
rename folded over a significant sig change hides the delta callers must
also address. Conservative is correct per project rules.

Decision documented in the detect_renames doc comment. Two regression
tests pin the behaviour: long_sig_pure_rename_is_confident_without_cosine
(sigs_match_modulo_rename covers long sigs; cosine redundant) and
rename_plus_large_sig_change_stays_separate (intentional gap preserved).

Relatedness ranking (acceptance criterion 3) stays gated on APIDRIFT-11.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_015wntaW4q23cpqiwoCUbypg

Evaluated cosine-over-word-counts (genome::Anatomy::structural_similarity
pattern) against the two-tier rename detector (sigs_match_modulo_rename +
edit_distance ≤ 8). Decision: reject.

sigs_match_modulo_rename already handles every pure-rename case at any sig
length. edit_distance ≤ 8 covers the remaining short co-change cases. The
only gap where cosine would differ—name change paired with a large sig
co-change (edit_dist > 8)—is intentionally left as two separate items: a
rename folded over a significant sig change hides the delta callers must
also address. Conservative is correct per project rules.

Decision documented in the detect_renames doc comment. Two regression
tests pin the behaviour: long_sig_pure_rename_is_confident_without_cosine
(sigs_match_modulo_rename covers long sigs; cosine redundant) and
rename_plus_large_sig_change_stays_separate (intentional gap preserved).

Relatedness ranking (acceptance criterion 3) stays gated on APIDRIFT-11.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015wntaW4q23cpqiwoCUbypg
BRO-98 landed as two PRs (#84 PR1, #85 PR2) on 2026-09-15. BRO-113 (#81)
followed at ~09:12. BackendEvent shape on dev is now settled (SessionUpdate,
PromptStarted/Finished, Permission, HumanInput, Usage, ModelChanged alongside
the existing Output/Disconnected). Both blockers are gone.

Ticket status updated to ready; next gate is APIDRIFT-8b (bro-tui ledger
embed) so the snapshot to pin against exists before the consumer check lands.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015wntaW4q23cpqiwoCUbypg
8b landed on nixpt/bro-cli branch agent/claude/APIDRIFT-8b.
BackendEvent snapshot hash a17f936. APIDRIFT-9 now unblocked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015wntaW4q23cpqiwoCUbypg
…syn usage scan

Adds the consumer half of the embedded ledger (design doc § "The consumer
check, concretely"):

- `crates/api-drift-ledger/src/config.rs` — parse `api-drift.toml`
  ([[upstream]] name/surface/source/pin)
- `crates/api-drift-ledger/src/usage.rs` — syn visitor: walks consumer
  `src/` for `EnumType::Variant` paths (match arms, constructors, use
  paths), returns file:line per match; proc-macro2 span-locations for
  accurate line numbers
- `crates/api-drift-ledger/src/consumer.rs` — `entries_after_pin` follows
  the ledger chain from pin → head; intersects breaks with usage sites;
  `run()` panics with a call-site-scoped report on any hit
- `crates/api-drift-ledger/src/lib.rs` — `check!` macro (consumer feature)
  generates `fn api_drift_consumer_check()` calling `consumer::run`
- `crates/api-drift-ledger/tests/consumer_check.rs` — 4 integration tests:
  clean pin, added-variant-no-site passes, removed-variant-at-call-site
  panics with agent.rs:7, empty-pin sees all entries
- `consumer` feature: syn 2 + proc-macro2 span-locations + toml 0.8

All pass: `cargo test --all-features`, clippy -D warnings, stable fmt.

bro-desktop embed: add `api-drift-ledger` with `features = ["consumer"]`
dev-dep, write `api-drift.toml` pinned at sha256:a17f936… once bro-cli#92
merges, invoke `check!()`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015wntaW4q23cpqiwoCUbypg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants