refactor(notes): a snippet's and lesson's stored title is its name; the trigger joins it only in the embedded document (milestone 427)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / integration (push) Successful in 52s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m35s
CI & Build / Build & push image (push) Successful in 32s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / integration (push) Successful in 52s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m35s
CI & Build / Build & push image (push) Successful in 32s
The title was `subject — trigger` because the stored title WAS the embedded one, and the join is what makes these kinds rank on the situation they apply to (#2485). Every surface that shows a title then showed the trigger too -- menus, lists and search rows ran to kilobytes. - embeddings.document_title(title, note_type, data, body) joins the trigger from `data` (body fallback) at embed time. Idempotent: an un-migrated composed title comes out the same, never doubled. The embed path, the startup backfill and the dedup gate's semantic signal all use it, so the embedded text -- and every vector -- is unchanged. - Writers store the subject: snippet create/update (service, REST, MCP) and lesson_document. Both compose_title helpers are removed. - Readers: dedup takes `data`; the menus strip the embedded title from a passage; list rows project `when_to_use`, which SnippetListView reads. - 0108 rewrites existing rows on an exact `' — ' || <own trigger>` suffix with raw SQL, leaving updated_at alone so the backfill does not re-embed the corpus for identical vectors. Downgrade recomposes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,10 +2,18 @@
|
||||
from scribe.services import snippets as s
|
||||
|
||||
|
||||
def test_compose_title_with_and_without_usage():
|
||||
assert s.compose_title("debounce", "rate-limit a callback") == "debounce — rate-limit a callback"
|
||||
assert s.compose_title(" debounce ", "") == "debounce"
|
||||
assert s.compose_title("debounce") == "debounce"
|
||||
def test_the_embedded_title_joins_the_trigger_the_stored_one_does_not_carry():
|
||||
"""Milestone 427: stored title = name; the trigger joins it at embed time,
|
||||
idempotently, so an old composed title comes out the same."""
|
||||
from scribe.services.embeddings import document_title
|
||||
|
||||
data = {"name": "debounce", "when_to_use": "rate-limit a callback"}
|
||||
assert document_title("debounce", "snippet", data) == "debounce — rate-limit a callback"
|
||||
assert document_title("debounce — rate-limit a callback", "snippet", data) == (
|
||||
"debounce — rate-limit a callback"
|
||||
)
|
||||
assert document_title("debounce", "snippet", {"name": "debounce"}) == "debounce"
|
||||
assert document_title("a — note", "note", data) == "a — note"
|
||||
|
||||
|
||||
def test_compose_tags_lowercases_language_and_dedups():
|
||||
@@ -32,7 +40,7 @@ def test_compose_body_bare_code_only():
|
||||
|
||||
|
||||
def test_parse_round_trips_a_composed_snippet():
|
||||
title = s.compose_title("useDebouncedRef", "debounce a reactive ref")
|
||||
title = "useDebouncedRef"
|
||||
body = s.compose_body(
|
||||
code="const x = 1", language="ts", signature="useDebouncedRef(v, ms)",
|
||||
when_to_use="debounce a reactive ref", repo="scribe",
|
||||
@@ -241,9 +249,9 @@ def test_data_and_body_round_trip_to_the_same_fields():
|
||||
name, when, sig, lang = ("debounce", "rate-limit a callback",
|
||||
"debounce(fn, ms)", "ts")
|
||||
locs = [{"repo": "web", "path": "src/util.ts", "symbol": "debounce"}]
|
||||
# compose_body takes no `name` — the name lives in the title — so the two
|
||||
# serializers get their own argument lists rather than a shared spread.
|
||||
title = s.compose_title(name, when)
|
||||
# compose_body takes no `name` — the name IS the title (milestone 427) — so
|
||||
# the two serializers get their own argument lists rather than a shared spread.
|
||||
title = name
|
||||
body = s.compose_body(code="const x = 1", language=lang, signature=sig,
|
||||
when_to_use=when, locations=locs, merged_from=[41, 42])
|
||||
tags = s.compose_tags(lang)
|
||||
|
||||
Reference in New Issue
Block a user