(t *testing.T)
| 437 | } |
| 438 | if task.Status != "in-progress" { |
| 439 | t.Errorf("status: got %q, want in-progress", task.Status) |
| 440 | } |
| 441 | |
| 442 | script := getScript() |
| 443 | if strings.Contains(script, "--resume") { |
| 444 | t.Errorf("fresh spawn should not use --resume: %s", script) |
| 445 | } |
| 446 | if !strings.Contains(script, "--session-id "+pinnedSID) { |
| 447 | t.Errorf("fresh spawn should pass --session-id %s: %s", pinnedSID, script) |
| 448 | } |
| 449 | if !strings.Contains(script, "fresh-task") { |
| 450 | t.Errorf("spawn script missing task slug: %s", script) |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | // TestCmdDoFreshSpawnFailureRollsBackSessionID pins the rollback |
| 455 | // invariant: when a fresh-bootstrap spawn fails (e.g. Terminal.app |
| 456 | // Accessibility denied), BOTH the session_id pre-allocation AND the |
| 457 | // status flip must be undone so the next `flow do` retries |
| 458 | // bootstrap fresh. Under the session-id invariant |
| 459 | // (status='backlog' OR session_id IS NOT NULL), preserving status |
| 460 | // in-progress while dropping session_id would be illegal — full |
| 461 | // rollback is the only consistent recovery. |
| 462 | // |
| 463 | // Repro of the user-reported bug: spawn-failure → DB has orphan |
| 464 | // session_id → next flow do takes resume path → claude can't find |
| 465 | // the jsonl. The fix rolls everything back so the next attempt is |
| 466 | // indistinguishable from the first. |
| 467 | func TestCmdDoFreshSpawnFailureRollsBackSessionID(t *testing.T) { |
| 468 | setupFlowRoot(t) |
nothing calls this directly
no test coverage detected