Capability: system prompt
This capability treats one or more prompt/policy text files (prompt.txt,
policy.md, SYSTEM.md) as the optimizable artifact — whatever text the runtime
prepends to the agent's context as its instructions, output contract, and decision
policy.
Prose is the right lever when the agent lacks something it could be told: a
format, a rule, a decision criterion. It is the wrong lever when the agent already
has the rule and does not act on it — that needs the behavior enforced in code, so
it belongs to whatever capability edits the agent's tools, not here. Classify the
failure clusters first (./guidance/diagnose/SKILL.md, when present) and spend
prose only on the clusters this capability can actually move.
Pick the lever
Each item is a bounded edit class. Fix the biggest cluster with the narrowest lever
that reaches it; ship every class the traces call for in one candidate. Examples are
1-line and generic; depth is in references/concepts.md.
- Rewrite a rule for clarity, positively framed — say what TO do, specifically.
A prohibition fences off one wrong path; a positive instruction names the target.
Ex: "Don't be vague" → "State the record ID in every reply."
- Add the reason to a bare rule — a rule paired with its rationale extends to
cases the rule's author never wrote down; a bare imperative does not.
Ex: "Never use ellipses" → "Never use ellipses — the output is read by a TTS
engine that cannot pronounce them."
- Consolidate redundant rules — merge duplicates into one, keeping every
distinct constraint. Ex: three "confirm before deleting" lines → one "Confirm
before any destructive action (delete, overwrite, send)."
- Add a rule the source requires but the prompt omits — it must trace to a real
source (the policy doc, the runner, the task spec), never be invented. The added
rule may introduce a constraint the prompt lacked, or state a stricter condition on
an existing one. It may not broaden an existing permission or flip a decision the
agent currently gets right: that changes behavior for every task in the class,
including the passing ones whose gold answer was the stricter behavior. When a
cluster needs different behavior, name the exact condition that separates the
qualifying cases instead. Ex: the source says refunds need a manager code →
"Require a manager code before any refund."
- Add an example — one or a few
<example>-tagged exemplars to pin a format
that is hard to describe in prose. Ex: one <example> showing the exact JSON
envelope expected. Examples are re-read every turn, so add the smallest set that
pins the shape and treat a larger set as a hypothesis to gate, not a free win.
- Restructure — separate instructions, context, examples, and input into their
own sections or tags so the model does not conflate them, and put long reference
data before the instruction that acts on it.
- Add a role / goal line — one sentence on who the agent is and what "done"
means, when the prompt has none. Ex: "You are a careful support agent; resolve
the request in one turn."
- Tighten the output contract — make the required shape explicit and exact.
Ex: "Reply with only a JSON object
{status, reason} — no prose." If the scorer
reads the agent's final message, the contract must require the agent to state every
value the scorer checks: agents routinely perform the action correctly and never
report the result, and the scorer sees only the omission. (A missing action, as
opposed to a missing report of it, is not fixable here — see the scope note above.)
- Soften over-strong wording — when a cluster shows the agent over-doing rather
than under-doing (excess tool calls, over-engineering, triggering a behavior where
it did not apply), downgrade
CRITICAL/MUST/ALWAYS to "Use … when …". The edit
that fixes an over-eagerness cluster is a cut, not an addition.
Never drop a needed rule — change, consolidate, or add
When an edit removes text, every distinct constraint that text carried must survive
somewhere: rewritten, merged into a combined rule, or relocated. Deletion is
legitimate when the information is genuinely redundant, contradicted by the source,
or now enforced deterministically elsewhere — and in the first two cases prefer
rewriting the conflicting rule. Consolidation cuts words, never rules.
An optimizer that deletes a needed rule can make one iteration's metric go up and
leave the class permanently broken, so the check is mechanical as well as stated:
apply() counts constraint-bearing lines before and after every edit and reports a
net loss in report["warnings"]. A warning is not a failure — a legitimate
consolidation triggers it too — it is a prompt to state, in PROCESS.md, where each
dropped constraint went. op: "set" on a whole file is the edit most likely to lose
one silently.
Keep the edit general
- Never hardcode a task's specifics. A rule must state the general policy that
holds across the class, not one task's case or answer. Good: "Reverse the charge
to the original payment method on file." Bad: "If the record id is
<TASK_SPECIFIC_ID>, apply the amount that task expects." Baking an id, value,
date, or answer into the prompt overfits, gets rejected by the held-out gate, and
can mislead other tasks. Use a failing task's specifics to identify the class, then
write the general rule. The test for any edit: would this help on a task the
optimizer has never seen?
- Resolve conflicts, don't stack rules. Before editing, list the rules that
govern the same action and check that no two give a different verdict on the same
input; rewrite toward the stricter one rather than dropping either. A contradiction
is the one failure mode detectable by reading the artifact alone, so it is worth
the pass.
- Consolidate as constraints move out of the prompt. When a rule is now enforced
deterministically elsewhere, remove its now-redundant prose: the enforcement is
authoritative and the duplicate sentence only competes for attention. The prompt
should get shorter as constraints become enforced, not longer. (This drops no rule
— the constraint still lives, enforced elsewhere.)
- Watch length, but measure it.
validate() reports each file's line, token, and
constraint-line counts. There is no universal length threshold worth quoting;
compare a candidate against the accepted candidates of your own run and treat a
prompt that grows every iteration without moving val as the signal to prune.
Handlers (scripts/abstract.py)
materialize(dir) -> {file: text} · apply(dir, edits) -> {changed, warnings} ·
validate(dir, baseline=None) -> {ok, files, stats, problems, warnings} ·
is_empty(dir) -> bool. Edit ops: set, append, ensure_contains. Pass
baseline (a directory or a {file: text} dict, e.g. the parent candidate) to have
validate report a constraint-line drop against it. A project adapter's apply can
call these directly.
How to run
python scripts/check.py
python scripts/run.py --path <capability_dir> # candidate + validity
python scripts/run.py --path <candidate_dir> --baseline <parent_dir> # + rule-loss check
References
references/concepts.md — what the prompt controls, the
six authoring practices and five failure modes in full, how to adapt a prompt to
the runtime reader's capability tier, pitfalls, and cited sources. Read once
before your first non-trivial edit, and again when a candidate is accepted but
barely moves the metric.
1---2name: system-prompt3description: Capability: system prompt4---56# Capability: system prompt78This capability treats one or more prompt/policy text files (`prompt.txt`,9`policy.md`, `SYSTEM.md`) as the optimizable artifact — whatever text the runtime10prepends to the agent's context as its instructions, output contract, and decision11policy.1213Prose is the right lever when the agent lacks something it could be *told*: a14format, a rule, a decision criterion. It is the wrong lever when the agent already15has the rule and does not act on it — that needs the behavior enforced in code, so16it belongs to whatever capability edits the agent's tools, not here. Classify the17failure clusters first (`./guidance/diagnose/SKILL.md`, when present) and spend18prose only on the clusters this capability can actually move.1920## Pick the lever2122Each item is a bounded edit class. Fix the biggest cluster with the narrowest lever23that reaches it; ship every class the traces call for in one candidate. Examples are241-line and generic; depth is in [`references/concepts.md`](references/concepts.md).25261. **Rewrite a rule for clarity, positively framed** — say what TO do, specifically.27 A prohibition fences off one wrong path; a positive instruction names the target.28 *Ex:* "Don't be vague" → "State the record ID in every reply."292. **Add the reason to a bare rule** — a rule paired with its rationale extends to30 cases the rule's author never wrote down; a bare imperative does not.31 *Ex:* "Never use ellipses" → "Never use ellipses — the output is read by a TTS32 engine that cannot pronounce them."333. **Consolidate redundant rules** — merge duplicates into one, keeping every34 distinct constraint. *Ex:* three "confirm before deleting" lines → one "Confirm35 before any destructive action (delete, overwrite, send)."364. **Add a rule the source requires but the prompt omits** — it must trace to a real37 source (the policy doc, the runner, the task spec), never be invented. The added38 rule may introduce a constraint the prompt lacked, or state a stricter condition on39 an existing one. It may not broaden an existing permission or flip a decision the40 agent currently gets right: that changes behavior for every task in the class,41 including the passing ones whose gold answer was the stricter behavior. When a42 cluster needs different behavior, name the exact condition that separates the43 qualifying cases instead. *Ex:* the source says refunds need a manager code →44 "Require a manager code before any refund."455. **Add an example** — one or a few `<example>`-tagged exemplars to pin a format46 that is hard to describe in prose. *Ex:* one `<example>` showing the exact JSON47 envelope expected. Examples are re-read every turn, so add the smallest set that48 pins the shape and treat a larger set as a hypothesis to gate, not a free win.496. **Restructure** — separate instructions, context, examples, and input into their50 own sections or tags so the model does not conflate them, and put long reference51 data before the instruction that acts on it.527. **Add a role / goal line** — one sentence on who the agent is and what "done"53 means, when the prompt has none. *Ex:* "You are a careful support agent; resolve54 the request in one turn."558. **Tighten the output contract** — make the required shape explicit and exact.56 *Ex:* "Reply with only a JSON object `{status, reason}` — no prose." If the scorer57 reads the agent's final message, the contract must require the agent to state every58 value the scorer checks: agents routinely perform the action correctly and never59 report the result, and the scorer sees only the omission. (A missing action, as60 opposed to a missing report of it, is not fixable here — see the scope note above.)619. **Soften over-strong wording** — when a cluster shows the agent over-doing rather62 than under-doing (excess tool calls, over-engineering, triggering a behavior where63 it did not apply), downgrade `CRITICAL/MUST/ALWAYS` to "Use … when …". The edit64 that fixes an over-eagerness cluster is a cut, not an addition.6566## Never drop a needed rule — change, consolidate, or add6768When an edit removes text, every distinct constraint that text carried must survive69somewhere: rewritten, merged into a combined rule, or relocated. Deletion is70legitimate when the information is genuinely redundant, contradicted by the source,71or now enforced deterministically elsewhere — and in the first two cases prefer72rewriting the conflicting rule. Consolidation cuts *words*, never *rules*.7374An optimizer that deletes a needed rule can make one iteration's metric go up and75leave the class permanently broken, so the check is mechanical as well as stated:76`apply()` counts constraint-bearing lines before and after every edit and reports a77net loss in `report["warnings"]`. A warning is not a failure — a legitimate78consolidation triggers it too — it is a prompt to state, in `PROCESS.md`, where each79dropped constraint went. `op: "set"` on a whole file is the edit most likely to lose80one silently.8182## Keep the edit general8384- **Never hardcode a task's specifics.** A rule must state the general policy that85 holds across the class, not one task's case or answer. *Good:* "Reverse the charge86 to the original payment method on file." *Bad:* "If the record id is87 `<TASK_SPECIFIC_ID>`, apply the amount that task expects." Baking an id, value,88 date, or answer into the prompt overfits, gets rejected by the held-out gate, and89 can mislead other tasks. Use a failing task's specifics to identify the class, then90 write the general rule. The test for any edit: *would this help on a task the91 optimizer has never seen?*92- **Resolve conflicts, don't stack rules.** Before editing, list the rules that93 govern the same action and check that no two give a different verdict on the same94 input; rewrite toward the stricter one rather than dropping either. A contradiction95 is the one failure mode detectable by reading the artifact alone, so it is worth96 the pass.97- **Consolidate as constraints move out of the prompt.** When a rule is now enforced98 deterministically elsewhere, remove its now-redundant prose: the enforcement is99 authoritative and the duplicate sentence only competes for attention. The prompt100 should get shorter as constraints become enforced, not longer. (This drops no rule101 — the constraint still lives, enforced elsewhere.)102- **Watch length, but measure it.** `validate()` reports each file's line, token, and103 constraint-line counts. There is no universal length threshold worth quoting;104 compare a candidate against the accepted candidates of your own run and treat a105 prompt that grows every iteration without moving val as the signal to prune.106107## Handlers (scripts/abstract.py)108109`materialize(dir) -> {file: text}` · `apply(dir, edits) -> {changed, warnings}` ·110`validate(dir, baseline=None) -> {ok, files, stats, problems, warnings}` ·111`is_empty(dir) -> bool`. Edit ops: `set`, `append`, `ensure_contains`. Pass112`baseline` (a directory or a `{file: text}` dict, e.g. the parent candidate) to have113`validate` report a constraint-line drop against it. A project adapter's `apply` can114call these directly.115116## How to run117118```119python scripts/check.py120python scripts/run.py --path <capability_dir> # candidate + validity121python scripts/run.py --path <candidate_dir> --baseline <parent_dir> # + rule-loss check122```123124## References125126- [`references/concepts.md`](references/concepts.md) — what the prompt controls, the127 six authoring practices and five failure modes in full, how to adapt a prompt to128 the runtime reader's capability tier, pitfalls, and cited sources. **Read once129 before your first non-trivial edit**, and again when a candidate is accepted but130 barely moves the metric.