feat(ledger): audits write rows, not prose — instruction surfaces carry the classification duty (#2790, milestone 294 step 4)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 26s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 56s
CI & Build / Build & push image (push) Successful in 27s

verify_snippet docstring: consumers enumerated while checking are
classify_shapes instance rows; detail keeps the WHY and what changed,
nothing that belongs in a row. The MCP _INSTRUCTIONS REUSE bullet gains
"classify shapes against canon — a consumer map is rows, never prose"
(budget rebalanced to 1,998/2,000: the rules bullet lost its historical
push-optimisation clause, the task-note line tightened). The reusing-code
skill gains the full contract: instance/variant/exempt with required
reasons, list_shapes(status=unclassified) as the standing todo, and the
derive-one-first rule for repeating shapes with no canon. Plugin 0.1.32.

The operator-side halves of this step live outside the repo: the Drift
Audit process gained step 7 (classify what the walk proved) and the DRY
Pass s9 now sends consumer maps to the ledger with the note keeping only
the narrative. The Forge P7 backfill payload is enumerated and parked on
task 2790 — it fires after the next deploy + coverage refresh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 21:16:04 -04:00
co-authored by Claude Fable 5
parent 5265d11a6a
commit 9f1a52a035
4 changed files with 28 additions and 6 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "scribe",
"description": "Scribe system-of-record for Claude Code: MCP tools over your notes/tasks/projects/rules, a session-start push channel that surfaces your always-on rules + active-project context, process-skills (writing-plans, systematic-debugging, verification, brainstorming, reusing-code), and your saved Scribe Processes auto-surfaced as skills (/scribe:sync). Replaces superpowers + file-memory with one app-backed plugin.",
"version": "0.1.31",
"version": "0.1.32",
"author": { "name": "Bryan Van Deusen" },
"mcpServers": {
"scribe": {
+15
View File
@@ -107,6 +107,21 @@ The result is a single entry that shows every place the thing is used — which
exactly the signal that it was worth consolidating. This is the cure the create
gate only hints at when it blocks a near-duplicate.
## Consumer maps are rows, never prose
Every enumerated relationship between code and canon belongs in the shape
ledger, not in a sentence. When you establish that call sites route through a
canonical helper — during an audit, a verify pass, or a consolidation —
record each consuming definition with
`classify_shapes(project_id, [{path, symbol, status: "instance", snippet_id}])`.
A deliberate departure is a `"variant"` (reason required — the why IS the
record); a judged one-off is `"exempt"` (reason required). Prose in a
verification detail cannot be sorted, queried, or diffed; rows are what make
"what uses this?" answerable forever. `list_shapes(project_id,
status="unclassified")` is the standing todo — and N same-shaped occurrences
matching no canon means derive one first (consolidate, `create_snippet`,
then classify the rest against it), never N loose classifications.
## Why this pays off
A one-off written a second time is the cost this avoids — and at project
+5 -5
View File
@@ -49,15 +49,15 @@ Hierarchy: Project -> Milestone -> Task/Note. The map, by purpose:
- WHERE work happens: Systems. Tag records with system_ids as you write;
create_system when the area is unmodelled.
- HOW to work: rules are pull-only and binding — call list_always_on_rules()
yourself at session start; a push that also delivered them was an
optimisation, not the bridge.
yourself at session start.
- UI: the project's design system is binding — resolve_design_system /
get_design_system_stylesheet before hand-writing a value.
- REUSE: search snippets before writing a helper; record what you build with
create_snippet. Saved procedures are Processes (follow verbatim). Deletes
are trash-recoverable.
create_snippet; classify shapes against canon (classify_shapes) — a
consumer map is rows, never prose. Saved procedures are Processes (follow
verbatim). Deletes are trash-recoverable.
A task is a note with status; *_note tools for notes, *_task for tasks.
A task is a note with status (*_note vs *_task tools).
Creates are duplicate-gated: a near-match BLOCKS and returns the existing
id — update it, don't force. shared:true records are another user's — a
suggestion, not the operator's settled practice.
+7
View File
@@ -352,6 +352,13 @@ async def verify_snippet(
"moved to services/knowledge.py"). It's what makes the record fixable later
by someone who wasn't here, so write it for them, not as a status echo.
CONSUMERS you enumerate while checking ("all N call sites still route
through it") are ledger rows, not detail prose: classify each consuming
definition as an `instance` of this snippet with classify_shapes — prose
cannot be sorted, queried, or diffed (note 2786's lesson), and the rows
are what make "what uses this?" answerable forever. `detail` keeps the
WHY and what changed, nothing that belongs in a row.
A verdict expires automatically if the snippet is edited afterwards: it is
stamped with a hash of the code it was checked against, so it can never go
on vouching for code nobody checked. Re-verify after fixing a record.