feat(snippets): body provenance — the cache-with-provenance half of the pointer model (#2688)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Failing after 21s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 53s
CI & Build / Build & push image (push) Successful in 28s

Decision #2686: the recorded location is the source of truth for a
snippet's code; the stored body is a cache of it. data.provenance now
records what the cache is a cache OF — commit_sha + fetched_at — as a
carried JSONB field following the verification precedent, so no
migration is needed and absence keeps today's exact semantics.

The rules: provenance follows the code (fresh SHA restamps it, a code
edit without one drops it, a metadata edit carries it); writes ABOUT
the code carry it — record_verification rebuilds data from scratch and
would otherwise erase it silently; an ok verdict at a known commit
restamps it, since the checker just proved the cache matches the source
there. verify_snippet verdicts also record the commit they ran at,
making "the repo moved on since the check" computable once the forge
integration lands. create/update/verify MCP tools take commit_sha
(git rev-parse HEAD — free for any session with a checkout).

Unit tests pin the compose/carry logic; real-Postgres integration tests
run create→verify→update end-to-end (#2663: DB paths get no
mocked-only coverage).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 12:00:40 -04:00
co-authored by Claude Fable 5
parent 8407368c0c
commit 1e7f66e72d
3 changed files with 268 additions and 2 deletions
+20
View File
@@ -105,6 +105,7 @@ async def create_snippet(
project_id: int = 0,
system_ids: list[int] | None = None,
force: bool = False,
commit_sha: str = "",
) -> dict:
"""Record a shape in the project's pattern library, so every later
instance starts from it instead of re-deriving it.
@@ -136,6 +137,12 @@ async def create_snippet(
proactively within their project; search finds them across projects.
system_ids: Ids of the project's Systems to associate this snippet with.
force: Bypass the near-duplicate gate (see below).
commit_sha: The commit the code was read at (`git rev-parse HEAD` — you
have the repo, so it's free). The recorded location is the source
of truth for the code and the stored body is a cache of it; this
stamps what the cache is a cache OF, so staleness is judgeable
later. Optional, but pass it whenever you're recording from a
checkout.
Returns the created snippet (including a parsed `snippet` field), OR — when a
duplicate already exists and force is false — {"duplicate": true,
@@ -181,6 +188,7 @@ async def create_snippet(
uid, name=name, code=code, language=language, signature=signature,
when_to_use=when_to_use, repo=repo, path=path, symbol=symbol,
locations=locations, tags=tags, project_id=project_id or None,
commit_sha=commit_sha,
)
if system_ids:
await systems_svc.set_record_systems(uid, note.id, system_ids)
@@ -295,6 +303,7 @@ async def find_duplicate_snippets(threshold: float = 0.0) -> dict:
async def verify_snippet(
snippet_id: int, status: str, detail: str = "", path: str = "",
commit_sha: str = "",
) -> dict:
"""Record whether a snippet's recorded location and code still match source.
@@ -329,6 +338,10 @@ async def verify_snippet(
path: The path you actually checked, if it differs from the recorded
one (e.g. you found the symbol at its new home). Defaults to the
recorded path.
commit_sha: The commit the working tree was at when you checked
(`git rev-parse HEAD`). An "ok" verdict with it also refreshes the
body's provenance — you just proved the cached code matches the
source at that commit.
Requires write access: a verdict changes how the record is presented, so
being able to read a snippet someone shared with you doesn't let you mark
@@ -337,6 +350,7 @@ async def verify_snippet(
uid = current_user_id()
note = await snippets_svc.record_verification(
uid, snippet_id, status=status, detail=detail, path=path,
commit_sha=commit_sha,
)
if note is None:
raise ValueError(
@@ -359,6 +373,7 @@ async def update_snippet(
tags: list[str] | None = None,
project_id: int = 0,
system_ids: list[int] | None = None,
commit_sha: str = "",
) -> dict:
"""Update a snippet. Only the fields you pass change.
@@ -374,6 +389,10 @@ async def update_snippet(
tags: Replaces the extra-tag set (language + "snippet" are re-derived).
project_id: 0 leaves it unchanged, -1 detaches it from its project, a
positive id moves it.
commit_sha: When you're updating the code from a checkout, the commit
it was read at (`git rev-parse HEAD`). Restamps the body's
provenance; changing the code WITHOUT it drops the old stamp,
since the new body no longer comes from that commit.
Editing someone else's snippet requires an editor or admin share from them.
A read-only share is refused with a message saying so — record your own
@@ -394,6 +413,7 @@ async def update_snippet(
signature=signature, when_to_use=when_to_use,
repo=repo, path=path, symbol=symbol,
locations=locations, tags=tags, project_id=project,
commit_sha=commit_sha or None,
)
except PermissionError as exc:
# Readable but not writable — surface the real reason, not "not found".