State the handoff length limit on every field it bounds

The prompt gave "at most 200 characters" for NEXT, WHY and REMAINING. The
validator applies it to OPEN Q and LEARNED as well, and run 10 lost a lease to
a 219-character OPEN Q against a limit nobody had stated for that field.

Third instance of one shape: a constraint the code enforces and no brief
mentions. The other two were the research finding id and the dead-end
separator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVbaKucEYBjMqVeUgJUsc1
This commit is contained in:
2026-08-28 16:08:10 +04:00
parent d7e75e9e31
commit 015764ec7b
2 changed files with 22 additions and 2 deletions
+2 -2
View File
@@ -199,8 +199,8 @@ NEXT: the single next action (one line, at most 200 characters).
WHY: why that is next (one line, at most 200 characters).
REMAINING: outstanding items, one line each, at most 200 characters each. If none: NONE.
DEAD ENDS: approaches tried that failed — "X → why it failed", one per line. Either arrow, and the words "tried"/"failed because" are optional. If none: NONE.
OPEN Q: unresolved decisions, one line each. If none: NONE.
LEARNED: constraints discovered that are NOT in TASK.md, one line each. If none: NONE.
OPEN Q: unresolved decisions, one line each, at most 200 characters each. If none: NONE.
LEARNED: constraints discovered that are NOT in TASK.md, one line each, at most 200 characters each. If none: NONE.
Do NOT include: what you completed (the diff shows it), the goal or done-criteria (TASK.md holds them), git SHAs/branches/paths, or a prose summary. No headings and no report. Do not edit TASK.md.`
+20
View File
@@ -9,6 +9,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
@@ -408,3 +409,22 @@ LEARNED: e
t.Error("a dead end with no separator was accepted")
}
}
// Every field the validator bounds must say so. Run 10 lost a lease to a
// 219-character OPEN Q against a limit the prompt stated for NEXT, WHY and
// REMAINING only.
func TestHandoffPromptStatesTheLimitOnEveryBoundedField(t *testing.T) {
for _, field := range []string{"NEXT", "WHY", "REMAINING", "OPEN Q", "LEARNED"} {
i := strings.Index(handoffPrompt, field+":")
if i < 0 {
t.Fatalf("the prompt never names %s", field)
}
line := handoffPrompt[i:]
if j := strings.Index(line, "\n"); j >= 0 {
line = line[:j]
}
if !strings.Contains(line, "200 characters") {
t.Errorf("%s is bounded at 200 but the prompt never says so: %q", field, line)
}
}
}