feat(shapes): the practice is written where it is read, and the coverage line measures the slip (milestone 439 step 6)
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 47s
CI & Build / Python tests (push) Successful in 1m39s
CI & Build / Build & push image (push) Successful in 29s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 16s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 47s
CI & Build / Python tests (push) Successful in 1m39s
CI & Build / Build & push image (push) Successful in 29s
- reusing-code: "Before the turn ends — say what you built" — the four verdicts, the one classify_shapes(repo=…) call, and the component file as a shape. Description names the end-of-turn moment. - shape-accounting: the writer judges; audits are the check that it held. The write path SUGGESTS (no more hook instances); component file rows and whole-file canon described; scoped covers Svelte too. - _INSTRUCTIONS reuse line: "before the turn ends, say what you built (create_snippet the reusable, classify_shapes the rest)" — 1570/1600. - Coverage line: "written-shape check (7d): N turns checked, M asked, K left unjudged", from the Stop hook's recorded outcomes; silent until the question has been put. - test_guidance_ownership pins the new topic on reusing-code. - prior-art hook header no longer says it stamps instance rows. Plugin version minted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "scribe",
|
||||
"description": "Scribe for Claude Code: connects the scribe MCP server, adds the hooks that deliver live project state and relevant records at the right moment, ships the shared client-neutral Scribe skills (using-scribe, writing-plans, reporting-back, systematic-debugging, verification, brainstorming, reusing-code, shape-accounting), and syncs your saved Scribe Processes as skills (/scribe:sync).",
|
||||
"version": "2026.10.01.1245",
|
||||
"version": "2026.10.01.1246",
|
||||
"author": {
|
||||
"name": "Bryan Van Deusen"
|
||||
},
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
# It is also the shape ledger's write-path feed (#2791): it names the
|
||||
# definitions being written (`shapes=`), and the server — only when the
|
||||
# session has PULLED a snippet this code references or resembles — records
|
||||
# them as instance rows, classified_by=hook. Evidence, not judgment; the
|
||||
# context line says what landed so a wrong stamp is corrected in the moment.
|
||||
# it as a PROPOSAL on them ("looks like #N"), never a status (milestone 439).
|
||||
# The agent's own end-of-turn judgment is the verdict; the same names go to
|
||||
# the written-shapes ledger the Stop hook asks about.
|
||||
#
|
||||
# NEVER BLOCKS. It returns `additionalContext` with no `permissionDecision`, so
|
||||
# the write proceeds untouched and Claude sees the note beside the tool result.
|
||||
@@ -103,8 +104,8 @@ fi
|
||||
# changes the inside of a function rather than its signature — the definition
|
||||
# enclosing the edit, found by walking the target file upward from the edited
|
||||
# lines. The server decides whether evidence exists (the session pulled a
|
||||
# snippet this code references or resembles) and stamps instance rows; with
|
||||
# no pulled canon in play, nothing is recorded. Titles only still — this sends
|
||||
# snippet this code references or resembles) and records it as a proposal;
|
||||
# with no pulled canon in play, nothing is recorded. Titles only still — this sends
|
||||
# names, not bodies.
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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.
|
||||
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 before the turn that built it ends, say what it is — record the reusable as a snippet, classify the rest — 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", having just built the first instance of anything, or the end-of-turn list of shapes to judge.
|
||||
---
|
||||
|
||||
# Reusing code — the pattern library
|
||||
@@ -85,6 +85,32 @@ through recall/auto-inject; this skill is the active reflex around that.
|
||||
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).
|
||||
|
||||
## Before the turn ends — say what you built
|
||||
|
||||
You are the one who knows what the code you just wrote is. The shape ledger
|
||||
records it from your answer, not from a guess made later, so give the answer
|
||||
in the turn that built it — while it is still true. When a turn wrote
|
||||
definitions nobody has judged, the plugin's Stop hook lists them once, with
|
||||
whatever evidence the machinery holds ("looks like #N", "#M is canon in this
|
||||
directory", "new"); other clients reach the same moment through
|
||||
`list_shapes(project_id, path=…)`. For each one, decide:
|
||||
|
||||
- **Something another part of the code should reuse** → record it with
|
||||
`create_snippet` (the fields above). Its own row becomes the canon.
|
||||
- **Built from a recorded snippet** → `instance` of it.
|
||||
- **A deliberate departure from one** → `variant`, with the why.
|
||||
- **A genuine one-off** → `exempt`, with a reason (`reason_code` such as
|
||||
`one-off-handler`, `test-helper`, `scoped-css` or `pure-helper` indexes it).
|
||||
|
||||
One call records them all: `classify_shapes(project_id, repo="<the repo's
|
||||
remote>", classifications=[{path, symbol, kind, status, snippet_id?, reason?}])`.
|
||||
`repo` lets a verdict land on a shape the ledger has not synced yet — the one
|
||||
you wrote a minute ago. A component file is a shape too (`kind: "file"`, named
|
||||
by its stem): when a card, chip or dialog is the reusable thing, the file is
|
||||
what you record. An unsure call is still yours to make — the reason you write
|
||||
is what the next reader judges it by — and a verdict is permanent, so each
|
||||
shape is asked about once.
|
||||
|
||||
## A shared snippet is a suggestion, not a standard
|
||||
|
||||
Scribe is multi-user, so a search can return snippets other people own. Those
|
||||
|
||||
@@ -18,8 +18,8 @@ row carries a status:
|
||||
- `exempt` — judged genuinely one-off. **Reason required.** A recorded
|
||||
judgment, not silence — it stops the next pass re-litigating it.
|
||||
- `scoped` — one-off **by construction**, stamped by the coverage sync
|
||||
(a Vue component's scoped `<style>` rules and its `<script setup>`
|
||||
functions — unreachable from any other file). Accounted for without a
|
||||
(a Vue or Svelte component's own styles and instance-script functions —
|
||||
unreachable from any other file). Accounted for without a
|
||||
judgment; still proposed against, grouped and flagged; any judgment you
|
||||
make overrides it. Not the todo.
|
||||
- `unclassified` — nobody has judged it yet. **This is the todo list.**
|
||||
@@ -39,22 +39,32 @@ row carries a status:
|
||||
nothing. Rows, never prose — a consumer list in a note or verification
|
||||
detail cannot be sorted, queried, or diffed.
|
||||
|
||||
## Rows that arrive on their own
|
||||
## The writer judges; audits check that it happened
|
||||
|
||||
Two feeds keep the ledger current between your batches, so most shapes never
|
||||
need a hand judgment:
|
||||
The ledger is filled from your answers, given while you still know them. When
|
||||
a turn wrote definitions nobody has judged, the plugin's Stop hook lists them
|
||||
once — with whatever the machinery holds as evidence — and you classify them
|
||||
in one `classify_shapes(project_id, repo=…, …)` call (the `reusing-code` skill
|
||||
says what each verdict means). `repo` lets a verdict land on a shape the sync
|
||||
has not read yet. So a project worked this way stays accounted as it grows,
|
||||
and an audit pass is a CHECK that the reflex held — the coverage line names
|
||||
what slipped — not the way rows get classified.
|
||||
|
||||
What still arrives without you:
|
||||
|
||||
- **The sync** stamps a snippet's own reference location `canonical`
|
||||
(`classified_by: mechanical`).
|
||||
- **The write path** stamps instances as you work: when you `get_snippet` a
|
||||
canon and then write code that references or resembles it, the
|
||||
definitions being written land as `instance` rows (`classified_by: hook`,
|
||||
the evidence in `reason`), and the prior-art hint tells you what landed
|
||||
("Shape accounting: recorded at … → instance of #N"). Offered-but-unopened
|
||||
snippets stamp nothing — so *pull the canon you are instantiating*; that
|
||||
pull is what turns your reuse into accounting. A `hook` row is evidence, not
|
||||
judgment: it never overrides a classification you made, and a
|
||||
`classify_shapes` call overrides it.
|
||||
(`classified_by: mechanical`) — including a component FILE row when the
|
||||
snippet's location names the file and no symbol.
|
||||
- **The write path suggests**: when you `get_snippet` a canon and then write
|
||||
code that references or resembles it, the shapes being written carry it as
|
||||
a proposal, and the prior-art hint says "→ looks like #N". It is evidence
|
||||
for your verdict, never a verdict — so *pull the canon you are
|
||||
instantiating*; that pull is what puts it in front of you at the end of the
|
||||
turn. Rows the hook stamped `instance` before it stopped doing so are listed
|
||||
by `stamps_to_review` for judgment.
|
||||
- **A component is a row of its own** (`kind: "file"`, named by its stem): a
|
||||
file that renders and defines nothing named after itself. It is judged like
|
||||
any other shape.
|
||||
|
||||
## The machine proposes, judgment classifies
|
||||
|
||||
|
||||
Reference in New Issue
Block a user