Merge requested by the operator on 2026-09-14 to unblock live testing. The plugin installs from main, and the server image is built from it.
What rides along (11 commits, all CI-green on dev)
#4016: records that cite each other are created together, and a guessed id is refused (441a1ac)
New create_records MCP tool and start_planning(body=, steps=): one transaction, with {{ref:N}} placeholders rewritten to real ids and titles.
Every MCP create/update of a note, task or milestone refuses a #N just above the highest assigned id.
Milestone 409 "Response shapes", steps 1–3
46d9134 (#4010): create_task / update_task (and the REST routes) return a placement block: milestone, step N of M, progress, next open step. It is share-aware.
b4dbc49 (#4011): the new reporting-back skill with the reply shapes.
7239e3c (#4012): the reporting reflex, and a one-line report_back cue when update_task closes a task.
#4022: instruction surfaces stop describing the always-on tier removed by milestone 394 (6c1fd28)
Milestone 410 "One owner per piece of guidance" (decision #4027), steps 1–6
f3036f0 (#4028): the guidance-topic registry and loss guard.
0a29252 (#4029): skills own the full reflexes and name no particular client.
76bfd92 (#4030): _INSTRUCTIONS becomes a client-neutral index (1,597 chars); the live session context carries live state only.
106e396 (#4031): the Claude Code plugin becomes a thin adapter; its static context goes from 8,705 to 1,791 chars.
15621fa (#4032): plugin/PACKAGING.md, the contract for packaging Scribe for other clients.
c440c49 (#4033): an exactly-one-owner guard replaces the tests that required every surface to repeat itself.
After merge
The plugin version changed (2026.09.14.1723), so Claude Code refreshes its plugin cache.
The server needs the new image deployed.
Then milestone 410 step 7 (#4034): a live check in a fresh session.
Merge requested by the operator on 2026-09-14 to unblock live testing. The plugin installs from `main`, and the server image is built from it.
## What rides along (11 commits, all CI-green on `dev`)
**#4016: records that cite each other are created together, and a guessed id is refused** (`441a1ac`)
- New `create_records` MCP tool and `start_planning(body=, steps=)`: one transaction, with `{{ref:N}}` placeholders rewritten to real ids and titles.
- Every MCP create/update of a note, task or milestone refuses a `#N` just above the highest assigned id.
**Milestone 409 "Response shapes", steps 1–3**
- `46d9134` (#4010): `create_task` / `update_task` (and the REST routes) return a `placement` block: milestone, step N of M, progress, next open step. It is share-aware.
- `b4dbc49` (#4011): the new `reporting-back` skill with the reply shapes.
- `7239e3c` (#4012): the reporting reflex, and a one-line `report_back` cue when `update_task` closes a task.
**#4022: instruction surfaces stop describing the always-on tier removed by milestone 394** (`6c1fd28`)
**Milestone 410 "One owner per piece of guidance" (decision #4027), steps 1–6**
- `f3036f0` (#4028): the guidance-topic registry and loss guard.
- `0a29252` (#4029): skills own the full reflexes and name no particular client.
- `76bfd92` (#4030): `_INSTRUCTIONS` becomes a client-neutral index (1,597 chars); the live session context carries live state only.
- `106e396` (#4031): the Claude Code plugin becomes a thin adapter; its static context goes from 8,705 to 1,791 chars.
- `15621fa` (#4032): `plugin/PACKAGING.md`, the contract for packaging Scribe for other clients.
- `c440c49` (#4033): an exactly-one-owner guard replaces the tests that required every surface to repeat itself.
## After merge
- The plugin version changed (2026.09.14.1723), so Claude Code refreshes its plugin cache.
- The server needs the new image deployed.
- Then milestone 410 step 7 (#4034): a live check in a fresh session.
No schema migrations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sessions predicted the ids their next creates would get and wrote them into
plan bodies and reference notes before the records existed. The database
never collides; the sequence is shared by every session and user, so any
concurrent create took the guessed numbers and the references pointed at
someone else's records.
- create_records (new MCP tool) and start_planning(body=, steps=) create
their records in ONE transaction: insert, flush for the real ids, rewrite
{{ref:N}} / {{ref:milestone}} placeholders as #id "title", commit. No
prediction, no waiting, no stub records left behind when a batch fails.
Ids need not be consecutive and nothing depends on it.
- Every MCP create/update of a note, task or milestone refuses a #N sitting
just above the highest assigned id (within 50): that can only be a guess.
Refusal, not warning. Numbers far above the max (PRs, forge issues) pass.
- notes.build_note splits validation out of create_note so the batch
validates records exactly as a single create does.
- writing-plans and using-scribe say to pass steps up front and never write
an unassigned id; plugin version minted.
Integration test runs six concurrent batches and checks each resolves its
placeholders to its own records, and that a failing batch writes nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 1 of milestone 409 "Response shapes". An agent reporting finished work
is asked to say which milestone it belongs to, which step of how many, and
what is next. Without those facts to hand it reconstructs them, and a
reconstruction reads exactly like the truth when it is wrong.
create_task and update_task (MCP) and the REST create/update task routes now
return a placement block: project; and for a task in a milestone, the
milestone, position {step, of}, progress {completed, total, pct} and next
(the next open step, falling back to the earliest open one before it).
- Step order is creation order, not get_milestone listing order, which
reshuffles on every update.
- Siblings are read through readable_notes_clause; position and progress
are computed over that same readable set, so a collaborator is never shown
a step title they cannot open, and a note share alone reveals no plan.
- Fail-open and omitted when empty, like every in-band decoration.
- _no_embedding moves into conftest as one opt-in fixture for both
integration modules that need it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 2 of milestone 409 "Response shapes". A reply written in the order the
work happened is accurate and still unreadable to someone who was not there.
The new bundled skill shapes it around where the work stands.
- Fires when an agent is about to report completion, hand off, ask the
operator something, answer "where are we", or propose an approach.
- Every reply: conclusion first, one topic per section, visible priority,
the ask in bold at the end, plain words, the work placed in Scribe.
- Placement is taken from the placement block step 1 returns (#4010), not
recalled; untracked work is said to be untracked.
- Four families of shapes: Reports, Asks, Answers, Proposals, with the
completion report written out in full.
- Domain-neutral: the worked example is a backup job, evidence is "what you
could open to check it". Written as practices, and naming no instance rule.
- A structural guard pins the completion sections, the from-the-record
placement, and the absence of software-only vocabulary.
Listed in the plugin README and manifest description; version minted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 3 of milestone 409 "Response shapes". Step 2's reporting-back skill
only helps if it fires, and only exists in the Claude Code plugin.
- scribe_static_context.md and using-scribe (new reflex 11) say: report back
in a shape the operator can read, placed from the `placement` block rather
than memory, and point at the reporting-back skill. using-scribe also lists
it among the sibling process-skills.
- update_task returns a one-line `report_back` cue when a task is closed
(done or cancelled). A tool response is the only surface every MCP client
sees, at the moment the report is about to be written.
- _INSTRUCTIONS takes no line: there is no budget without trading out a
session-start reflex. The decision is recorded in server.py's comment
block so it is not re-litigated blind.
- Guards: test_instruction_surfaces_agree pins the reflex and the placement
pointer on both plugin surfaces; a tool test pins the cue on closing
statuses and its absence on every other update.
Plugin version minted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Skill bodies and tool docstrings still taught the deleted model: using-scribe
said always-on rules "arrive whether or not you ask" and that SessionStart may
inject a rule index; create_project, decide_project_inception and enter_project
said an undecided project gets "every always-on rulebook"; create_rule pointed
standards at "the always-on one"; the verification sweeps and
retrieval_telemetry listed always-on paths and a live preload.
Every passage now describes the current model: every rule is retrieved, a
rulebook binds only by subscription, an undecided project inherits nothing,
and the preload survives only in telemetry rows older than 394.
Also repairs three sentences left half-replaced by the 394 edits: the static
context's "If you have not loaded the no rule has arrived", create_rule's
"an A subscribed rulebook", and create_project's doubled
subscribe_rulebooks entry. Plugin version minted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 1 of milestone 410 "One owner per piece of guidance". The later steps
delete duplicate copies of agent guidance; this guard stops the last copy of
a topic going with them.
- tests/test_guidance_ownership.py holds the registry: 30 topics from the
ownership map in decision #4027, each with its owner and marker phrases,
and one definition of a delivered surface (_INSTRUCTIONS, tool docstrings,
each skill, the static context, the adapter commands, the live session
context).
- The loss guard: every topic is stated in full, with all its markers
together, on at least one delivered surface. A miss names the nearest
partial match.
- The owner column is recorded but not asserted yet; step 6 adds the
exactly-one-owner guard once the moves are done.
- test_the_loss_guard_can_fail proves split and absent markers are reported
(rule 167).
- The old DISPLACED_TOPICS list in test_instruction_surfaces_agree is folded
in, so there is one list rather than two.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Step 3 of milestone 410 "One owner per piece of guidance".
_INSTRUCTIONS is rewritten as an index for every MCP client (1,597 of 2,000
chars): orient, rules, recall, record, plan, ids, reuse, UI, report. Each
line names its tool, and the block says every reflex is stated in full in
the using-scribe skill and in each tool description.
- names no client: CLAUDE.md, auto-memory and "the client injects ~2k
chars" are gone
- gains the two reflexes it lacked: records that cite each other go through
create_records with {{ref:N}}, and reports start from `placement`
The comment block above it now explains ownership (decision #4027) instead of
accumulating per-milestone trade history, and keeps the budget and its
reason (#2562).
build_session_context states only what the server knows about this session:
the active project and open work, its design system, an unbound-repo hint,
or that no project is bound. Removed: the "you are not holding the
operator's rules" section, the closing "Reflex: search Scribe" line, the
design-system usage sentence, and the plugin-specific header. using-scribe
owns all of that. The truncation note no longer restates the rules ask.
Tests: a pin that the live context carries no rules reflex; the cap test
drives truncation through the unbound-repo hint, since a bare session is now
one line; the budget test message describes the index.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 4 of milestone 410 "One owner per piece of guidance". The plugin's
static session context was a second copy of using-scribe and the server
index. It now says only what Claude Code needs said: 8,705 -> 1,791 chars.
scribe_static_context.md:
- points at using-scribe for how to work with Scribe, and names the process
skills
- Claude Code specifics: keep one copy in Scribe rather than CLAUDE.md or
auto-memory (leave auto-memory at its default); injected lines are
retrieval, not the whole set; compact at clean seams; stored Processes
arrive as scribe-proc-* skills with /scribe:sync; say so when the tools
are unavailable
- retired: the restated reflexes, "how the surfaces divide the work", and
the "follow the surface that assumes least" precedence (decision #4027)
Hook behaviour is unchanged. The SessionStart hook header says what the
static tier now carries, and the unreachable-instance status points at the
using-scribe skill instead of "the standing guidance above".
README and manifest describe the plugin as the Claude Code adapter over the
shared, client-neutral skills. Fixed along the way: the README said the
SessionStart hook "injects your rules" and suggested disabling auto-memory,
both contradicting the product since milestone 394.
Tests: the session-start rules guards now pin the owner (using-scribe) and
the index (_INSTRUCTIONS) rather than every surface; the Systems-reflex and
snippet-trigger guards pin their owners; the reporting-reflex guard pins
using-scribe. The loss guard and client-neutral guard stay green. Plugin
version minted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 5 of milestone 410 "One owner per piece of guidance". The operator
wants any attempt to package Scribe for another agent client to find the
repo already in the right shape.
plugin/PACKAGING.md (linked from the README) states:
- what every client package shares: plugin/skills/ (verbatim), the /mcp
endpoint and its in-band responses, the /api/plugin/* adapter endpoints
(context, retrieve, prior-art, tool-rules, processes), and one fmcp_ key
- what each client adds: a manifest; hooks limited to timing and transport;
optional commands; adapter static text that never copies a skill or the
index
- the Claude Code adapter file by file, as the worked example
- how Agent Plugins 1.0 clients (Codex, Cursor, Copilot/VS Code, Kiro,
ChatGPT) and Gemini CLI would map, marked researched-not-tested (#4023)
- four open questions for the second package: passing the key to the MCP
server, whether two manifests can share one folder, hook parity, and
where process skills go
Hook audit: every hook prints only server-provided text, status or outage
lines, the running version, or the compaction reload pointer. No guidance
copies, so nothing moved.
Guard: test_the_skills_reference_nothing_outside_their_folder fails on a
relative path upward or a reference to plugin/, hooks/, commands/ or a
manifest from inside a skill, with a companion test showing it can fail.
Plugin version minted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Step 6 of milestone 410 "One owner per piece of guidance". CI now keeps the
shape decision #4027 set, so the next feature cannot quietly add a copy.
tests/test_guidance_ownership.py, 33 topics, each with an owner, markers, a
statement distinctive to the owner's full wording, and optional index markers:
- test_every_topic_is_stated_by_its_owner: markers and statement on the owner
- test_no_topic_is_stated_in_full_off_its_owner: the statement appears on no
other session surface (index, adapter static text and commands, live
context, other skills). Tool docstrings are not scanned; a contract may
elaborate the reflex that calls it.
- test_the_index_names_each_reflex_it_points_at: _INSTRUCTIONS keeps a
one-line pointer for each session-start reflex
- shared_with declares the one deliberate sharing: the note-check question
lives in create_note and in using-scribe for two different moments,
already pinned by test_verification_guidance_survives
- test_the_ownership_guards_can_fail shows each guard turning red (rule 167)
- the process topic now keys on get_process's "follow the returned body";
it had been passing on an unrelated "verbatim" in two other tools
tests/test_instruction_surfaces_agree.py keeps only what ownership cannot
enforce: the fold budget, rules-bind-names-preferences, and using-scribe's
pointer to reporting-back. Retired: the every-session-start-surface ask and
absence tests, the Systems and snippet owner pins (now registry topics), and
the SessionStart-without-ask test (#2497's shape). The push has carried no
rules since milestone 394, and requiring the ask beside every mention of it
would force a copy. The module docstring records where each protection went.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Merge requested by the operator on 2026-09-14 to unblock live testing. The plugin installs from
main, and the server image is built from it.What rides along (11 commits, all CI-green on
dev)#4016: records that cite each other are created together, and a guessed id is refused (
441a1ac)create_recordsMCP tool andstart_planning(body=, steps=): one transaction, with{{ref:N}}placeholders rewritten to real ids and titles.#Njust above the highest assigned id.Milestone 409 "Response shapes", steps 1–3
46d9134(#4010):create_task/update_task(and the REST routes) return aplacementblock: milestone, step N of M, progress, next open step. It is share-aware.b4dbc49(#4011): the newreporting-backskill with the reply shapes.7239e3c(#4012): the reporting reflex, and a one-linereport_backcue whenupdate_taskcloses a task.#4022: instruction surfaces stop describing the always-on tier removed by milestone 394 (
6c1fd28)Milestone 410 "One owner per piece of guidance" (decision #4027), steps 1–6
f3036f0(#4028): the guidance-topic registry and loss guard.0a29252(#4029): skills own the full reflexes and name no particular client.76bfd92(#4030):_INSTRUCTIONSbecomes a client-neutral index (1,597 chars); the live session context carries live state only.106e396(#4031): the Claude Code plugin becomes a thin adapter; its static context goes from 8,705 to 1,791 chars.15621fa(#4032):plugin/PACKAGING.md, the contract for packaging Scribe for other clients.c440c49(#4033): an exactly-one-owner guard replaces the tests that required every surface to repeat itself.After merge
No schema migrations.
🤖 Generated with Claude Code
Sessions predicted the ids their next creates would get and wrote them into plan bodies and reference notes before the records existed. The database never collides; the sequence is shared by every session and user, so any concurrent create took the guessed numbers and the references pointed at someone else's records. - create_records (new MCP tool) and start_planning(body=, steps=) create their records in ONE transaction: insert, flush for the real ids, rewrite {{ref:N}} / {{ref:milestone}} placeholders as #id "title", commit. No prediction, no waiting, no stub records left behind when a batch fails. Ids need not be consecutive and nothing depends on it. - Every MCP create/update of a note, task or milestone refuses a #N sitting just above the highest assigned id (within 50): that can only be a guess. Refusal, not warning. Numbers far above the max (PRs, forge issues) pass. - notes.build_note splits validation out of create_note so the batch validates records exactly as a single create does. - writing-plans and using-scribe say to pass steps up front and never write an unassigned id; plugin version minted. Integration test runs six concurrent batches and checks each resolves its placeholders to its own records, and that a failing batch writes nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Step 1 of milestone 409 "Response shapes". An agent reporting finished work is asked to say which milestone it belongs to, which step of how many, and what is next. Without those facts to hand it reconstructs them, and a reconstruction reads exactly like the truth when it is wrong. create_task and update_task (MCP) and the REST create/update task routes now return a placement block: project; and for a task in a milestone, the milestone, position {step, of}, progress {completed, total, pct} and next (the next open step, falling back to the earliest open one before it). - Step order is creation order, not get_milestone listing order, which reshuffles on every update. - Siblings are read through readable_notes_clause; position and progress are computed over that same readable set, so a collaborator is never shown a step title they cannot open, and a note share alone reveals no plan. - Fail-open and omitted when empty, like every in-band decoration. - _no_embedding moves into conftest as one opt-in fixture for both integration modules that need it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Step 3 of milestone 410 "One owner per piece of guidance". _INSTRUCTIONS is rewritten as an index for every MCP client (1,597 of 2,000 chars): orient, rules, recall, record, plan, ids, reuse, UI, report. Each line names its tool, and the block says every reflex is stated in full in the using-scribe skill and in each tool description. - names no client: CLAUDE.md, auto-memory and "the client injects ~2k chars" are gone - gains the two reflexes it lacked: records that cite each other go through create_records with {{ref:N}}, and reports start from `placement` The comment block above it now explains ownership (decision #4027) instead of accumulating per-milestone trade history, and keeps the budget and its reason (#2562). build_session_context states only what the server knows about this session: the active project and open work, its design system, an unbound-repo hint, or that no project is bound. Removed: the "you are not holding the operator's rules" section, the closing "Reflex: search Scribe" line, the design-system usage sentence, and the plugin-specific header. using-scribe owns all of that. The truncation note no longer restates the rules ask. Tests: a pin that the live context carries no rules reflex; the cap test drives truncation through the unbound-repo hint, since a bare session is now one line; the budget test message describes the index. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>