fix(test): planning-lane E2E is RED on main (2/7, incl. its own control) — same unplanned-spec fixture defect #2634 fixed next door (#2658)

Found while establishing the pre-closing E2E baseline for the final
verification pass (closing bar, item 4). **Two of this family's seven
cases are failing on `origin/main` right now**, and one of them is its
own control.

```
releases an ordinary held card on a default board (the control)       expected [] to include 'FN-OK'
holds a card parked for approval MID-SWEEP, after the snapshot read   expected false to be true
```

## Cause — the same defect #2634 repaired in the file next door

`seedHeldTask` creates the task and never writes a `PROMPT.md`, so the
card carries only the bootstrap seed. FN-7648's
`isUnplannedForExecution` reads that file for any card resting in an
intake- or hold-trait column and refuses to move an unplanned card into
a processing column, so the sweep released nothing.

**Being held was the gate working.** The fixture was exercising the gate
rather than the sweep — which is exactly why the *control* failed, and a
failing control means the rest of the family's assertions cannot be
trusted either.

`workflow-lifecycle-live-e2e` had the identical problem and #2634 fixed
it the same way. This file landed alongside it (#2611) and did not get
the same treatment. Worth stating twice because it is a general rule for
this directory: **a release/scheduler fixture that does not model a card
which cleared specification is testing the gate, not the sweep.**

## The check that matters more than the fix

#2611's stated value is "3/7 red without the guard". Making red tests
green is the easiest thing in the world to do wrongly, so I verified the
family still discriminates *after* the seed — disabling
`isTaskBlockedOnApproval` in `hold-release.ts` still kills exactly
three, and the same three:

| killed by mutation |
|---|
| does NOT release a card blocked on manual plan approval on a
**default** board |
| does NOT release a card blocked on manual plan approval on a
**renamed** board |
| holds a card parked for approval **MID-SWEEP**, after the snapshot was
read |

Two cases turned green, zero discriminating power lost. Without that
mutation this change would be indistinguishable from weakening the tests
until they passed, which the standing rule forbids.

Note the third killed case is also one of the two that were failing: it
was red for the fixture reason **and** genuinely proves the guard.

## Why it is worth a PR of its own

The closing bar's final verification pass (gate, `verify:fast`, all E2E,
census) has to run on a green tree. Two red E2E cases on main would
otherwise show up in that report as a new failure and cost a diagnosis
at exactly the wrong moment.

Pre-closing baseline for the record — **13 E2E families, 109 tests,
these 2 the only failures**:

```
green  agent-count 13 · agent-link 5 · lease-rebound 6 · lifecycle 24 · merge-family 7
       merge-rebound 4 · merge-safeguards 10 · merged-board 5 · planner-lane 5
       planner-lane-resolution 3 · rebound-family 15 · stranded-column 5
RED    planning-lane 7  (2 failing)
```

## Verification

7/7 green, mutation 3/7 as designed, engine typecheck clean (0 lines),
`pnpm lint` exit 0, `pnpm test:gate` exit 0.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-07-30 00:47:43 -07:00
committed by GitHub
parent cef1b08af3
commit f6010ef558

View File

@@ -85,6 +85,28 @@ pgDescribe("live planning-lane E2E: real hold-release sweep + real PostgreSQL st
{ taskId, applyDefaultWorkflowSteps: false } as never,
);
await store.writeTaskWorkflowSelection(taskId, workflowId, []);
/*
FNXC:WorkflowLifecycleColumns 2026-07-30-09:30 (release-leg fixture fix, same defect as #2634):
The card needs a PLANNED PROMPT.md before the sweep will release it. Task creation leaves a
bootstrap seed ("# <id>\n\n<description>"), and FN-7648's `isUnplannedForExecution` reads that
file for any card resting in an intake- or hold-trait column and refuses to move an unplanned
card into a processing column. So the sweep released NOTHING and even this file's own control
case ("releases an ordinary held card on a default board") went red — the gate working, not a
scheduler defect.
Identical to the defect #2634 repaired in workflow-lifecycle-live-e2e, and the reason it is
worth stating twice: a release/scheduler fixture that does not model a card which cleared
specification is testing the gate, not the sweep.
*/
const { writeFileSync, mkdirSync } = await import("node:fs");
const { join } = await import("node:path");
const dir = join((store as never as { getTasksDir(): string }).getTasksDir(), taskId);
mkdirSync(dir, { recursive: true });
writeFileSync(
join(dir, "PROMPT.md"),
`# ${taskId}\n\n## Context\nA planned spec, so the release sweep does not classify this card as an unplanned seed.\n\n## Steps\n### Step 1\n- [ ] do the planned work\n`,
"utf-8",
);
if (Object.keys(fields).length > 0) await store.updateTask(taskId, fields as never);
store.taskCache.delete(taskId);
}