fix(dedup): a rule or preference create surfaces what it overlaps by meaning (#4134)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 56s
CI & Build / integration (push) Successful in 1m4s
CI & Build / Python tests (push) Failing after 1m16s
CI & Build / Build & push image (push) Skipped
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 56s
CI & Build / integration (push) Successful in 1m4s
CI & Build / Python tests (push) Failing after 1m16s
CI & Build / Build & push image (push) Skipped
find_duplicate_rule was title-only, on the stated premise that rules are not a semantic-retrieval surface - false since rules were embedded. A preference restating a rule under another title passed untouched, and since both kinds share one ranking, the weaker label could arrive alone. find_overlapping_rules queries semantic_search_rules with the rule_document shape, both kinds, in the scope the new record ranks in (global: every rule the caller owns; project: global + that project). All three MCP create doors call it before creating and return overlaps + overlap_note on the reply. It advises rather than blocks, on measurement: across 16 sampled records the nearest DISTINCT neighbour reached 0.853, while a true rewording scored 0.850. No threshold separates the bands, so the floor (0.80) sits below the restatement and the author judges. The stale docstring is corrected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -147,3 +147,20 @@ def _no_rule_arm():
|
||||
with patch("scribe.services.plugin_context.semantic_search_rules",
|
||||
AsyncMock(return_value=[])):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_rule_overlap():
|
||||
"""Stub the rule/preference create path's overlap check (#4134).
|
||||
|
||||
The same reason as _no_rule_arm, one door over: every create_rule /
|
||||
create_project_rule / create_preference now asks semantic_search_rules
|
||||
whether an existing record answers the same moment, so each existing
|
||||
rule-tool unit test would load the embedding model through a call it never
|
||||
meant to make. The check's own behaviour is tested in
|
||||
tests/test_rule_overlap_gate.py, which binds the real function at import
|
||||
time — before this patch runs — and stubs the search beneath it instead.
|
||||
"""
|
||||
with patch("scribe.services.dedup.find_overlapping_rules",
|
||||
AsyncMock(return_value=[])):
|
||||
yield
|
||||
|
||||
Reference in New Issue
Block a user