Blocking on "unknown" from hasImplementationArtifacts broke real-world
auto-mode in projects without clean git merge-bases (single-branch,
fresh repos, detached HEAD). The auto-loop silently stopped at
completing-milestone with no visible error.
Reverted to warn-and-proceed for "unknown" — only "absent" (confirmed
no implementation files) blocks completion. This matches the original
fail-open behavior for inconclusive git checks.
1. hasImplementationArtifacts "unknown" now blocks completion instead of
warn-and-proceed. Both auto-dispatch.ts and auto-recovery.ts updated
to treat "unknown" as a stop condition, preventing milestone completion
when git status cannot be verified.
2. Audit log SAFE_KEYS allowlist expanded to include "id", "error", and
"count" fields. SPLIT BRAIN logError entries now persist the entity ID
and rollback error details to audit-log.jsonl for triage/repair.
1. Paused session file deletion deferred until after lock acquisition.
Previously the file was deleted before acquireSessionLock — if the
lock failed, the pause metadata was lost on disk and in memory,
making the session unresumable. Now the file path is stored in
s.pausedSessionFile and only deleted after successful lock.
2. Lock failure path preserves pause file for retry.
Five fixes for session lifecycle and recovery reliability:
1. hasImplementationArtifacts now returns tri-state ("present"|"absent"|"unknown")
instead of boolean. "unknown" on git errors lets callers warn+proceed instead
of either silently blocking or silently allowing. Both callers updated.
2. DB-ahead-of-disk split-brain: rollback DELETE in db-writer.ts saveDecisionToDb
and saveRequirementToDb now wrapped in try/catch with logError. A failed
rollback is explicitly logged as SPLIT BRAIN so the orphaned row is auditable.
3. _consecutiveCompleteBootstraps moved from module-level in auto-start.ts into
AutoSession class. Now properly reset by s.reset(), preventing cross-session
counter bleed in long-running processes (VS Code extension).
4. s.paused sticky on lock failure: when acquireSessionLock fails during resume,
s.paused is now set back to false so isAutoPaused() doesn't return true
permanently.
5. nativeCommit empty message replaced with "chore(gsd): reconcile merge state"
to avoid rejection by strict git configurations.
Ecosystem research: executeSearchQuery() was a stub returning empty
results. Research now happens during the discussion (between Layer 1
and Layer 2) using whatever web search tools are available — native
Anthropic web search for Claude, search-the-web for other providers.
Preparation phase focuses on mechanical work only.
Adversarial review fixes:
- Clear lastPreparationResult on every discuss entry to prevent
cross-session/project state leaks
- Replace invalid JS regex anchor \z with indexOf-based section
extraction in prompt-validation.ts
- Document consecutive error counter finding as upstream behavior
(agent-loop.ts is part of pi-agent-core, not gsd extension)
The Model [phase] [tier] notification fired on every unit dispatch during
auto-mode, cluttering the notification widget. The dashboard header already
displays the active model, making this redundant. Gate behind verbose flag
consistent with all other model routing notifications in the same function.
task.files ("files likely touched") is a planning hint that includes files
a task will create, not a dependency contract. Including it in ordering
checks caused false "sequence violation" blocking errors when a task listed
files it would create. Only task.inputs (machine-parsed prerequisites)
should trigger ordering violations, matching checkFilePathConsistency (#3626).
Closes#3677
- Changed checkTaskOrdering to check [...task.inputs] instead of
[...task.files, ...task.inputs]
- Updated 4 existing tests to use inputs (were testing buggy behavior)
- Added 8 regression tests: 5 ordering false-positive cases,
3 consistency edge cases
The ghost milestone check (#3645) was eliminating queued shell
milestones before the deferred-shell logic (#3470) could handle them,
causing queued milestones to vanish from the registry entirely.
Fixes workflow-logger coverage test failures: empty catch blocks in
reopen-slice/reopen-task and raw process.stderr in reopen-milestone
now use logWarning from workflow-logger.
Fixes identified by comprehensive state machine validation:
- M12: reopen-task/slice now deletes SUMMARY.md from disk, preventing
the DB-filesystem reconciler from auto-correcting tasks back to
"complete" — reopen was previously a no-op when artifacts existed
- H4: add 30s hard timeout to unitPromise via Promise.race — prevents
permanent hang if supervision fails to resolve agent_end
- H5: add handleReopenMilestone — milestone completion was irrevocable
- H6: pass ID as title when auto-creating phantom parent entities
- H7: guard loadRegistry() against missing/corrupt registry.json
- M4: report_blocker replay now sets blocker_discovered flag via
new setTaskBlockerDiscovered() DB function
- M5: insertVerificationEvidence uses INSERT OR IGNORE with unique
index on (task_id, slice_id, milestone_id, command, verdict)
- M11: complete-slice rollback preserves original status instead of
hardcoding "pending"
- M14: deriveWorkflowAction shows contextual labels for blocked,
paused, validating-milestone, completing-milestone, needs-discussion,
and replanning-slice phases instead of generic "Continue"
Includes 86 regression tests (49 unit + 37 integration) validating
every phase transition, completion guard, and edge case.
Closes#3161