feat(410): the server orients with a client-neutral index; the live context carries live state only (#4030)
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 54s
CI & Build / Python tests (push) Successful in 1m28s
CI & Build / Build & push image (push) Successful in 27s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 54s
CI & Build / Python tests (push) Successful in 1m28s
CI & Build / Build & push image (push) Successful in 27s
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>
This commit is contained in:
@@ -2160,30 +2160,18 @@ async def build_session_context(
|
||||
on each write so the server could say whether the resident rules had
|
||||
moved; nothing is resident now, so nothing can have moved, and a rule is
|
||||
re-retrieved at the moment it applies rather than held and aged.
|
||||
`context` is markdown ready to drop into `additionalContext`; it is capped
|
||||
at _MAX_CHARS with an explicit truncation note so the hook can pass it
|
||||
through verbatim.
|
||||
"""
|
||||
lines: list[str] = [
|
||||
"# Scribe — standing session context (auto-injected by the Scribe plugin)",
|
||||
"",
|
||||
"You are working with Scribe, the operator's self-hosted second brain.",
|
||||
"",
|
||||
"## You are not holding the operator's rules",
|
||||
"",
|
||||
"No rule has been loaded into this session, and that is deliberate. "
|
||||
"Rules arrive when something you are about to do makes one relevant — "
|
||||
"a command you are about to run, code you are writing, or what the "
|
||||
"operator just asked for. On most turns none will, and that is the "
|
||||
"surface working rather than failing.",
|
||||
"",
|
||||
"**\"No rule arrived\" means \"nothing matched\" — never \"there is no "
|
||||
"rule.\"** Before a consequential act, one that is hard to reverse or "
|
||||
"outward-facing, `search(content_type=\"rule\")` is how you ask. "
|
||||
"Retrieval runs on its own and is a convenience; asking is what you do "
|
||||
"when it matters and nothing has spoken.",
|
||||
]
|
||||
`context` is markdown an adapter can drop into its session verbatim; it
|
||||
is capped at _MAX_CHARS with an explicit truncation note.
|
||||
|
||||
LIVE STATE ONLY (decision #4027, milestone 410). This used to open with the
|
||||
rules reflex and close with a recall reflex — a fifth copy of guidance the
|
||||
using-scribe skill owns, arriving in every session beside the other four.
|
||||
It now says only what the server alone knows about THIS session: the
|
||||
active project, its open work, its design system, or that the working repo
|
||||
is unbound. How to work with Scribe is the skill's to say, and it says it
|
||||
once.
|
||||
"""
|
||||
lines: list[str] = ["# Scribe — live session state"]
|
||||
|
||||
project_dict: dict | None = None
|
||||
if project_id:
|
||||
@@ -2222,9 +2210,7 @@ async def build_session_context(
|
||||
f"(id {design['id']}){inherits}",
|
||||
f"{design['token_count']} tokens"
|
||||
+ (f" across {groups}" if groups else "")
|
||||
+ ". This project's UI is built from these, not from "
|
||||
"literals — reach for a token before writing a colour, "
|
||||
"size, radius or duration by hand.",
|
||||
+ ".",
|
||||
f"Values: `resolve_design_system({design['id']})` · "
|
||||
f"stylesheet: `get_design_system_stylesheet({design['id']})` "
|
||||
f"· the prose (aesthetic, voice, where the accent may "
|
||||
@@ -2241,18 +2227,12 @@ async def build_session_context(
|
||||
"(call `list_projects` to find the id) and future sessions here will "
|
||||
"auto-load that project's context.",
|
||||
]
|
||||
|
||||
lines += [
|
||||
"",
|
||||
"Reflex: search Scribe (search / list_tasks / list_notes, scoped to the "
|
||||
"active project) before answering or starting work; prefer UPDATING an "
|
||||
"existing note/rule over creating a new one.",
|
||||
]
|
||||
else:
|
||||
lines += ["", "No Scribe project is bound to this working directory."]
|
||||
|
||||
context = "\n".join(line for line in lines if line is not None)
|
||||
if len(context) > _MAX_CHARS:
|
||||
context = context[:_MAX_CHARS].rstrip() + \
|
||||
"\n\n…(truncated — ask with search(content_type=\"rule\"))"
|
||||
context = context[:_MAX_CHARS].rstrip() + "\n\n…(truncated)"
|
||||
|
||||
return {
|
||||
"context": context,
|
||||
|
||||
Reference in New Issue
Block a user