fix(shapes): the signature basis admits the band true instances score in (#4306)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 57s
CI & Build / Python tests (push) Successful in 1m44s
CI & Build / Build & push image (push) Successful in 27s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 57s
CI & Build / Python tests (push) Successful in 1m44s
CI & Build / Build & push image (push) Successful in 27s
Measured over 459 judged instance rows against every same-family canon: true instances score 1.0 or ~0.795 (a model whose mixin list differs from the canon's), and 0.8 cut the second band entirely. The proposal is read before it is confirmed, so the floor admits it: 0.75 takes every measured true row, at 35 wrong-canon pairings instead of 14. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -1570,12 +1570,22 @@ def _semantic_priority(row) -> tuple:
|
|||||||
# not evidence (see _SEMANTIC_LIMIT) — but the proposals themselves did not
|
# not evidence (see _SEMANTIC_LIMIT) — but the proposals themselves did not
|
||||||
# change, so no re-examination is owed; a stale miss basis is inert.
|
# change, so no re-examination is owed; a stale miss basis is inert.
|
||||||
# v5: the semantic arm's floor dropped from 0.8 to the write-path floor (#4208),
|
# v5: the semantic arm's floor dropped from 0.8 to the write-path floor (#4208),
|
||||||
# so rows it examined and found nothing for must be read once more.
|
# and the signature floor from 0.8 to 0.75 (#4306), so rows examined and
|
||||||
|
# found nothing for must be read once more.
|
||||||
_PROPOSER_VERSION = 5
|
_PROPOSER_VERSION = 5
|
||||||
# Signature resemblance floor, name blanked (difflib ratio) — and a length
|
# Signature resemblance floor, name blanked (difflib ratio) — and a length
|
||||||
# floor, because `def NAME():` resembles `def NAME(x):` at 0.95 while saying
|
# floor, because `def NAME():` resembles `def NAME(x):` at 0.95 while saying
|
||||||
# nothing; a family shape has parameters to resemble.
|
# nothing; a family shape has parameters to resemble.
|
||||||
_SIGNATURE_FLOOR = 0.8
|
#
|
||||||
|
# A proposal is read before it is confirmed, so this admits the band where
|
||||||
|
# true instances live rather than the band where nothing is wrong (#4306).
|
||||||
|
# Measured 2026-09-22 over 459 judged instance rows against every same-family
|
||||||
|
# canon: true instances score 1.0 or ~0.795 (a model class whose mixin list
|
||||||
|
# differs from the canon's), and 0.8 cut the whole second band. At 0.75 all
|
||||||
|
# of them clear; the price is `async def NAME(user_id: int, …) -> dict`
|
||||||
|
# look-alikes (35 wrong-canon pairings vs 14 at 0.8), which read as wrong at
|
||||||
|
# a glance. Below 0.75 the next true row is at 0.6 behind 150+ wrong ones.
|
||||||
|
_SIGNATURE_FLOOR = 0.75
|
||||||
_SIGNATURE_MIN_LEN = 30
|
_SIGNATURE_MIN_LEN = 30
|
||||||
# Textual containment needs enough substance to mean anything.
|
# Textual containment needs enough substance to mean anything.
|
||||||
_TEXT_FLOOR = 40
|
_TEXT_FLOOR = 40
|
||||||
|
|||||||
@@ -180,6 +180,22 @@ def test_signature_similarity_blanks_the_names():
|
|||||||
assert sim("def helper(x):", "helper", "def make_app():", "make_app") == 0.0
|
assert sim("def helper(x):", "helper", "def make_app():", "make_app") == 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_model_with_a_different_mixin_list_is_proposed_against_the_model_canon():
|
||||||
|
"""The band 0.8 cut (#4306). Measured over judged instances: a model class
|
||||||
|
whose mixins differ from the canon's scores ~0.795 against it — a true
|
||||||
|
instance, and the proposal is read before it is confirmed, so the floor
|
||||||
|
must admit it."""
|
||||||
|
from scribe.services.shape_ledger import Canon, _norm_text, match_canon
|
||||||
|
|
||||||
|
model = Canon(44, "sym", "Gadget", (("src/app/models/gadget.py", "Gadget"),),
|
||||||
|
"class Gadget(Base, TimestampMixin, SoftDeleteMixin):",
|
||||||
|
_norm_text(""), 0, "python")
|
||||||
|
hit = match_canon("sym", "src/app/models/widget.py", "Widget",
|
||||||
|
"class Widget(Base, TimestampMixin):", " pass", [model])
|
||||||
|
assert hit is not None and hit[:2] == (44, "signature")
|
||||||
|
assert 0.75 <= hit[2] < 0.8
|
||||||
|
|
||||||
|
|
||||||
def test_text_containment_is_whitespace_insensitive_with_a_floor():
|
def test_text_containment_is_whitespace_insensitive_with_a_floor():
|
||||||
from scribe.services.shape_ledger import text_contains
|
from scribe.services.shape_ledger import text_contains
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user