Files
learnharness/src/agent/prompts
amosblomqvist 377d4b6548 fix: the handoff freeze + the free-form mermaid pass
Two user-reported problems from the muscle-protein-synthesis session,
both diagnosed from the live data (chat_mtxeml9e_6118e59f).

The freeze: after probe_done, the open session never showed the
teacher's wake turn — only navigating away and back loaded it. Not an
agent-switch problem: the server-side handoff worked perfectly
(write-ahead persist, liveness registry, the sidebar's busy dot saw the
wake the whole time). The gap was client attach: the only mid-session
wake detector the open page has is the jobs poll, and probe-phase
sessions have zero job traffic, so that poll is OFF; the post-turn
adoption poll read turnInFlight=false at ~0ms (the wake fires at
~0.75-1.2s, after the pump's grace), adopted, and stopped. Fix: the
post-turn adoption effect now keeps a short WATCH WINDOW after adopting
(~4s, 8x500ms) — if turnInFlight flips true, it hands off to the
existing wake-adoption poll (busy shimmer, adopt at finish).

The mermaid failures: four failed plan_init calls, all caused by ONE
hidden rule — underscores are forbidden in node ids (mps_translation,
net_balance, per_meal). The id regex rejected '_' BEFORE the slug check,
so the specific, actionable message never fired; the generic 'can't read
the edge — expected a[title] --> b[title]' lied (the syntax was exactly
that), and the teacher spent three attempts hunting punctuation it
suspected (colons, commas, multi-word labels) — visible in its own
reasoning trail. Per the user's principle — enforce only the slugs,
free everything else: underscores are first-class slug chars; the id
CANDIDATE class is broad so every bad id reaches the specific slug
message; chained edges (a --> b --> c) expand to pairs; ==>, -.-> are
edge synonyms; any direction header accepted (we layout ourselves);
id["title"] quote pairs are stripped. The tool description, zod
describe, and the teacher's planning prompt now state the one strict
rule instead of the old subset liturgy.

Verified: tsc, 305/305 (the exact muscle-protein mermaid is now a
passing test), lint, build; real-browser puppeteer smoke on live GLM —
the teacher's wake turn appeared in the open page ~50s after the probe
concluded with ZERO navigation, verdict gate + first teach check +
plan window all live in-page (the single console 404 is the app's
missing favicon, environmental noise).
2026-09-11 23:54:06 +03:00
..

Prompt fragments

System prompts are composed at agent construction (src/agent/teacher-agent.ts), one composition per agent — the probe/teach split (docs/probe-teach-split.md):

  1. src/agent/system-prompt.md — the SHARED base: the teaching philosophy (both principles), accuracy, quiz-option construction, the question tools, formatting. Owned by the master seam; do not edit from a worker.
  2. Every numeric-prefix *.md fragment in the agent's directory (prober/ or teacher/), in sorted filename order, joined with --- separators. The loader enforces the numeric prefix (\d*-*.md) — other files (like this README) never enter the model's prompt.

Rules for adding a fragment:

  • Name it with a numeric order prefix, inside the right agent directory.
  • One fragment per workstream — your brief tells you which filename you own.
  • Document YOUR agent's tools/behaviors exactly; reference tool input field names verbatim (they must match the zod schemas).
  • Keep it tight: fragments are always in context. No restating the base prompt.
  • The two agents share one transcript but never one toolset — never reference the other agent's tools as if you had them.