fix: reconcile stale task status in filesystem-based state derivation (#2514)
`_deriveStateImpl` (used when no gsd.db exists) lacked the SUMMARY-based reconciliation added to `deriveStateFromDb` in0e7a01f4. Heading-style tasks (`### T01:`) are always parsed as `done=false` by `parsePlan` because the heading syntax has no checkbox. When the agent writes a SUMMARY file but the plan heading has no checkbox, the task appears incomplete forever, causing infinite re-dispatch. Now checks each non-done task for a SUMMARY file on disk after `parsePlan()`, mirroring the DB reconciliation logic. Root cause: `parsePlan()` recognizes two task formats: 1. `- [x] **T01: Title**` → done from checkbox state 2. `### T01: Title` → always done=false (no checkbox to read) The DB path (deriveStateFromDb) was already fixed in0e7a01f4to reconcile via SUMMARY files. This commit applies the same fix to the filesystem path used by projects without gsd.db.
This commit is contained in:
parent
c6328a229f
commit
43de82912e
1 changed files with 18 additions and 0 deletions
|
|
@ -1248,6 +1248,24 @@ export async function _deriveStateImpl(basePath: string): Promise<GSDState> {
|
|||
}
|
||||
|
||||
const slicePlan = parsePlan(slicePlanContent);
|
||||
|
||||
// ── Reconcile stale task status for filesystem-based projects (#2514) ──
|
||||
// Heading-style tasks (### T01:) are always parsed as done=false by
|
||||
// parsePlan because the heading syntax has no checkbox. When the agent
|
||||
// writes a SUMMARY file but the plan's heading isn't converted to a
|
||||
// checkbox, the task appears incomplete forever — causing infinite
|
||||
// re-dispatch. Reconcile by checking SUMMARY files on disk.
|
||||
for (const t of slicePlan.tasks) {
|
||||
if (t.done) continue;
|
||||
const summaryPath = resolveTaskFile(basePath, activeMilestone.id, activeSlice.id, t.id, "SUMMARY");
|
||||
if (summaryPath && existsSync(summaryPath)) {
|
||||
t.done = true;
|
||||
process.stderr.write(
|
||||
`gsd-reconcile: task ${activeMilestone.id}/${activeSlice.id}/${t.id} has SUMMARY on disk but plan shows incomplete — marking done (#2514)\n`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const taskProgress = {
|
||||
done: slicePlan.tasks.filter(t => t.done).length,
|
||||
total: slicePlan.tasks.length,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue