feat(instructions): fit the delivery fold — 2k server map, floor Systems reflex, write-time systems_hint
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / integration (push) Successful in 18s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 47s
CI & Build / Build & push image (push) Successful in 28s

Claude Code injects only the first ~2,048 chars of an MCP server's
instructions and silently cuts the rest mid-word (#2562, observed live):
_INSTRUCTIONS was 20,002 chars, so ~90% — including all Systems tagging
guidance — never reached any session. Rearchitect delivery around what
each surface actually delivers:

- _INSTRUCTIONS becomes a 1,997-char purpose-sorted map, with a header
  comment stating the budget and where detail belongs instead.
- Tool docstrings keep the per-tool HOW (audit: nearly all displaced
  topics were already duplicated there); backfill the four gaps —
  enter_project session scoping + project bootstrap, create_rule
  entity-vs-rule test, create_design_system not-a-rulebook,
  create_system two-records test.
- The plugin static context (the delivery floor) gains the
  tag-to-Systems reflex and a surfaces-layering statement; plugin
  0.1.25 -> 0.1.26 so the executing cache refreshes (#2209).
- create_task / create_note / create_snippet return a systems_hint when
  a record is created untagged in a project that has Systems — in-band
  at the exact write it applies to, fail-open like the dedup gate.
- Guards: _INSTRUCTIONS length budget, floor-states-the-reflex, and a
  displaced-topics sweep asserting every cut topic still lives on a
  delivered surface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-09 12:53:35 -04:00
co-authored by Claude Fable 5
parent 272b7dbddf
commit 3ff8803593
12 changed files with 304 additions and 300 deletions
+89
View File
@@ -85,6 +85,95 @@ def test_every_session_start_surface_states_the_pull():
)
def _instructions_text() -> str:
"""The _INSTRUCTIONS literal from server.py, as the client would see it."""
import re
src = (ROOT / "src" / "scribe" / "mcp" / "server.py").read_text()
match = re.search(r'_INSTRUCTIONS = """(.*?)"""', src, re.S)
assert match, "server.py no longer defines _INSTRUCTIONS as a triple-quoted literal"
return match.group(1).strip()
# Claude Code injects only the first ~2,048 characters of an MCP server's
# instructions and silently cuts the rest mid-word (#2562: observed live —
# the previous 20k-char version delivered ~10% of itself, and none of the
# Systems tagging guidance ever reached a session). 2,000 leaves margin.
INSTRUCTIONS_BUDGET = 2000
def test_instructions_fit_the_fold():
text = _instructions_text()
assert len(text) <= INSTRUCTIONS_BUDGET, (
f"_INSTRUCTIONS is {len(text)} chars; the client injects only ~2,048 "
f"and silently cuts the rest (#2562). This block is a MAP — move the "
f"detail to the tool's docstring (delivered at reach-for time), the "
f"plugin static context (always delivered), or a skill; see the "
f"comment above _INSTRUCTIONS."
)
def test_floor_states_the_systems_reflex():
"""Write-time tagging guidance must live on the surface that always arrives.
#2562's behavioral finding: with the guidance only in tool descriptions,
sessions filed records untagged. The static context is the delivery floor,
so the tag-as-you-write reflex has to be stated there.
"""
floor = (ROOT / "plugin" / "hooks" / "scribe_static_context.md").read_text()
for needle in ("system_ids", "create_system"):
assert needle in floor, (
f"plugin/hooks/scribe_static_context.md no longer mentions "
f"{needle} — the Systems tagging reflex must be stated on the "
f"floor, not only in tool descriptions (#2562)."
)
# Topics displaced from _INSTRUCTIONS when it was cut to fit the fold. Each
# must remain stated on at least one DELIVERED surface: a tool docstring
# (arrives with the tool schema), the plugin static context (always arrives),
# or a bundled skill (arrives on trigger match). Keyed by a phrase distinctive
# enough that its disappearance means the guidance is gone, not reworded —
# update the phrase alongside a deliberate rewording.
DISPLACED_TOPICS = {
"supersedes": "supersedes",
"trash is recoverable": "deleted_batch_id",
"duplicate gate": "duplicate",
"systems tag-as-you-write": "system_ids",
"reference note vs dev-log": "reference note",
"work-logs over body rewrites": "add_task_log",
"rule homes / altitude": "create_project_rule",
"rules vs other entities": "standing instruction",
"shared records are suggestions": "shared",
"processes run verbatim": "verbatim",
"snippet reuse reflex": "when_to_use",
"compaction at seams": "compact",
"plans are milestones": "start_planning",
"scope to the entered project": "cross-project",
"project bootstrap needs confirmation": "never guessing a project",
}
def test_displaced_topics_live_on_a_delivered_surface():
corpus = ""
for p in (ROOT / "src" / "scribe" / "mcp" / "tools").glob("*.py"):
corpus += p.read_text()
corpus += (ROOT / "plugin" / "hooks" / "scribe_static_context.md").read_text()
for p in (ROOT / "plugin" / "skills").rglob("SKILL.md"):
corpus += p.read_text()
corpus = corpus.lower()
missing = [
f"{topic} (phrase: {phrase!r})"
for topic, phrase in DISPLACED_TOPICS.items()
if phrase.lower() not in corpus
]
assert not missing, (
f"guidance displaced from _INSTRUCTIONS has fallen off every delivered "
f"surface (tool docstrings / static context / skills): {missing}. It "
f"was cut from _INSTRUCTIONS deliberately (#2562) on the premise it "
f"lives elsewhere — restore it somewhere that delivers."
)
def test_no_surface_names_the_push_without_stating_the_pull():
"""The exact shape #2497 took.
+61
View File
@@ -73,3 +73,64 @@ async def test_create_task_issue_sets_kind_provenance_and_systems():
assert kwargs["arose_from_id"] == 9
systems_svc.set_record_systems.assert_awaited_once_with(1, 50, [2, 3])
assert result["id"] == 50
@pytest.mark.asyncio
async def test_untagged_hint_names_the_projects_systems():
sys_a = MagicMock(); sys_a.id = 1; sys_a.name = "workers"
sys_b = MagicMock(); sys_b.id = 2; sys_b.name = "scrape-pipeline"
with patch("scribe.mcp.tools.systems.systems_svc") as svc:
svc.list_systems = AsyncMock(return_value=[sys_a, sys_b])
from scribe.mcp.tools.systems import untagged_systems_hint
hint = await untagged_systems_hint(1, 5)
assert "workers" in hint and "scrape-pipeline" in hint
assert "system_ids" in hint
assert "create_system" in hint
@pytest.mark.asyncio
async def test_untagged_hint_absent_without_systems_and_fails_open():
from scribe.mcp.tools.systems import untagged_systems_hint
with patch("scribe.mcp.tools.systems.systems_svc") as svc:
svc.list_systems = AsyncMock(return_value=[])
assert await untagged_systems_hint(1, 5) is None
with patch("scribe.mcp.tools.systems.systems_svc") as svc:
# A hint must never break a create — DB failure degrades to no hint.
svc.list_systems = AsyncMock(side_effect=RuntimeError("db down"))
assert await untagged_systems_hint(1, 5) is None
@pytest.mark.asyncio
async def test_create_task_untagged_in_project_with_systems_carries_hint():
note = MagicMock(); note.id = 60; note.to_dict.return_value = {"id": 60}
sys_a = MagicMock(); sys_a.id = 4; sys_a.name = "plugin-hooks"
with patch("scribe.mcp.tools.tasks.current_user_id", return_value=1), \
patch("scribe.mcp.tools.tasks.notes_svc") as notes_svc, \
patch("scribe.mcp.tools.tasks.dedup_svc") as dedup_svc, \
patch("scribe.mcp.tools.systems.systems_svc") as hint_svc:
notes_svc.create_note = AsyncMock(return_value=note)
dedup_svc.find_duplicate_note = AsyncMock(return_value=None)
hint_svc.list_systems = AsyncMock(return_value=[sys_a])
from scribe.mcp.tools.tasks import create_task
result = await create_task(title="untagged", project_id=5)
assert "plugin-hooks" in result["systems_hint"]
@pytest.mark.asyncio
async def test_create_task_tagged_or_projectless_carries_no_hint():
note = MagicMock(); note.id = 61; note.to_dict.return_value = {"id": 61}
with patch("scribe.mcp.tools.tasks.current_user_id", return_value=1), \
patch("scribe.mcp.tools.tasks.notes_svc") as notes_svc, \
patch("scribe.mcp.tools.tasks.dedup_svc") as dedup_svc, \
patch("scribe.mcp.tools.tasks.systems_svc") as systems_svc, \
patch("scribe.mcp.tools.systems.systems_svc") as hint_svc:
notes_svc.create_note = AsyncMock(return_value=note)
dedup_svc.find_duplicate_note = AsyncMock(return_value=None)
systems_svc.set_record_systems = AsyncMock()
systems_svc.list_record_systems = AsyncMock(return_value=[])
hint_svc.list_systems = AsyncMock(return_value=[MagicMock()])
from scribe.mcp.tools.tasks import create_task
tagged = await create_task(title="tagged", project_id=5, system_ids=[4])
orphan = await create_task(title="orphan", project_id=0)
assert "systems_hint" not in tagged
assert "systems_hint" not in orphan