Consolidate all worktree sync, resource staleness, stale worktree escape,
and stale runtime unit cleanup into auto-worktree.ts. Extract shared
ROOT_STATE_FILES constant and isSamePath helper to eliminate triple
duplication of the rootFiles array and copy-pasted symlink checks.
Replace inline 26-line stale-unit cleanup in auto-start.ts with a call
to cleanStaleRuntimeUnits().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove duplicate resolveExpectedArtifactPath() and diagnoseExpectedArtifact()
from auto-recovery.ts, making auto-artifact-paths.ts the single source of truth.
auto-recovery.ts re-exports both functions for backward compatibility.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
guided-flow.ts has its own local implementation; the exported version
in auto-recovery.ts was never imported anywhere. Removes 35 lines of
dead code, the unused clearUnitRuntimeRecord import, and associated
tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
session-forensics.ts is a general-purpose JSONL parser that had a direct
import of getAutoWorktreePath from auto-worktree.ts, creating tight
coupling. getDeepDiagnostic now accepts an optional worktreePath parameter
instead of resolving it internally. The caller (auto.ts) resolves the
worktree path via readActiveMilestoneId + getAutoWorktreePath and passes
it in.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove basePath and unitId from RunVerificationGateOptions — they were
defined in the interface and passed by callers but never read by
runVerificationGate(). This eliminates false coupling where callers
compute values that have zero effect.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete unused resource-version.ts (functions duplicated in auto-worktree-sync.ts
with zero imports). Remove GitServiceImpl.git() private method with no call sites.
Clean up orphaned section headers and dangling JSDoc in git-service.ts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SLICE_BRANCH_RE, QUICK_BRANCH_RE, and WORKFLOW_BRANCH_RE were scattered
across worktree.ts and git-service.ts. Extract all three into
branch-patterns.ts as the single source of truth. Both original modules
re-export for backward compatibility — no consumer changes needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The lock acquisition had a primary path and a retry path with identical
28-line onCompromised callbacks and 6-line state assignment blocks (68 lines
of copy-paste). Extract into createLockCompromisedHandler() and
assignLockState() helpers so bug fixes only need to be applied once.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The doctor-environment and doctor-git tests used assertTrue and assertEq
which are not defined — they should be assert.ok and assert.equal from
the imported node:assert/strict module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These test files imported `assert` from node:assert/strict but used
assertTrue/assertEq (from test-helpers.ts createTestContext) without
importing them, breaking typecheck:extensions on main and all PRs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The GSD extension only listened for session_start, not session_switch.
When /resume switched to a previous session, GSD's write-gate, loop guard,
discussion flow, service tier, and tool API keys were never re-initialized,
leaving GSD in stale state from the prior session.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the free-form parameter listing in step 7 of complete-milestone.md
with structured, typed parameter definitions that match the tool schema in
db-tools.ts. Parameters are grouped into required and optional sections with
explicit types (marking arrays as arrays, booleans as booleans) to prevent
LLM validation failures when calling gsd_complete_milestone.
Fixes#2581
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The forensics prompt and gh skill used --label "bug" / --label "type:feature"
for issue classification, polluting the label taxonomy and leaving the Type
field unset. gh issue create has no --type flag, so issue types must be set
via GraphQL mutation after creation.
Closes#2579
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Auto-mode sessions are long-running (minutes to hours) with their own
internal per-unit timeout via auto-supervisor. The 300s overall timeout
was killing active sessions mid-execution, triggering wasteful restart
cycles.
Changes:
- Disable overall timeout for auto-mode when using the default 300s
(user can still set --timeout explicitly, including --timeout 0)
- Guard timeout timer creation for null when timeout is 0
- Cancel overall timeout when new-milestone --auto chains into auto-mode
- Fix headless auto-responder to pick "Force start" for lock-guard
prompts instead of "View status" (which silently blocked auto-mode)
- Allow --timeout 0 to explicitly disable timeout for any command
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(auto): align UAT artifact suffix with gsd_slice_complete output
The auto-mode files referenced UAT-RESULT as the artifact suffix,
but gsd_slice_complete writes files as S##-UAT.md. This mismatch
caused ENOENT errors during validate-milestone dispatch.
Fixes#2564
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(auto): update test and doc references from UAT-RESULT to UAT
Aligns test assertions and ADR documentation with the corrected
artifact suffix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(auto): replace separate UAT-RESULT file check with in-file verdict check
The original two-file model (UAT spec + UAT-RESULT verdict) never
worked because gsd_slice_complete only writes S##-UAT.md. The blind
string replacement made checkNeedsRunUat always return null by
resolving the same file twice. Now checks for a verdict: line inside
the UAT file content to determine if UAT has been completed.
Also deduplicates a redundant resolveSliceFile call in the verdict
gate and updates tests to verify the single-file verdict model.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server errors (500/502/503/504) are server-side failures — rotating
credentials doesn't help. Only rate_limit and quota_exhausted are
meaningfully credential-scoped. This prevents the cascading backoff
where a single 500 backs off the sole API key for 20s, causing all
subsequent retries to fail with "All credentials temporarily backed off".
Closes#2588
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SessionLockData no longer has a completedUnits field. Use sessionFile
(an actual optional field) for the same assertion coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
onCompromised was declaring lock lost when the lock file was temporarily
unreadable (NFS/CIFS latency, macOS APFS snapshot, or concurrent process
briefly holding the file). Add readExistingLockDataWithRetry (3 attempts,
200ms delay) so transient filesystem hiccups do not trigger false-positive
compromise events.
Fixes#2324
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>