diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 6fd872a..fb5dc06 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -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": { diff --git a/plugin/skills/reusing-code/SKILL.md b/plugin/skills/reusing-code/SKILL.md index 1ae1c23..bfc9921 100644 --- a/plugin/skills/reusing-code/SKILL.md +++ b/plugin/skills/reusing-code/SKILL.md @@ -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 diff --git a/src/scribe/mcp/server.py b/src/scribe/mcp/server.py index bd19447..f0ee82c 100644 --- a/src/scribe/mcp/server.py +++ b/src/scribe/mcp/server.py @@ -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. diff --git a/src/scribe/mcp/tools/snippets.py b/src/scribe/mcp/tools/snippets.py index 1cc2871..748438e 100644 --- a/src/scribe/mcp/tools/snippets.py +++ b/src/scribe/mcp/tools/snippets.py @@ -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.