fix(instructions): the push is an optimisation, not the bridge
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 15s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 47s
CI & Build / Build & push image (push) Successful in 29s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 15s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 47s
CI & Build / Build & push image (push) Successful in 29s
_INSTRUCTIONS told an agent the SessionStart hook was how rules reach a session, and used that as the argument against a host-memory pointer. The using-scribe skill said the opposite — pull them yourself, treat any push as a bonus. Nothing said which wins, and #119 makes these surfaces the specification, so this was the product behaving two ways. #2198 is the case that settles it: every plugin hook was silently inert for an extended period. An agent trusting the push would have run with no binding rules and no signal, while those rules govern branch, commit and push. So: _INSTRUCTIONS now leads with the explicit pull and names the hook as a delivery optimisation. The argument against a host-memory pointer survives — it never needed the hook to be reliable, because the pull IS the bridge and it is written into every surface a session already loads. The static context gains the tiebreaker for the next disagreement: follow the surface that assumes least about its own delivery. "Most detailed wins" is wrong precisely because the most detailed surface is the one with a delivery precondition. It goes there by its own logic — a tiebreaker arriving over MCP cannot arbitrate what to do when MCP is absent. Guarded by tests/test_instruction_surfaces_agree.py: every session-start surface states the pull, and no surface names the push without it. Plugin version bumped so the cache that executes actually picks the file up (#2209). Refs #2497
This commit is contained in:
+23
-12
@@ -174,19 +174,30 @@ written as a rule. A repeatable procedure is a PROCESS. Reusable code is a
|
||||
SNIPPET. Reach for a rule when the thing genuinely is a standing instruction
|
||||
about how to work, and nothing else can hold it.
|
||||
|
||||
Rules are pull-only: CALL list_always_on_rules() YOURSELF at the start of a
|
||||
session, before substantive work. Do not wait to be handed them. The plugin's
|
||||
SessionStart hook also pushes the always-on rules + active-project context, but
|
||||
that is a delivery optimisation, not the bridge — it can be absent (instance
|
||||
unreachable, key not configured, or the hook itself silently inert, which is
|
||||
what #2198 was) and its absence does not announce itself. When the push did
|
||||
arrive, the pull costs one redundant call; when it didn't, skipping the pull
|
||||
means working without the operator's binding rules and having no signal that
|
||||
you are. Those two costs are not comparable, so pull.
|
||||
|
||||
One thing NOT to do: don't bridge Scribe into a session by writing to the
|
||||
host's native memory. Rules are pull-only, so a fresh session won't reach for
|
||||
them unless its always-loaded context says to — but the bridge for that is the
|
||||
Scribe plugin's SessionStart hook, which pushes the always-on rules +
|
||||
active-project context into each session directly. So do NOT create or refresh
|
||||
a "rules live in Scribe" pointer in CLAUDE.md / AGENTS.md / ~/.claude memory,
|
||||
and do NOT keep rules, recall, or plans in those stores in parallel with Scribe
|
||||
— Scribe holds the single copy. Native auto-memory stays for facts about the
|
||||
user; CLAUDE.md for codebase onboarding. Never make Scribe's correctness depend
|
||||
on the operator disabling a native function (e.g. autoMemoryEnabled): the
|
||||
plugin must work with auto-memory at its default. If the plugin is ever removed
|
||||
the session loses this push and rebuilds context over time — an acceptable cost,
|
||||
and far better than a silent settings change the operator may not know about.
|
||||
host's native memory. That explicit pull IS the bridge — it is written into
|
||||
every instruction surface the session already loads, so it needs no pointer on
|
||||
disk. So do NOT create or refresh a "rules live in Scribe" pointer in
|
||||
CLAUDE.md / AGENTS.md / ~/.claude memory, and do NOT keep rules, recall, or
|
||||
plans in those stores in parallel with Scribe — Scribe holds the single copy,
|
||||
and a pointer Scribe cannot update is one that goes stale without anyone
|
||||
noticing. Native auto-memory stays for facts about the user; CLAUDE.md for
|
||||
codebase onboarding. Never make Scribe's correctness depend on the operator
|
||||
disabling a native function (e.g. autoMemoryEnabled): the plugin must work with
|
||||
auto-memory at its default. If the plugin is ever removed the session loses both
|
||||
the push and these instructions, and rebuilds context over time — an acceptable
|
||||
cost, and far better than a silent settings change the operator may not know
|
||||
about.
|
||||
|
||||
When you are working on a specific project, call enter_project(project_id)
|
||||
ONCE at session start (or whenever the active project changes). It returns the
|
||||
|
||||
Reference in New Issue
Block a user