Files
FabledScribe/plugin/skills/reusing-code/SKILL.md
T
bvandeusenandClaude Fable 5 9f1a52a035
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
feat(ledger): audits write rows, not prose — instruction surfaces carry the classification duty (#2790, milestone 294 step 4)
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>
2026-08-19 21:16:04 -04:00

133 lines
8.0 KiB
Markdown

---
name: reusing-code
description: Use when you're about to build ANY shape — a component, control, route handler, service class, helper, test scaffold — search recorded snippets FIRST and start from the recorded shape instead of re-solving it. And the FIRST time a shape is built, record it as a snippet so every later instance starts from it. Triggers on "write a util/helper", "I need a function that…", "let me add a component/button/field/route", or having just built the first instance of anything.
---
# Reusing code — the pattern library
Snippets are the project's **pattern library**, not a dedup net. Each records a
named shape — with its language, signature, canonical location (repo · path ·
symbol), a one-line *"when to reach for it,"* and the code — so every later
instance STARTS from the recorded shape: buttons start from the button shape,
fields from the field shape, and "special" is a deliberate, named exception
rather than drift. A mature project's snippet corpus reads as a map of every
shape in it, from the humblest control to the most complex subsystem pattern.
Snippets are ordinary embedded notes, so a recorded one also surfaces on its own
through recall/auto-inject; this skill is the active reflex around that.
## Before you build any shape — search first
- About to build a component, control, route handler, service class, utility,
hook, formatter, adapter, or test scaffold?
**Search snippets before writing it.** `list_snippets(q="…")` (or a plain
`search`) — a matching one may already exist, in this project or another.
`list_snippets` searches every project by default; that's deliberate, since a
helper you need here was quite possibly written somewhere else. Narrow with
`project_id` only when you specifically want this project's own.
- **About to edit an existing file? Ask by place, not just by meaning.**
`list_snippets(repo="…", path="…")` answers "what canonical helpers are already
recorded here?" — `path` matches the exact file or anything beneath it, so
`path="frontend/src"` covers the whole tree. Cheaper and sharper than a
wording search when you already know where the code is going, and it catches
the helper you'd otherwise duplicate a few lines down. `symbol="…"` narrows
further, and all three must match the same recorded location. Combine with `q`
to ask both at once.
- If a snippet fits, pull it in full with `get_snippet(id)` and reuse it — its
`location` points at the reference implementation. Adapt, don't re-derive.
- If auto-inject already surfaced a snippet title that looks relevant, that's
your cue to `get_snippet` it rather than start from scratch.
- **Prior art offered beside a write is not noise — read it.** When Scribe notes
that a snippet is already recorded for the file you just wrote or edited, open
it before you go any further. Either it's the helper you were about to
duplicate — reuse it and drop yours — or it isn't, and the record needs the new
location adding. Both are cheaper now than after the duplicate settles in.
- **A `[records this file]` hint is a duty, not a menu.** When the hint says a
snippet records the very file you're editing, the record's freshness is now
YOUR edit's responsibility: if the edit changes the recorded shape,
`update_snippet(id, code=…)` with the new form as part of the same task; if
it doesn't, `verify_snippet(id, status="ok", commit_sha=…)` costs one call
and re-stamps the record as checked. Scribe never reads the repo — this
moment, in the session that has the context, is the only place the record
gets kept true.
## The first time a shape is built — record it
- Just built the FIRST instance of anything with a shape — a component, a
field, a route, a service pattern, a scaffold? Record it with
`create_snippet` while it's fresh. Do **not** stop to judge whether it will
recur: the builder of the first instance can never know, and a missed record
is invisible until it resurfaces as an uninformed duplicate. Over-recording
is safe — dead weight shows up in the usage counters and can be pruned;
under-recording has no signal at all. The record is cheap — these fields:
- **name** — what it's called, e.g. `useDebouncedRef`.
- **code** — the implementation.
- **when_to_use** — one sharp line on when to reach for it. This becomes part
of the title, so it's what a later recall menu shows — make it earn the pull.
- **language**, **signature**, and **location** (`repo` / `path` / `symbol`)
so the recorded copy points back at the canonical source.
- **project_id** / **system_ids** to associate it with the work it belongs to.
- Record the *reference* implementation, not every call site — one good entry
per reusable thing. If it already exists, `update_snippet` it instead of
recording a second copy (the create gate will flag a near-duplicate anyway).
## A shared snippet is a suggestion, not a standard
Scribe is multi-user, so a search can return snippets other people own. Those
come back marked `shared: true` with an `owner`.
- Read one as **that person's suggestion**, not as the way things are done here.
Judge the code on its merits before reaching for it.
- Say whose it is when you propose it — "there's a snippet from *alex* that does
this" — so the operator can weigh the source, not just the code.
- Don't treat it as the house pattern, and don't build on it at scale, without
the operator agreeing to adopt it.
- Snippets shared directly with the operator only appear when you search for
them, never in a plain `list_snippets` — so anything ambient is genuinely
theirs.
## Keep the record honest
A recorded snippet is offered as prior art on every matching turn, so a wrong
one costs more than a missing one.
- Details gone stale — a renamed symbol, a moved file, a signature that's
changed? Fix it with `update_snippet`. Passing an **empty string** clears a
field, so a wrong signature or location can be removed, not just written over.
- Recorded something that turned out not to be reusable, or that no longer
exists? Retire it with `delete_snippet` — it goes to the trash and can be
restored. Don't leave it competing for attention.
## Found the same thing in several places — unify it
When you notice the same reusable thing recorded (or written) as several
one-offs, don't leave the duplicates competing in recall — **merge them**.
`merge_snippets(canonical_id, [other_ids])` keeps one canonical record, folds in
the others' call sites as locations, and retires the duplicates to the trash.
The result is a single entry that shows every place the thing is used — which is
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
scale, the cost is an application whose buttons, fields, and services each
exist in four diverging shapes. Recording every shape once — with a location
and a crisp "when to use" — means every later session starts from the pattern
library instead of re-deriving it. Search before building; record every shape
at first build.