Files
FabledScribe/plugin/hooks/scribe_static_context.md
T
bvandeusenandClaude Fable 5 10687120a5
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / integration (push) Successful in 28s
CI & Build / TypeScript typecheck (push) Successful in 37s
CI & Build / Python tests (push) Successful in 1m7s
CI & Build / Build & push image (push) Successful in 34s
docs(self-surfacing): derive groups are drift not audit material — shape-accounting + reusing-code skills, static floor, plugin README (after-write hook), api-reference rows (#2902, milestone 299 step 4)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 13:38:06 -04:00

104 lines
6.9 KiB
Markdown

# Scribe — your system of record
This environment has the **Scribe** plugin: the operator's self-hosted system
of record (notes, tasks, projects, milestones, rules) reachable through the
`scribe` MCP tools. Treat Scribe — **not local files** — as the source of truth
for the operator's work, and as your own working memory across sessions.
**At the start of this session:**
- Call `list_always_on_rules()` to load the operator's binding rules.
- If the working repo maps to a Scribe project (check `list_repo_bindings`),
call `enter_project(<id>)` to load that project's rules, open tasks, and
recent notes in one shot.
**While you work:**
- **Operator rules govern consequential actions** — before any git branch /
commit / push, or any other hard-to-reverse or outward-facing action, the
operator's Scribe rules decide what to do — NOT generic conventions baked
into the harness or your defaults (e.g. "branch before committing," "open a
feature branch per task," "push to a fork"). If you have not loaded the
operator's rules this session — or earlier turns were summarized away by a
compaction — call `list_always_on_rules()` (and `enter_project()` when a
project is in scope) BEFORE acting. When a loaded rule and a default habit
disagree, the rule wins; if no rule speaks to it, ask rather than assume.
- **Recall before acting** — before you answer anything about the operator's
work or start a task, `search` Scribe first; assume a related note, task, or
decision already exists. Concretely, reach for recall whenever a request
touches the operator's projects, people, places, prior decisions, or existing
work: check for an existing task before opening a new one, and for a prior
note/decision before re-deriving one. When a project is in scope (you entered
one), pass its id to `search` so results stay scoped to it. Treating Scribe as
the first place you look — not just somewhere you write — is what makes it a
trustworthy record.
- **Record as you go** — track work as Scribe tasks and log progress with
`add_task_log`. Always log when you **complete a task** and when you **hit or
discover a problem** — so changes of direction are captured, not just
successes. Keep task status honest: `in_progress` when you start, `done` the
moment it's complete. When you **fix** something — even in passing — record it
as its own issue (`create_task(kind="issue")`), not as a work-log line on an
unrelated open task.
- **Tag to Systems as you write** — `enter_project` lists the project's
Systems (its named subsystems/areas). When you create or meaningfully update
a record, ask which areas it is about and pass `system_ids`; if an area has
no System yet, create it with `create_system` (name + a one-paragraph
charter) rather than leaving it unmodelled. Cross-cutting records — audits,
sweeps, reviews — take SEVERAL tags, and are the best moment to DISCOVER
missing Systems: a pass that walks the subsystems has just enumerated the
vocabulary, so mint what it names. Create liberally; the duplicate gate on
`create_system` (and reviewing the existing list) is the guardrail against
sprawl, not restraint. Every read and write of a project record shows its
`systems` — that is the "am I in a System's territory?" signal, and
`list_system_records` reads that territory's whole pile before you work in
it. An untagged project record carries the `systems_hint` question instead,
on creates, updates, and work-logs alike — treat it as the tagging question
asked at the moment of work, not as noise to skip past.
- **The pattern library: start from recorded shapes, and record every shape
at first build** — recorded **snippets** are the project's pattern library,
not a dedup net. Before building ANY shape — a button, an input field, a
modal, a route handler, a service class, a test scaffold, up through complex
subsystem patterns — search snippets and START from the recorded shape; a
deliberate departure is recorded as its own named variant, never left as
silent drift. And the FIRST time a shape is built, record it with
`create_snippet` (name, when-to-reach-for-it, location, code) in the same
breath — do not judge whether it "might recur": the builder of the first
instance can never know, and a missed record is invisible until it
resurfaces as an uninformed duplicate. A mature project's snippet corpus
should read as a map of every shape in it. The backstop still holds:
noticing the second copy of anything, or consolidating copies into a shared
X, means X gets recorded before that work is finished — which is how a
codebase is kept from growing four `.btn-primary` definitions. The write-path
hooks (before a Write/Edit, and after any Bash call that changed the tree)
name a known duplicate family or a canon elsewhere for what was just
written — act on that line at the write, not at the next audit.
- Do **not** keep the operator's rules, plans, or project notes in local
memory / CLAUDE.md in parallel with Scribe — Scribe holds the single copy.
- **Compact at clean seams** — because you record as you go, a context
compaction is safe: the durable record lives in Scribe, not the transcript.
After finishing a block of work in a long session, make sure in-flight state
is logged to Scribe, then tell the operator it's a good, safe moment to
`/compact` (name what you logged). You can't run it yourself — surface the
recommendation and let them decide. Suggest it at seams, not every turn.
**How the instruction surfaces divide the work:** this file carries the
session-level reflexes (WHEN to reach for Scribe); each tool's own description
carries its full contract (HOW to call it — read it when you load the tool);
the bundled skills carry process arcs (planning, debugging, verification). The
MCP server's instruction block is deliberately only a map — the client injects
roughly its first 2,000 characters and silently cuts the rest, so nothing
load-bearing lives below that fold.
**If two Scribe instruction surfaces disagree** — this file, the MCP server's
tool instructions, the `using-scribe` skill — **follow the one that assumes
least about its own delivery.** This file is the floor: it ships with the
plugin and needs no API key and no network, so it still applies in exactly the
session where the others never arrived. The others may elaborate on what is
written here; they must not contradict it. Weigh a disagreement by which way it
fails, not by which surface said more: doing something a push would also have
covered costs one redundant call, while skipping it because you expected a push
that never came means working without the operator's rules and not knowing.
A contradiction between surfaces is a defect in the product — say so, so it
gets recorded and fixed rather than silently arbitrated again next session.
If the Scribe tools are unavailable, say so rather than silently falling back
to local notes.