Planning bug: a region measured by SEARCHING for its boundary — `SHARED PLANNING RULES` occurs inside the framing it was cutting
A figure was measured with a CUT POINT that was not the thing it was named for, and it went onto a story, a card and an ADR before anybody re-read it.
The claim
MOTIR-3916 and MOTIR-3918 both stated: "every deepen session gets 5,161 chars of skeleton instruction."
How it was produced
i = system_message.index('SHARED PLANNING RULES')
framing = system_message[:i] # 5,161
The command is correct, the string is present, and the number is arithmetically true of the region it measured. It is not the framing. SHARED PLANNING RULES first occurs at offset 5,217 inside RUNBOOK_PROMPT itself, in a CROSS-REFERENCE:
"…set each leaf's
type/executorand plan the COMPLETE type set + canonical composition + the two story-level test subtasks — all in the SHARED PLANNING RULES below."
So the cut landed in the middle of the framing, on a sentence that POINTS at the rule section rather than starting it.
What it actually is
Measured from the constants instead of by string search:
| chars | |
|---|---|
| full deepen system message | 127,705 |
rule section (composePlanningRules) | 117,494 |
| framing | 10,211 |
— RUNBOOK_PROMPT | 6,997 |
— GENERATION_FEWSHOT | 2,742 |
| — mode note + separators | ≈472 |
Skeleton-only portion ≈8,416, not 5,161 — the error UNDERSTATED the defect by about 63%.
Why no gate caught it
core.md gate 2's QUANTITY limb is exactly on point — "a threshold, share, count or projection may not be written into a criterion unless the measurement producing it was RUN, at the criterion's OWN scope" — and it names this failure shape by name: the denominator swap, "a corpus-wide share quoted about one region". It was run, at what looked like the right scope, and the constant it depended on (where the rule section begins) was inferred from a string rather than read.
The tell that generalises: the figure came from a SEARCH for a boundary, not from the thing that DEFINES the boundary. The system message is assembled by buildGenerationSystemPrompt as [runbook, '', rules, …] — the boundary is a concatenation the code performs, and the code is right there. Searching for a heading finds the first place that heading is MENTIONED, and a corpus of rules mentions its own headings constantly.
The fix, which is a rule change
core.md gate 2's QUANTITY limb requires the tool, the scope and the reading. It should also require, for a figure that measures a REGION of an assembled artifact, that the region's boundary come from the assembly rather than from a search over the result — len(part) where the parts are exported, never result.index(marker). A marker that appears inside the region it is supposed to bound is not an exotic case; in a corpus that cross-references itself it is the norm.
The mechanised half is cheap where the parts are exported constants, which is the case here and in every composition this corpus performs.
Amendments already applied
- MOTIR-3916 and MOTIR-3918: the paragraph struck and replaced with the re-measurement and its per-section table.
motir-metaprompts/plan-rules/DECISION.rule-phase.mdquotes the corrected framing total; it never quoted the 5,161.