gsd-pi 2.78.1-dev.e9d88a536 → 2.78.1-dev.eccf86e27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/dist/help-text.js +1 -1
- package/dist/resource-loader.js +6 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +41 -5
- package/dist/resources/extensions/gsd/auto/loop.js +235 -36
- package/dist/resources/extensions/gsd/auto/phases.js +14 -7
- package/dist/resources/extensions/gsd/auto/session.js +36 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +49 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +26 -12
- package/dist/resources/extensions/gsd/auto-worktree.js +185 -201
- package/dist/resources/extensions/gsd/auto.js +139 -49
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +26 -20
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -55
- package/dist/resources/extensions/gsd/crash-recovery.js +160 -47
- package/dist/resources/extensions/gsd/db/auto-workers.js +227 -0
- package/dist/resources/extensions/gsd/db/command-queue.js +105 -0
- package/dist/resources/extensions/gsd/db/milestone-leases.js +210 -0
- package/dist/resources/extensions/gsd/db/runtime-kv.js +91 -0
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +322 -0
- package/dist/resources/extensions/gsd/db-writer.js +96 -16
- package/dist/resources/extensions/gsd/delegation-policy.js +155 -0
- package/dist/resources/extensions/gsd/docs/COORDINATION.md +42 -0
- package/dist/resources/extensions/gsd/doctor-proactive.js +4 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -6
- package/dist/resources/extensions/gsd/doctor.js +12 -2
- package/dist/resources/extensions/gsd/gsd-db.js +355 -3
- package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +116 -26
- package/dist/resources/extensions/gsd/interrupted-session.js +18 -15
- package/dist/resources/extensions/gsd/metrics.js +287 -1
- package/dist/resources/extensions/gsd/paths.js +79 -8
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
- package/dist/resources/extensions/gsd/state.js +21 -6
- package/dist/resources/extensions/gsd/templates/project.md +10 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/workspace.js +59 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +79 -2
- package/dist/resources/extensions/gsd/write-intercept.js +3 -3
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/README.md +2 -11
- package/packages/mcp-server/dist/remote-questions.d.ts +27 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +28 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts +28 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +94 -4
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +226 -0
- package/packages/mcp-server/src/remote-questions.test.ts +103 -0
- package/packages/mcp-server/src/remote-questions.ts +35 -0
- package/packages/mcp-server/src/server.ts +129 -6
- package/packages/mcp-server/src/workflow-tools.ts +1 -1
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +37 -5
- package/src/resources/extensions/gsd/auto/loop.ts +263 -41
- package/src/resources/extensions/gsd/auto/phases.ts +15 -7
- package/src/resources/extensions/gsd/auto/session.ts +40 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +63 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +27 -12
- package/src/resources/extensions/gsd/auto-worktree.ts +218 -225
- package/src/resources/extensions/gsd/auto.ts +166 -43
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +26 -21
- package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +103 -0
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -55
- package/src/resources/extensions/gsd/crash-recovery.ts +177 -43
- package/src/resources/extensions/gsd/db/auto-workers.ts +273 -0
- package/src/resources/extensions/gsd/db/command-queue.ts +149 -0
- package/src/resources/extensions/gsd/db/milestone-leases.ts +274 -0
- package/src/resources/extensions/gsd/db/runtime-kv.ts +127 -0
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +446 -0
- package/src/resources/extensions/gsd/db-writer.ts +113 -17
- package/src/resources/extensions/gsd/delegation-policy.ts +197 -0
- package/src/resources/extensions/gsd/docs/COORDINATION.md +42 -0
- package/src/resources/extensions/gsd/doctor-proactive.ts +4 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +24 -6
- package/src/resources/extensions/gsd/doctor.ts +10 -2
- package/src/resources/extensions/gsd/gsd-db.ts +354 -3
- package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +152 -26
- package/src/resources/extensions/gsd/interrupted-session.ts +19 -12
- package/src/resources/extensions/gsd/metrics.ts +321 -1
- package/src/resources/extensions/gsd/paths.ts +67 -8
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
- package/src/resources/extensions/gsd/state.ts +44 -6
- package/src/resources/extensions/gsd/templates/project.md +10 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +14 -14
- package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/auto-loop-symlink-worktree.test.ts +190 -0
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +331 -0
- package/src/resources/extensions/gsd/tests/auto-workers.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/command-queue.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +169 -59
- package/src/resources/extensions/gsd/tests/db-writer-path-containment.test.ts +152 -0
- package/src/resources/extensions/gsd/tests/db-writer-root-artifact.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/db-writer-scope.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/delegation-policy.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/detect-stuck-respects-retry.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/dispatch-backgroundable-annotation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +3 -23
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +246 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +218 -0
- package/src/resources/extensions/gsd/tests/gsd-db-failed-open-restore.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/gsd-db-workspace-scope.test.ts +226 -0
- package/src/resources/extensions/gsd/tests/gsd-root-canonical.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/gsd-root-home-guard.test.ts +68 -5
- package/src/resources/extensions/gsd/tests/guided-flow-prompt-consolidation.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +22 -12
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +24 -10
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +35 -23
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +369 -0
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +72 -25
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +72 -25
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +9 -6
- package/src/resources/extensions/gsd/tests/metrics-atomic-merge.test.ts +222 -0
- package/src/resources/extensions/gsd/tests/metrics-lock-hardening.test.ts +400 -0
- package/src/resources/extensions/gsd/tests/metrics-lock-not-acquired.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/metrics-lock-retry-sleep.test.ts +287 -0
- package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +149 -0
- package/src/resources/extensions/gsd/tests/metrics-scope.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +152 -0
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +329 -0
- package/src/resources/extensions/gsd/tests/parallel-milestone-isolation.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/path-cache-decoupled.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/path-normalization-unified.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/paths-cache.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/paused-session-via-db.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +3 -17
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +150 -7
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +138 -16
- package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/runtime-kv.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +133 -28
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +434 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +247 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +41 -1
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +239 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/workspace.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +35 -35
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +94 -71
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +1 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/workspace.ts +95 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +78 -2
- package/src/resources/extensions/gsd/write-intercept.ts +3 -3
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +0 -213
- package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +0 -87
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +0 -159
- /package/dist/web/standalone/.next/static/{oZGTPvJBQX_IDKKnuV8Bt → Y5UeGFkXTYM9WIQOWHkot}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{oZGTPvJBQX_IDKKnuV8Bt → Y5UeGFkXTYM9WIQOWHkot}/_ssgManifest.js +0 -0
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* `let` or `var` declarations.
|
|
17
17
|
*/
|
|
18
18
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
19
|
+
import { normalizeRealPath } from "../paths.js";
|
|
19
20
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
20
21
|
export const STUB_RECOVERY_THRESHOLD = 2;
|
|
21
22
|
export const NEW_SESSION_TIMEOUT_MS = 120_000;
|
|
@@ -32,6 +33,22 @@ export class AutoSession {
|
|
|
32
33
|
// ── Paths ────────────────────────────────────────────────────────────────
|
|
33
34
|
basePath = "";
|
|
34
35
|
originalBasePath = "";
|
|
36
|
+
// TODO(C8): remove basePath/originalBasePath once all readers use s.scope
|
|
37
|
+
scope = null;
|
|
38
|
+
// ── Coordination identity (Phase B — DB-backed coordination) ────────────
|
|
39
|
+
/**
|
|
40
|
+
* Worker registry ID set by registerAutoWorker() at session start. Used by
|
|
41
|
+
* heartbeatAutoWorker() each loop iteration and by recordDispatchClaim()
|
|
42
|
+
* to fence dispatch ledger writes against stale workers.
|
|
43
|
+
*/
|
|
44
|
+
workerId = null;
|
|
45
|
+
/**
|
|
46
|
+
* Active milestone lease fencing token, set by claimMilestoneLease() inside
|
|
47
|
+
* worktree-resolver.enterMilestone(). Threaded into recordDispatchClaim()
|
|
48
|
+
* as milestone_lease_token so out-of-band dispatches by a stale worker
|
|
49
|
+
* are detectable.
|
|
50
|
+
*/
|
|
51
|
+
milestoneLeaseToken = null;
|
|
35
52
|
previousProjectRootEnv = null;
|
|
36
53
|
hadProjectRootEnv = false;
|
|
37
54
|
projectRootEnvCaptured = false;
|
|
@@ -160,6 +177,22 @@ export class AutoSession {
|
|
|
160
177
|
get lockBasePath() {
|
|
161
178
|
return resolveWorktreeProjectRoot(this.basePath, this.originalBasePath);
|
|
162
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Canonical project root for state-derivation reads AND writer paths.
|
|
182
|
+
*
|
|
183
|
+
* Prefers the realpath-normalized projectRoot from the MilestoneScope
|
|
184
|
+
* (introduced by PR #5236), falling back to resolveWorktreeProjectRoot
|
|
185
|
+
* during early lifecycle / engine-bypass paths where scope may be null.
|
|
186
|
+
*
|
|
187
|
+
* Always realpath-normalized so cache keys (e.g. deriveState's _stateCache)
|
|
188
|
+
* cannot drift across worktree↔project-root path-string variants for the
|
|
189
|
+
* same filesystem location.
|
|
190
|
+
*/
|
|
191
|
+
get canonicalProjectRoot() {
|
|
192
|
+
const root = this.scope?.workspace.projectRoot
|
|
193
|
+
?? resolveWorktreeProjectRoot(this.basePath, this.originalBasePath);
|
|
194
|
+
return normalizeRealPath(root);
|
|
195
|
+
}
|
|
163
196
|
reset() {
|
|
164
197
|
this.clearTimers();
|
|
165
198
|
// Lifecycle
|
|
@@ -173,6 +206,9 @@ export class AutoSession {
|
|
|
173
206
|
// Paths
|
|
174
207
|
this.basePath = "";
|
|
175
208
|
this.originalBasePath = "";
|
|
209
|
+
this.scope = null;
|
|
210
|
+
this.workerId = null;
|
|
211
|
+
this.milestoneLeaseToken = null;
|
|
176
212
|
this.previousProjectRootEnv = null;
|
|
177
213
|
this.hadProjectRootEnv = false;
|
|
178
214
|
this.projectRootEnvCaptured = false;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* without modifying orchestration code.
|
|
10
10
|
*/
|
|
11
11
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
12
|
-
import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted, getMilestone } from "./gsd-db.js";
|
|
12
|
+
import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted, getMilestone, insertAssessment, transaction } from "./gsd-db.js";
|
|
13
13
|
import { isClosedStatus } from "./status-guards.js";
|
|
14
14
|
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
15
15
|
import { gsdRoot, resolveMilestoneFile, resolveMilestonePath, resolveSliceFile, resolveTaskFile, relSliceFile, buildMilestoneFileName, } from "./paths.js";
|
|
@@ -31,6 +31,9 @@ import { ensureWorkflowPreferencesCaptured } from "./planning-depth.js";
|
|
|
31
31
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
32
32
|
import { PROJECT_RESEARCH_INFLIGHT_MARKER, } from "./project-research-policy.js";
|
|
33
33
|
import { isWorkflowPrefsCaptured, resolveDeepProjectSetupState, } from "./deep-project-setup-policy.js";
|
|
34
|
+
import { annotateBackgroundable } from "./delegation-policy.js";
|
|
35
|
+
import { invalidateAllCaches } from "./cache.js";
|
|
36
|
+
import { insertMilestoneValidationGates } from "./milestone-validation-gates.js";
|
|
34
37
|
let reassessmentChecker = checkNeedsReassessment;
|
|
35
38
|
let researchProjectPromptBuilder = buildResearchProjectPrompt;
|
|
36
39
|
function shouldBypassMilestoneDepthGateInAuto(prefs) {
|
|
@@ -995,9 +998,12 @@ export const DISPATCH_RULES = [
|
|
|
995
998
|
const skipSource = trivialVariant
|
|
996
999
|
? "trivial-scope pipeline variant (#4781)"
|
|
997
1000
|
: "`skip_milestone_validation` preference";
|
|
1001
|
+
const skipValidationReason = trivialVariant ? "trivial-scope" : "preference";
|
|
998
1002
|
const content = [
|
|
999
1003
|
"---",
|
|
1000
1004
|
"verdict: pass",
|
|
1005
|
+
"skip_validation: true",
|
|
1006
|
+
`skip_validation_reason: ${skipValidationReason}`,
|
|
1001
1007
|
"remediation_round: 0",
|
|
1002
1008
|
"---",
|
|
1003
1009
|
"",
|
|
@@ -1006,6 +1012,39 @@ export const DISPATCH_RULES = [
|
|
|
1006
1012
|
`Milestone validation was skipped via ${skipSource}.`,
|
|
1007
1013
|
].join("\n");
|
|
1008
1014
|
writeFileSync(validationPath, content, "utf-8");
|
|
1015
|
+
try {
|
|
1016
|
+
// DB-backed state derivation keys off assessments, not only the file
|
|
1017
|
+
// projection. Persist the skipped validation there too so the next
|
|
1018
|
+
// loop iteration advances to completing-milestone instead of
|
|
1019
|
+
// re-entering validating-milestone.
|
|
1020
|
+
if (isDbAvailable()) {
|
|
1021
|
+
transaction(() => {
|
|
1022
|
+
insertAssessment({
|
|
1023
|
+
path: validationPath,
|
|
1024
|
+
milestoneId: mid,
|
|
1025
|
+
sliceId: null,
|
|
1026
|
+
taskId: null,
|
|
1027
|
+
status: "pass",
|
|
1028
|
+
scope: "milestone-validation",
|
|
1029
|
+
fullContent: content,
|
|
1030
|
+
});
|
|
1031
|
+
const gateSliceId = getMilestoneSlices(mid)[0]?.id;
|
|
1032
|
+
if (gateSliceId) {
|
|
1033
|
+
insertMilestoneValidationGates(mid, gateSliceId, "pass", new Date().toISOString());
|
|
1034
|
+
}
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
catch (err) {
|
|
1039
|
+
try {
|
|
1040
|
+
unlinkSync(validationPath);
|
|
1041
|
+
}
|
|
1042
|
+
catch (unlinkErr) {
|
|
1043
|
+
logWarning("dispatch", `failed to remove skipped validation file after DB write failure for ${mid}: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`);
|
|
1044
|
+
}
|
|
1045
|
+
throw err;
|
|
1046
|
+
}
|
|
1047
|
+
invalidateAllCaches();
|
|
1009
1048
|
}
|
|
1010
1049
|
return { action: "skip" };
|
|
1011
1050
|
}
|
|
@@ -1086,13 +1125,19 @@ export const DISPATCH_RULES = [
|
|
|
1086
1125
|
if (validationContent) {
|
|
1087
1126
|
// Allow completion when validation was intentionally skipped by
|
|
1088
1127
|
// preference/budget profile (#3399, #3344).
|
|
1128
|
+
const skippedByMarker = /^skip_validation:\s*true$/im.test(validationContent);
|
|
1089
1129
|
const skippedByPreference = /skip(?:ped)?[\s\-]+(?:by|per|due to)\s+(?:preference|budget|profile)/i.test(validationContent);
|
|
1130
|
+
const skippedByTrivialVariant = /trivial-scope pipeline variant/i.test(validationContent);
|
|
1090
1131
|
// Accept either the structured template format (table with MET/N/A/SATISFIED)
|
|
1091
1132
|
// or prose evidence patterns the validation agent may emit.
|
|
1092
1133
|
const structuredMatch = validationContent.includes("Operational") &&
|
|
1093
1134
|
(validationContent.includes("MET") || validationContent.includes("N/A") || validationContent.includes("SATISFIED"));
|
|
1094
1135
|
const proseMatch = /[Oo]perational[\s\S]{0,500}?(?:✅|pass|verified|confirmed|met|complete|true|yes|addressed|covered|satisfied|partially|n\/a|not[\s-]+applicable)/i.test(validationContent);
|
|
1095
|
-
const hasOperationalCheck =
|
|
1136
|
+
const hasOperationalCheck = skippedByMarker ||
|
|
1137
|
+
skippedByPreference ||
|
|
1138
|
+
skippedByTrivialVariant ||
|
|
1139
|
+
structuredMatch ||
|
|
1140
|
+
proseMatch;
|
|
1096
1141
|
if (!hasOperationalCheck) {
|
|
1097
1142
|
return {
|
|
1098
1143
|
action: "stop",
|
|
@@ -1152,7 +1197,7 @@ export async function resolveDispatch(ctx) {
|
|
|
1152
1197
|
// Delegate to registry when available
|
|
1153
1198
|
try {
|
|
1154
1199
|
const registry = getRegistry();
|
|
1155
|
-
return await registry.evaluateDispatch(ctx);
|
|
1200
|
+
return annotateBackgroundable(await registry.evaluateDispatch(ctx));
|
|
1156
1201
|
}
|
|
1157
1202
|
catch (err) {
|
|
1158
1203
|
// Registry not initialized — fall back to inline loop
|
|
@@ -1163,7 +1208,7 @@ export async function resolveDispatch(ctx) {
|
|
|
1163
1208
|
if (result) {
|
|
1164
1209
|
if (result.action !== "skip")
|
|
1165
1210
|
result.matchedRule = rule.name;
|
|
1166
|
-
return result;
|
|
1211
|
+
return annotateBackgroundable(result);
|
|
1167
1212
|
}
|
|
1168
1213
|
}
|
|
1169
1214
|
// No rule matched — unhandled phase.
|
|
@@ -24,6 +24,7 @@ import { runTurnGitAction, } from "./git-service.js";
|
|
|
24
24
|
import { verifyExpectedArtifact, resolveExpectedArtifactPath, writeBlockerPlaceholder, diagnoseExpectedArtifact, } from "./auto-recovery.js";
|
|
25
25
|
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
26
26
|
import { syncStateToProjectRoot } from "./auto-worktree.js";
|
|
27
|
+
import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
27
28
|
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
28
29
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
29
30
|
import { consumeSignal } from "./session-status-io.js";
|
|
@@ -51,6 +52,11 @@ import { detectAbandonMilestone } from "./abandon-detect.js";
|
|
|
51
52
|
import { isDeterministicPolicyError } from "./auto-tool-tracking.js";
|
|
52
53
|
import { clearProjectResearchInflightMarker, finalizeProjectResearchTimeout, } from "./project-research-policy.js";
|
|
53
54
|
import { validateArtifact } from "./schemas/validate.js";
|
|
55
|
+
// ─── Path Comparison Helper ───────────────────────────────────────────────
|
|
56
|
+
/** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
|
|
57
|
+
function isSamePathLocal(a, b) {
|
|
58
|
+
return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
|
|
59
|
+
}
|
|
54
60
|
/** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
|
|
55
61
|
const MAX_VERIFICATION_RETRIES = 3;
|
|
56
62
|
/** Keep failure toasts short while still showing concrete examples. */
|
|
@@ -510,7 +516,7 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
510
516
|
await rebuildState(s.basePath);
|
|
511
517
|
});
|
|
512
518
|
// Sync worktree state back to project root (skipped for lightweight sidecars)
|
|
513
|
-
if (!opts?.skipWorktreeSync && s.originalBasePath && s.originalBasePath
|
|
519
|
+
if (!opts?.skipWorktreeSync && s.originalBasePath && !isSamePathLocal(s.originalBasePath, s.basePath)) {
|
|
514
520
|
await runSafely("postUnit", "worktree-sync", () => {
|
|
515
521
|
syncStateToProjectRoot(s.basePath, s.originalBasePath, s.currentMilestoneId);
|
|
516
522
|
});
|
|
@@ -650,13 +656,15 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
650
656
|
if (s.currentUnit.type === "triage-captures") {
|
|
651
657
|
try {
|
|
652
658
|
const { executeTriageResolutions } = await import("./triage-resolution.js");
|
|
653
|
-
const state = await deriveState(s.
|
|
659
|
+
const state = await deriveState(s.canonicalProjectRoot);
|
|
654
660
|
const mid = state.activeMilestone?.id ?? "";
|
|
655
661
|
const sid = state.activeSlice?.id ?? "";
|
|
656
662
|
// executeTriageResolutions handles defer milestone creation even
|
|
657
663
|
// without an active milestone/slice (the "all milestones complete"
|
|
658
664
|
// scenario from #1562). inject/replan/quick-task still require mid+sid.
|
|
659
|
-
|
|
665
|
+
// Phase C: write to canonical project root. copyPlanningArtifacts
|
|
666
|
+
// has been deleted, so triage writes land where readers consult.
|
|
667
|
+
const triageResult = executeTriageResolutions(s.canonicalProjectRoot, mid, sid);
|
|
660
668
|
if (triageResult.injected > 0) {
|
|
661
669
|
ctx.ui.notify(`Triage: injected ${triageResult.injected} task${triageResult.injected === 1 ? "" : "s"} into ${sid} plan.`, "info");
|
|
662
670
|
}
|
|
@@ -799,10 +807,14 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
799
807
|
try {
|
|
800
808
|
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
801
809
|
if (mid && sid) {
|
|
802
|
-
|
|
810
|
+
// Phase C: write to the canonical project root (#5236 scope)
|
|
811
|
+
// so non-symlinked worktrees no longer maintain a separate
|
|
812
|
+
// local .gsd/ projection. copyPlanningArtifacts has been
|
|
813
|
+
// deleted; reads + writes converge at projectRoot.
|
|
814
|
+
const regenerated = await regenerateIfMissing(s.canonicalProjectRoot, mid, sid, "PLAN");
|
|
803
815
|
if (regenerated) {
|
|
804
816
|
// Re-check after regeneration
|
|
805
|
-
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.
|
|
817
|
+
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.canonicalProjectRoot);
|
|
806
818
|
if (triggerArtifactVerified) {
|
|
807
819
|
invalidateAllCaches();
|
|
808
820
|
}
|
|
@@ -993,7 +1005,7 @@ export async function postUnitPostVerification(pctx) {
|
|
|
993
1005
|
if (mid && sid && tid) {
|
|
994
1006
|
try {
|
|
995
1007
|
updateTaskStatus(mid, sid, tid, "pending");
|
|
996
|
-
await renderPlanCheckboxes(s.
|
|
1008
|
+
await renderPlanCheckboxes(s.canonicalProjectRoot, mid, sid);
|
|
997
1009
|
}
|
|
998
1010
|
catch (dbErr) {
|
|
999
1011
|
// DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
|
|
@@ -1003,7 +1015,8 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1003
1015
|
}
|
|
1004
1016
|
// 2. Delete SUMMARY.md for the task
|
|
1005
1017
|
if (mid && sid && tid) {
|
|
1006
|
-
|
|
1018
|
+
// Phase C: read+delete via canonical project root.
|
|
1019
|
+
const tasksDir = resolveTasksDir(s.canonicalProjectRoot, mid, sid);
|
|
1007
1020
|
if (tasksDir) {
|
|
1008
1021
|
const summaryFile = join(tasksDir, buildTaskFileName(tid, "SUMMARY"));
|
|
1009
1022
|
if (existsSync(summaryFile)) {
|
|
@@ -1013,7 +1026,7 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1013
1026
|
}
|
|
1014
1027
|
// 3. Delete the retry_on artifact (e.g. NEEDS-REWORK.md)
|
|
1015
1028
|
if (trigger.retryArtifact) {
|
|
1016
|
-
const retryArtifactPath = resolveHookArtifactPath(s.
|
|
1029
|
+
const retryArtifactPath = resolveHookArtifactPath(s.canonicalProjectRoot, trigger.unitId, trigger.retryArtifact);
|
|
1017
1030
|
if (existsSync(retryArtifactPath)) {
|
|
1018
1031
|
unlinkSync(retryArtifactPath);
|
|
1019
1032
|
}
|
|
@@ -1249,16 +1262,17 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1249
1262
|
if (hasPendingCaptures(s.basePath)) {
|
|
1250
1263
|
const pending = loadPendingCaptures(s.basePath);
|
|
1251
1264
|
if (pending.length > 0) {
|
|
1252
|
-
const
|
|
1265
|
+
const readRoot = s.canonicalProjectRoot;
|
|
1266
|
+
const state = await deriveState(readRoot);
|
|
1253
1267
|
const mid = state.activeMilestone?.id;
|
|
1254
1268
|
const sid = state.activeSlice?.id;
|
|
1255
1269
|
if (mid && sid) {
|
|
1256
1270
|
let currentPlan = "";
|
|
1257
1271
|
let roadmapContext = "";
|
|
1258
|
-
const planFile = resolveSliceFile(
|
|
1272
|
+
const planFile = resolveSliceFile(readRoot, mid, sid, "PLAN");
|
|
1259
1273
|
if (planFile)
|
|
1260
1274
|
currentPlan = (await loadFile(planFile)) ?? "";
|
|
1261
|
-
const roadmapFile = resolveMilestoneFile(
|
|
1275
|
+
const roadmapFile = resolveMilestoneFile(readRoot, mid, "ROADMAP");
|
|
1262
1276
|
if (roadmapFile)
|
|
1263
1277
|
roadmapContext = (await loadFile(roadmapFile)) ?? "";
|
|
1264
1278
|
const capturesList = pending.map(c => `- **${c.id}**: "${c.text}" (captured: ${c.timestamp})`).join("\n");
|
|
@@ -1306,7 +1320,7 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1306
1320
|
// exits the loop, leaving the user with no hint to /clear and /gsd again.
|
|
1307
1321
|
if (s.stepMode) {
|
|
1308
1322
|
try {
|
|
1309
|
-
const nextState = await deriveState(s.
|
|
1323
|
+
const nextState = await deriveState(s.canonicalProjectRoot);
|
|
1310
1324
|
ctx.ui.notify(buildStepCompleteMessage(nextState), "info");
|
|
1311
1325
|
}
|
|
1312
1326
|
catch (e) {
|