Stop losing a lease to an arrow character

Run 9's planner wrote a dead end as "tried X -> failed because Y". The content
was exactly what the protocol asks for. The parser split on "→" only, refused
the handoff, and a refused handoff fails the release rather than the turn, so
the lease expired with the work intact and unrecorded.

Accept either arrow. A separator is not the thing being validated.

The prefix stripping was also wrong on the right-hand side: it trimmed
"failed because " from an untrimmed string that started with a space, so every
parsed dead end kept the literal prefix in why_failed.

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 15:11:06 +04:00
parent 4712c7dc0e
commit 98f1b2dccc
2 changed files with 40 additions and 4 deletions
+28
View File
@@ -365,3 +365,31 @@ func TestLastObservedCommandSkipsOrchestrasOwnHandoffWrite(t *testing.T) {
}
}
}
// Run 9 lost a lease because the agent wrote "->" instead of "→". The content
// was exactly right, the handoff was refused, and a refused handoff fails the
// release rather than the turn.
func TestDeadEndAcceptsEitherArrowAndStripsThePrefixes(t *testing.T) {
for _, arrow := range []string{"→", "->"} {
a, err := parseHandoffAnswer(`NEXT: inspect the failing integration test
WHY: isolate the regression before changing production code
REMAINING: fix the assertion after identifying the cause
DEAD ENDS: tried finding ids "F1".."F8" ` + arrow + ` failed because the schema requires lowercase
OPEN Q: whether the remote worker has the updated fixture
LEARNED: the fixture requires a committed scratch branch
`)
if err != nil {
t.Fatalf("arrow %q: %v", arrow, err)
}
if len(a.DeadEnds) != 1 {
t.Fatalf("arrow %q: parsed %d dead ends", arrow, len(a.DeadEnds))
}
d := a.DeadEnds[0]
if d.Tried != `finding ids "F1".."F8"` {
t.Errorf("arrow %q: tried = %q", arrow, d.Tried)
}
if d.WhyFailed != "the schema requires lowercase" {
t.Errorf("arrow %q: why_failed = %q", arrow, d.WhyFailed)
}
}
}