feat(410): the skills own the full reflexes, in words any client can read (#4029)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / integration (push) Successful in 53s
CI & Build / TypeScript typecheck (push) Successful in 55s
CI & Build / Python tests (push) Successful in 1m34s
CI & Build / Build & push image (push) Successful in 16s

Step 2 of milestone 410 "One owner per piece of guidance". Skills are the
part of every client package shared verbatim (Agent Skills, decision #4027),
so they state each reflex in full and name no particular client.

using-scribe gains what only the static session context said:
- a retrieved rule outranks a default habit; ask when no rule speaks to it
- log on completing a task and on hitting a problem, not only successes
- the systems_hint on an untagged record is the tagging question, answered
  at the moment of work

Client-specific text leaves the skills, rewritten as the universal idea:
- using-scribe: "keep one copy" no longer names CLAUDE.md, MEMORY.md, native
  auto-memory or autoMemoryEnabled; "this plugin" becomes Scribe
- reusing-code / shape-accounting: Write/Edit and Bash become editor tools
  and shell edits; the prior-art "hook" becomes the prior-art hint; a plugin
  version number is dropped

tests/test_guidance_ownership.py:
- test_the_skills_name_no_particular_client fails on any Claude Code path,
  memory file, slash command, hook event or tool name in a skill, each
  marker commented with why it is client-specific; a companion test shows
  it can fail
- three registry topics for what using-scribe now owns; the loss guard
  stays green

Plugin version minted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-14 11:50:30 -04:00
co-authored by Claude Opus 5
parent f3036f0cd7
commit 0a29252f9b
5 changed files with 95 additions and 29 deletions
+6 -6
View File
@@ -47,12 +47,12 @@ need a hand judgment:
- **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/Edit code that references or resembles it, the
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 hook tells you what landed
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
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.
@@ -91,8 +91,8 @@ The catalogue exists so the codebase is DRY **from inception**, not as DRY as
the last sweep left it. Three surfaces say so without anyone running an audit
(milestone 299):
- **At the write** — the prior-art hint (the Write/Edit hook, and since
0.1.39 the after-write hook on Bash, so sed/heredoc/script edits count too)
- **At the write** — the prior-art hint (delivered beside a write where your
client supports it; shell edits count as much as editor writes)
carries a `Shape ledger at <path>` line when a name just written is a known
**duplicate family** ("identical body in N other files, no canon"), a
**repeated name** ("defined in N other files, no canon") or a
@@ -144,7 +144,7 @@ Three questions the ledger answers mechanically (#2793):
proposer did not match to that canon. `diverges_from` names the canon.
Judge it: `instance` if it should be built from the canon (and rebuild
it), `variant` with the why if the departure is deliberate. The write-path
hook asks the same question in-band the moment such a shape is written.
hint asks the same question in-band the moment such a shape is written.
- **History** — `shape_history(project_id, path, symbol?)`: the current rows
plus every `classified` / `vanished` / `reappeared` / `drifted` event with
its commit — "instance of #N from <date>, re-judged variant of #M because