feat(6249): the write-path hint asks whether a new definition copies a close snippet
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 55s
CI & Build / integration (push) Successful in 1m2s
CI & Build / Python tests (push) Successful in 1m56s
CI & Build / Build & push image (push) Successful in 22s

The derive check matches by name, so a renamed copy of a recorded snippet
passed it and showed only as "similar" prior art. When a write introduces a
definition the file does not hold (shape_ledger.new_shapes_at) and an unseen
snippet on the menu clears the write-path floor by WRITEPATH_COPY_MARGIN (0.80
at the default floor), the hint now says to reuse it or extract the shared
shape before another copy. Names the derive check or the stamping feed already
spoke for are left to them. Covers recorded snippets only: the ledger keeps no
bodies to compare an unrecorded sibling against.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 20:14:41 -04:00
co-authored by Claude Opus 5.5
parent 0a4eb313fe
commit db2427a3dc
4 changed files with 148 additions and 0 deletions
+22
View File
@@ -665,6 +665,28 @@ async def test_write_time_derive_names_the_family_or_the_canon_for_a_name(seeded
assert await write_time_derive(pid, "v/B.vue", [("css", "log-empty")]) == []
@pytest.mark.integration
async def test_new_shapes_at_names_only_the_definitions_the_file_does_not_hold(seeded):
"""A shape the ledger holds at the path is an edit inside it; one it
does not hold there — even under a name living elsewhere — is new."""
from grimoire.services.shape_ledger import new_shapes_at
pid = seeded["pid"]
await sync_repo_shapes(pid, REPO, _defs(
("src/a.py", "sym", "load", "def load():", "def load():\n return 1"),
("src/b.py", "sym", "save", "def save():", "def save():\n return 2"),
("v/A.vue", "css", "log-empty", ".log-empty {", ".log-empty { color: red }"),
), seen_marker="m1")
assert await new_shapes_at(pid, "src/a.py", [("sym", "load"), ("sym", "save")]) == [
("sym", "save"),
]
# CSS compares without the leading dot, as the rest of the ledger does.
assert await new_shapes_at(pid, "v/A.vue", [("css", ".log-empty")]) == []
assert await new_shapes_at(pid, "src/new.py", [("sym", "load")]) == [("sym", "load")]
assert await new_shapes_at(pid, "src/a.py", [("sym", "")]) == []
@pytest.mark.integration
async def test_derive_new_names_the_copy_that_joined_a_family_since_the_stamp(seeded):
"""The first sync seeds one `slug`; a later sync adds an identical