feat(ledger): write-path stamping — a pulled canon the session then instantiates lands as a hook instance row (#2791, milestone 294 step 5)
CI & Build / Plugin hooks (push) Failing after 2s
CI & Build / Python lint (push) Successful in 4s
CI & Build / integration (push) Failing after 28s
CI & Build / TypeScript typecheck (push) Successful in 36s
CI & Build / Python tests (push) Successful in 1m5s
CI & Build / Build & push image (push) Successful in 39s
CI & Build / Plugin hooks (push) Failing after 2s
CI & Build / Python lint (push) Successful in 4s
CI & Build / integration (push) Failing after 28s
CI & Build / TypeScript typecheck (push) Successful in 36s
CI & Build / Python tests (push) Successful in 1m5s
CI & Build / Build & push image (push) Successful in 39s
The prior-art hook now names the shapes being written (shapes=kind:name — every definition in the payload, or the one enclosing an Edit found by walking the file upward) and the server stamps them as instance rows when the session PULLED a snippet inside PULL_WINDOW that the payload references by symbol or that the semantic arm scored for this very payload. classified_by=hook, evidence in reason; never overrides a judgment or a canonical row, overridable by classify_shapes. Offered-but-unopened stamps nothing. Pulled-and-already-seen snippets stay in the semantic query as evidence without re-entering the deduped menu. A brand-new shape gets a provisional row the next sync confirms or vanishes. Read-scoped keys get the hint, never the stamp. Plugin 0.1.34. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,3 +82,56 @@ def test_classify_and_list_are_mounted_as_mcp_tools():
|
||||
mcp = build_mcp_server()
|
||||
for name in ("classify_shapes", "list_shapes", "refresh_pattern_coverage"):
|
||||
assert mcp._tool_manager.get_tool(name) is not None
|
||||
|
||||
|
||||
# --- step 5: the write-path feed's evidence tests (pure) ---------------------
|
||||
|
||||
|
||||
def test_symbol_reference_is_word_bounded_and_kind_aware():
|
||||
from scribe.services.shape_ledger import references_symbol as ref
|
||||
|
||||
code = "const ok = await confirmed({ title: 'x' });\nif (!ok) return;"
|
||||
assert ref(code, "confirmed", "sym")
|
||||
assert not ref(code, "confirm", "sym") # prefix never claims the call
|
||||
assert not ref("", "confirmed", "sym")
|
||||
assert not ref(code, "", "sym")
|
||||
# CSS: the class as a selector or inside a class attribute; dashes are part
|
||||
# of the name, so `btn` must not claim `btn-primary`.
|
||||
html = '<button class="btn btn-primary">Go</button>'
|
||||
assert ref(html, ".btn-primary", "css")
|
||||
assert ref(html, "btn-primary", "css")
|
||||
assert ref(".btn-primary { color: red }", ".btn-primary", "css")
|
||||
assert not ref('<button class="btn-primary">', ".btn", "css")
|
||||
assert ref('<button class="btn-primary btn">', ".btn", "css")
|
||||
|
||||
|
||||
def test_snippet_kind_reads_the_symbol_then_the_language():
|
||||
from scribe.services.shape_ledger import snippet_kind
|
||||
|
||||
assert snippet_kind(".btn-primary", "css") == "css"
|
||||
assert snippet_kind(".btn-primary", "") == "css"
|
||||
assert snippet_kind("confirmed", "typescript") == "sym"
|
||||
assert snippet_kind("", "scss") == "css" # whole-stylesheet record
|
||||
assert snippet_kind("", "python") == "sym"
|
||||
|
||||
|
||||
def test_route_shapes_param_parses_capped_and_deduped():
|
||||
from scribe.routes.plugin import _SHAPES_CAP, _parse_shapes
|
||||
|
||||
assert _parse_shapes("css:btn-primary,sym:onTrash") == [
|
||||
("css", "btn-primary"), ("sym", "onTrash"),
|
||||
]
|
||||
assert _parse_shapes(" sym:a , sym:a ,bogus:x,sym:,:,") == [("sym", "a")]
|
||||
assert _parse_shapes("") == []
|
||||
many = ",".join(f"sym:f{i}" for i in range(40))
|
||||
assert len(_parse_shapes(many)) == _SHAPES_CAP
|
||||
|
||||
|
||||
def test_hook_is_a_server_internal_classifier():
|
||||
"""`hook` is in the status vocabulary but NOT a via a caller may claim —
|
||||
a classify_shapes call saying via="hook" would launder judgment as
|
||||
evidence (the reverse of the stamping rule's point)."""
|
||||
from scribe.services.shape_ledger import _CALLER_VIAS
|
||||
|
||||
assert "hook" in SHAPE_CLASSIFIERS
|
||||
assert "hook" not in _CALLER_VIAS
|
||||
|
||||
Reference in New Issue
Block a user