Files
FabledScribe/tests/test_embedding_text.py
T
bvandeusen bbba0b3ae3
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 34s
CI & Build / Python tests (push) Successful in 50s
CI & Build / Build & push image (push) Successful in 26s
refactor(embeddings): one definition of the document a record is embedded as
`f"{title}\n{body}"` was written out four times. #2486 found three — the write
path, the recurring-task spawn, the startup backfill. The guard added here
found the fourth immediately, and it was the one that mattered most.

`dedup.find_duplicate_note` built the same string as a QUERY, compared against
embedded documents. Shaped differently from the corpus it searches, the gate
degrades silently: it still returns neighbours, just less apt ones, and nothing
says the query and the index stopped agreeing. The spawn path has the same
shape of risk — a recurring task embedded differently from everything else is
ranked against documents it doesn't match.

None of the four had diverged. That is what makes this worth doing now rather
than after: they are identical today, so collapsing them is a no-op, and the
whole point is that the next change to the shape can't hit three of four.

Which is imminent. #2486 measured a dev-log separating from five unrelated
dev-logs by 0.023 where a snippet separates by 0.153 — the difference being
that a snippet states its purpose twice in a short document. Whether that shape
is right is the open question; testing an alternative against four copies would
mean testing a shape that isn't the one in production. This is the precondition
the issue named.

The guard is source inspection, matching the f-string pattern rather than a
variable name, so a copy that renames its locals is still caught. A behavioural
test cannot see this: an inlined copy produces the same string today and
diverges the day the shape changes.

Refs #2486
2026-08-07 13:01:45 -04:00

82 lines
3.5 KiB
Python

"""The document shape a record is embedded as, and the guard that keeps it one.
WHY THIS EXISTS
`f"{title}\\n{body}"` was written out three times — the write path, the
recurring-task spawn, and the startup backfill. Identical copies of a formatting
rule are three chances to change one and not the others, and the spawn path is
the dangerous one: a recurring task embedded to a different shape than the rest
of the corpus is ranked against documents it doesn't match, and nothing reports
it. A wrong vector returns results; it just returns the wrong ones.
It is also the precondition for #2486. A dev-log's vector separates from five
unrelated dev-logs by 0.023 where a snippet separates by 0.153, and the leading
explanation is shape — a snippet states its purpose twice in a short document.
Testing an alternative against three copies would mean testing a shape that
isn't the one in production.
"""
from __future__ import annotations
import ast
import pathlib
from scribe.services.embeddings import embedding_text
SERVICES = pathlib.Path(__file__).resolve().parents[1] / "src" / "scribe"
def test_title_and_body_are_joined_by_a_newline():
assert embedding_text("A title", "A body") == "A title\nA body"
def test_a_bodyless_record_embeds_as_its_title_alone():
"""Not "title\\n" — the trailing separator would be a token's worth of noise
on the shortest documents, which are the ones least able to spare it."""
assert embedding_text("Just a title", "") == "Just a title"
assert embedding_text("Just a title", None) == "Just a title"
def test_an_empty_record_yields_an_empty_string():
"""Callers gate on falsiness to skip embedding entirely, so this must be
empty rather than a stray newline."""
assert embedding_text("", "") == ""
assert embedding_text(None, None) == ""
def test_surrounding_whitespace_is_stripped():
assert embedding_text(" A title ", " A body ") == "A title \n A body"
def test_nothing_else_builds_the_embedding_document_itself():
"""The guard. A fourth copy is how the first three happened.
Source inspection, because this is the shape no behavioural test catches:
an inlined copy produces the same string today and diverges silently the day
the shape changes. Matches the f-string pattern itself rather than a
variable name, so a copy that renames its locals is still caught.
"""
offenders = []
for path in SERVICES.rglob("*.py"):
source = path.read_text()
for node in ast.walk(ast.parse(source)):
if not isinstance(node, ast.JoinedStr):
continue
# An f-string whose literal parts are exactly a newline, with a
# substitution either side: `f"{x}\n{y}"`.
literals = [
v.value for v in node.values
if isinstance(v, ast.Constant) and isinstance(v.value, str)
]
subs = [v for v in node.values if isinstance(v, ast.FormattedValue)]
if literals == ["\n"] and len(subs) == 2:
offenders.append(f"{path.relative_to(SERVICES)}:{node.lineno}")
# embeddings.py holds the one definition.
offenders = [o for o in offenders if not o.startswith("services/embeddings.py")]
assert not offenders, (
f"these build the embedding document inline instead of calling "
f"embedding_text(): {offenders}. One definition — an inlined copy is "
f"ranked against a corpus it no longer matches the moment the shape "
f"changes, and nothing reports it (#2486)."
)