Reply shapes reach the reply, a Stop hook checks completion reports, and hook pipes keep their output #156

Merged
bvandeusen merged 6 commits from dev into main 2026-09-14 18:57:07 -04:00
3 changed files with 23 additions and 36 deletions
Showing only changes of commit 9071cb05da - Show all commits
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "scribe", "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).", "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.09.14.1723", "version": "2026.09.14.2001",
"author": { "author": {
"name": "Bryan Van Deusen" "name": "Bryan Van Deusen"
}, },
+5 -6
View File
@@ -10,15 +10,14 @@ shape-accounting) carry their arcs.
What only Claude Code needs said: What only Claude Code needs said:
- **Keep one copy — in Scribe, not Claude Code's local memory.** The - **Keep one copy — in Scribe, not Claude Code's local memory.** Claude
operator's rules, plans and project notes go to Scribe, not also to Code's local memory is `CLAUDE.md` and auto-memory: the operator's rules,
`CLAUDE.md` or auto-memory. Leave auto-memory at its default setting: you plans and project notes go to Scribe instead, and using-scribe says how
replace its job by doing the work in Scribe, not by switching it off. Scribe works alongside them.
- **Lines injected beside your work are retrieval.** When the operator sends a - **Lines injected beside your work are retrieval.** When the operator sends a
message, and before a write or a command, Scribe may add rules, preferences, message, and before a write or a command, Scribe may add rules, preferences,
notes and prior art that resemble what you are doing. Open the ones that notes and prior art that resemble what you are doing. Open the ones that
apply. They are what matched, never the whole set — using-scribe says how to apply; using-scribe says what a quiet turn means.
ask for the rest.
- **Compact at clean seams.** Because work is recorded as you go, a compaction - **Compact at clean seams.** Because work is recorded as you go, a compaction
is safe once in-flight state is logged. After finishing a block of work in a is safe once in-flight state is logged. After finishing a block of work in a
long session, log it to Scribe, then tell the operator it's a good moment to long session, log it to Scribe, then tell the operator it's a good moment to
+17 -29
View File
@@ -13,23 +13,14 @@ asked for.
## Do this first (every session) ## Do this first (every session)
**You are not holding the operator's rules, and no call loads them all.**
There is no standing set to pull. A rule reaches you when what you are about to
do matches it — a command, code you are writing, or what the operator just
asked for — and on most turns none will. That is the surface working.
**So the reflex is to ASK, not to load.** Before a consequential act — anything
hard to reverse or outward-facing — `search(content_type="rule")` for the thing
you are about to do. An empty session is not evidence of an empty rulebook.
If the working repo maps to a Scribe project (you're in a known repo, or If the working repo maps to a Scribe project (you're in a known repo, or
`list_repo_bindings` shows a binding), call `enter_project(id)` — it returns the `list_repo_bindings` shows a binding), call `enter_project(id)` — it returns the
project plus the rules bound to the areas it works in, open tasks, and recent project plus the rules bound to the areas it works in, open tasks, and recent
notes in one shot. notes in one shot.
Do this actively. Nothing is handed to a session up front to stand in for it — Then **ask before you act**: before anything hard to reverse or outward-facing,
rules arrive by retrieval, when your work or the operator's message matches search the rules for what you are about to do. Reflex 2 below is why asking,
one — so asking and entering the project are the reliable path. not loading, is how the operator's rules reach you.
## Scribe holds these functions — keep one copy ## Scribe holds these functions — keep one copy
@@ -59,12 +50,20 @@ Two constraints on *how* that's achieved:
re-deriving it or opening a duplicate. When a project is in scope, pass its re-deriving it or opening a duplicate. When a project is in scope, pass its
`project_id` so results stay scoped. `project_id` so results stay scoped.
2. **Rules are binding, and silence does not mean there are none.** Nothing 2. **Rules are binding, and they reach you by retrieval.** No call loads the
is preloaded, so "no rule arrived" means "nothing matched" — never "no rule operator's rules and no standing set is handed to a session. A rule arrives
exists". Ask with `search(content_type="rule")` before a consequential act, when what you are about to do resembles what it is about — a command, the
and pull a record's full statement with `get_rule(id)` when it is about to code you are writing, the operator's message — and on most turns none will.
bite. When a project is in scope, `enter_project(id)` also returns the rules That is the surface working: it is what lets a rulebook keep growing, since
bound to its areas. a rule costs nothing in a session it has nothing to do with. A rule binds
just as hard for never having been handed to you.
So "no rule arrived" means "nothing matched", never "no rule exists" — an
empty session is not evidence of an empty rulebook. Retrieval fires when
something asks: before a consequential act, `search(content_type="rule")` on
what you are about to do, and pull a record's full statement with
`get_rule(id)` when it is about to bite. When a project is in scope,
`enter_project(id)` also returns the rules bound to its areas.
**`kind` says how much force a record carries, and it is never something to **`kind` says how much force a record carries, and it is never something to
infer.** A **rule** must be followed: ignoring it breaks something or infer.** A **rule** must be followed: ignoring it breaks something or
@@ -84,17 +83,6 @@ Two constraints on *how* that's achieved:
asks. If what you learned is that something MUST be done a certain way, asks. If what you learned is that something MUST be done a certain way,
that is a rule to propose, not a preference to harden in place. that is a rule to propose, not a preference to harden in place.
Every rule is RETRIEVED: one reaches you when a command, the code you are
writing or the operator's message resembles what it is about, and a rule
binds just as hard for never having been handed to you. So before a
consequential act, `search(content_type="rule")` on what you are about to
do. An empty session is not evidence that no rule applies; it is only
evidence that nothing has matched yet, and those are different claims.
Retrieval is what lets a rulebook keep growing — a rule costs nothing in a
session it has nothing to do with — but retrieval only fires if something
asks.
**A retrieved rule outranks a default habit.** Before a hard-to-reverse or **A retrieved rule outranks a default habit.** Before a hard-to-reverse or
outward-facing act — changing shared state, publishing, deleting, sending outward-facing act — changing shared state, publishing, deleting, sending
something outside the session — the operator's rules decide what to do, not something outside the session — the operator's rules decide what to do, not