Decision #2686: snippets are the project's pattern library, not a dedup net. The floor, the reusing-code skill, and the snippet tool docstrings now state the proactive model — record every shape the first time it is built, with no will-it-recur judgment, and start later instances from the recorded shape; second-copy consolidation stays as the backstop. The floor guard test pins all three elements (tool, first-build trigger, backstop) so the model cannot silently regress to the reactive wording. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.6 KiB
name, description
| name | description |
|---|---|
| reusing-code | 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 plainsearch) — a matching one may already exist, in this project or another.list_snippetssearches every project by default; that's deliberate, since a helper you need here was quite possibly written somewhere else. Narrow withproject_idonly 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?" —pathmatches the exact file or anything beneath it, sopath="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 withqto ask both at once. - If a snippet fits, pull it in full with
get_snippet(id)and reuse it — itslocationpoints 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_snippetit 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.
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_snippetwhile 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.
- name — what it's called, e.g.
- Record the reference implementation, not every call site — one good entry
per reusable thing. If it already exists,
update_snippetit 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.
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.