CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 32s
CI & Build / Python tests (push) Successful in 1m7s
CI & Build / TypeScript typecheck (push) Successful in 4m18s
CI & Build / Build & push image (push) Successful in 25s
Every instruction surface told a session to load the always-on rules and stopped there. None said the loaded set is partial, so an empty one read as "no rule applies" when it only ever meant "none was pushed" — different claims, and only one of them has been checked. That is #2198's asymmetry one level in. The earlier defect was trusting the SessionStart push over the explicit pull; this is trusting the resident TIER as if it were the whole rulebook. It is also why the always-on tier was the only one that worked, on any install rather than this one (rule 115): a rule nothing retrieves must be resident to bind at all, and a resident rule costs tokens in every session forever — so a rulebook that only delivers cannot grow past what one session holds. Retrieval lifts that ceiling, and it fires only if something asks. A tool-choice reflex asks least of all (#3476, #161). The same obligation now lands on all three session-start surfaces, because rule 119 makes them the specification jointly and a surface stating it differently IS the product behaving differently (#2497). Pinned by test_every_session_start_surface_states_the_conditional_retrieval, mirroring the pull test beside it. THE BUDGET TRADE. _INSTRUCTIONS sat at 1978 against a 2000 test budget, and its own comment says an addition there is a trade, never an append. Bought the new clause by trading out "Processes are saved procedures (follow verbatim)" and "Deletes are trash-recoverable" — both already in DISPLACED_TOPICS and already stated on a delivered surface, and both per-tool guidance, which by this block's doctrine belongs in the tool docstring. Now 1976. Recorded in the comment above the block so it is not silently reversed. Plugin version minted: shipped plugin content moved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
114 lines
7.6 KiB
Markdown
114 lines
7.6 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.
|
|
- **What you loaded is not all of the rules.** Only the always-on tier arrives
|
|
that way; conditional rules are RETRIEVED, and one you were never handed
|
|
binds exactly as hard. So before a consequential act, `search` for a rule
|
|
about it (`content_type="rule"`) rather than concluding from an empty
|
|
loaded set that nothing applies. "I was not told" is not the same as "there
|
|
is no rule," and only one of those is checkable.
|
|
This bites hardest on which TOOL to reach for — curling an API that has an
|
|
MCP client, standing up a local stack, running a suite CI owns. Those feel
|
|
like mechanics rather than decisions, so they raise no doubt and generate no
|
|
query; the moment you are most confident is the moment to look.
|
|
- **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.
|