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
|
@@ -14,7 +14,7 @@ import type { GSDPreferences } from "./preferences.js";
|
|
|
14
14
|
import type { UatType } from "./files.js";
|
|
15
15
|
import type { MinimalModelRegistry } from "./context-budget.js";
|
|
16
16
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
17
|
-
import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted, getMilestone } from "./gsd-db.js";
|
|
17
|
+
import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted, getMilestone, insertAssessment, transaction } from "./gsd-db.js";
|
|
18
18
|
import { isClosedStatus } from "./status-guards.js";
|
|
19
19
|
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
20
20
|
|
|
@@ -77,6 +77,9 @@ import {
|
|
|
77
77
|
resolveDeepProjectSetupState,
|
|
78
78
|
type DeepProjectSetupStage,
|
|
79
79
|
} from "./deep-project-setup-policy.js";
|
|
80
|
+
import { annotateBackgroundable } from "./delegation-policy.js";
|
|
81
|
+
import { invalidateAllCaches } from "./cache.js";
|
|
82
|
+
import { insertMilestoneValidationGates } from "./milestone-validation-gates.js";
|
|
80
83
|
|
|
81
84
|
// ─── Types ────────────────────────────────────────────────────────────────
|
|
82
85
|
|
|
@@ -89,6 +92,12 @@ export type DispatchAction =
|
|
|
89
92
|
pauseAfterDispatch?: boolean;
|
|
90
93
|
/** Name of the matched dispatch rule from the unified registry (journal provenance). */
|
|
91
94
|
matchedRule?: string;
|
|
95
|
+
/**
|
|
96
|
+
* True when the matched unit type has a `good` verdict in delegation-policy.ts.
|
|
97
|
+
* Annotated in `resolveDispatch`. Consumers may use this to fork the prompt
|
|
98
|
+
* to a background sub-agent; default behavior is unchanged (synchronous).
|
|
99
|
+
*/
|
|
100
|
+
backgroundable?: boolean;
|
|
92
101
|
}
|
|
93
102
|
| { action: "stop"; reason: string; level: "info" | "warning" | "error"; matchedRule?: string }
|
|
94
103
|
| { action: "skip"; matchedRule?: string };
|
|
@@ -1196,9 +1205,12 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1196
1205
|
const skipSource = trivialVariant
|
|
1197
1206
|
? "trivial-scope pipeline variant (#4781)"
|
|
1198
1207
|
: "`skip_milestone_validation` preference";
|
|
1208
|
+
const skipValidationReason = trivialVariant ? "trivial-scope" : "preference";
|
|
1199
1209
|
const content = [
|
|
1200
1210
|
"---",
|
|
1201
1211
|
"verdict: pass",
|
|
1212
|
+
"skip_validation: true",
|
|
1213
|
+
`skip_validation_reason: ${skipValidationReason}`,
|
|
1202
1214
|
"remediation_round: 0",
|
|
1203
1215
|
"---",
|
|
1204
1216
|
"",
|
|
@@ -1207,6 +1219,45 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1207
1219
|
`Milestone validation was skipped via ${skipSource}.`,
|
|
1208
1220
|
].join("\n");
|
|
1209
1221
|
writeFileSync(validationPath, content, "utf-8");
|
|
1222
|
+
try {
|
|
1223
|
+
// DB-backed state derivation keys off assessments, not only the file
|
|
1224
|
+
// projection. Persist the skipped validation there too so the next
|
|
1225
|
+
// loop iteration advances to completing-milestone instead of
|
|
1226
|
+
// re-entering validating-milestone.
|
|
1227
|
+
if (isDbAvailable()) {
|
|
1228
|
+
transaction(() => {
|
|
1229
|
+
insertAssessment({
|
|
1230
|
+
path: validationPath,
|
|
1231
|
+
milestoneId: mid,
|
|
1232
|
+
sliceId: null,
|
|
1233
|
+
taskId: null,
|
|
1234
|
+
status: "pass",
|
|
1235
|
+
scope: "milestone-validation",
|
|
1236
|
+
fullContent: content,
|
|
1237
|
+
});
|
|
1238
|
+
const gateSliceId = getMilestoneSlices(mid)[0]?.id;
|
|
1239
|
+
if (gateSliceId) {
|
|
1240
|
+
insertMilestoneValidationGates(
|
|
1241
|
+
mid,
|
|
1242
|
+
gateSliceId,
|
|
1243
|
+
"pass",
|
|
1244
|
+
new Date().toISOString(),
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
} catch (err) {
|
|
1250
|
+
try {
|
|
1251
|
+
unlinkSync(validationPath);
|
|
1252
|
+
} catch (unlinkErr) {
|
|
1253
|
+
logWarning(
|
|
1254
|
+
"dispatch",
|
|
1255
|
+
`failed to remove skipped validation file after DB write failure for ${mid}: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`,
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
throw err;
|
|
1259
|
+
}
|
|
1260
|
+
invalidateAllCaches();
|
|
1210
1261
|
}
|
|
1211
1262
|
return { action: "skip" };
|
|
1212
1263
|
}
|
|
@@ -1291,7 +1342,9 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1291
1342
|
if (validationContent) {
|
|
1292
1343
|
// Allow completion when validation was intentionally skipped by
|
|
1293
1344
|
// preference/budget profile (#3399, #3344).
|
|
1345
|
+
const skippedByMarker = /^skip_validation:\s*true$/im.test(validationContent);
|
|
1294
1346
|
const skippedByPreference = /skip(?:ped)?[\s\-]+(?:by|per|due to)\s+(?:preference|budget|profile)/i.test(validationContent);
|
|
1347
|
+
const skippedByTrivialVariant = /trivial-scope pipeline variant/i.test(validationContent);
|
|
1295
1348
|
|
|
1296
1349
|
// Accept either the structured template format (table with MET/N/A/SATISFIED)
|
|
1297
1350
|
// or prose evidence patterns the validation agent may emit.
|
|
@@ -1300,7 +1353,12 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1300
1353
|
(validationContent.includes("MET") || validationContent.includes("N/A") || validationContent.includes("SATISFIED"));
|
|
1301
1354
|
const proseMatch =
|
|
1302
1355
|
/[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);
|
|
1303
|
-
const hasOperationalCheck =
|
|
1356
|
+
const hasOperationalCheck =
|
|
1357
|
+
skippedByMarker ||
|
|
1358
|
+
skippedByPreference ||
|
|
1359
|
+
skippedByTrivialVariant ||
|
|
1360
|
+
structuredMatch ||
|
|
1361
|
+
proseMatch;
|
|
1304
1362
|
if (!hasOperationalCheck) {
|
|
1305
1363
|
return {
|
|
1306
1364
|
action: "stop" as const,
|
|
@@ -1366,7 +1424,7 @@ export async function resolveDispatch(
|
|
|
1366
1424
|
// Delegate to registry when available
|
|
1367
1425
|
try {
|
|
1368
1426
|
const registry = getRegistry();
|
|
1369
|
-
return await registry.evaluateDispatch(ctx);
|
|
1427
|
+
return annotateBackgroundable(await registry.evaluateDispatch(ctx));
|
|
1370
1428
|
} catch (err) {
|
|
1371
1429
|
// Registry not initialized — fall back to inline loop
|
|
1372
1430
|
logWarning("dispatch", `registry dispatch failed, falling back to inline rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1376,7 +1434,7 @@ export async function resolveDispatch(
|
|
|
1376
1434
|
const result = await rule.match(ctx);
|
|
1377
1435
|
if (result) {
|
|
1378
1436
|
if (result.action !== "skip") result.matchedRule = rule.name;
|
|
1379
|
-
return result;
|
|
1437
|
+
return annotateBackgroundable(result);
|
|
1380
1438
|
}
|
|
1381
1439
|
}
|
|
1382
1440
|
|
|
@@ -1392,6 +1450,7 @@ export async function resolveDispatch(
|
|
|
1392
1450
|
};
|
|
1393
1451
|
}
|
|
1394
1452
|
|
|
1453
|
+
|
|
1395
1454
|
/** Exposed for testing — returns the rule names in evaluation order. */
|
|
1396
1455
|
export function getDispatchRuleNames(): string[] {
|
|
1397
1456
|
return DISPATCH_RULES.map((r) => r.name);
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
} from "./auto-recovery.js";
|
|
43
43
|
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
44
44
|
import { syncStateToProjectRoot } from "./auto-worktree.js";
|
|
45
|
+
import { normalizeWorktreePathForCompare } from "./worktree-root.js";
|
|
45
46
|
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
46
47
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
47
48
|
import { consumeSignal } from "./session-status-io.js";
|
|
@@ -80,6 +81,12 @@ import {
|
|
|
80
81
|
} from "./project-research-policy.js";
|
|
81
82
|
import { validateArtifact } from "./schemas/validate.js";
|
|
82
83
|
|
|
84
|
+
// ─── Path Comparison Helper ───────────────────────────────────────────────
|
|
85
|
+
/** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
|
|
86
|
+
function isSamePathLocal(a: string, b: string): boolean {
|
|
87
|
+
return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
/** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
|
|
84
91
|
const MAX_VERIFICATION_RETRIES = 3;
|
|
85
92
|
/** Keep failure toasts short while still showing concrete examples. */
|
|
@@ -617,7 +624,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
617
624
|
});
|
|
618
625
|
|
|
619
626
|
// Sync worktree state back to project root (skipped for lightweight sidecars)
|
|
620
|
-
if (!opts?.skipWorktreeSync && s.originalBasePath && s.originalBasePath
|
|
627
|
+
if (!opts?.skipWorktreeSync && s.originalBasePath && !isSamePathLocal(s.originalBasePath, s.basePath)) {
|
|
621
628
|
await runSafely("postUnit", "worktree-sync", () => {
|
|
622
629
|
syncStateToProjectRoot(s.basePath, s.originalBasePath!, s.currentMilestoneId);
|
|
623
630
|
});
|
|
@@ -761,14 +768,16 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
761
768
|
if (s.currentUnit.type === "triage-captures") {
|
|
762
769
|
try {
|
|
763
770
|
const { executeTriageResolutions } = await import("./triage-resolution.js");
|
|
764
|
-
const state = await deriveState(s.
|
|
771
|
+
const state = await deriveState(s.canonicalProjectRoot);
|
|
765
772
|
const mid = state.activeMilestone?.id ?? "";
|
|
766
773
|
const sid = state.activeSlice?.id ?? "";
|
|
767
774
|
|
|
768
775
|
// executeTriageResolutions handles defer milestone creation even
|
|
769
776
|
// without an active milestone/slice (the "all milestones complete"
|
|
770
777
|
// scenario from #1562). inject/replan/quick-task still require mid+sid.
|
|
771
|
-
|
|
778
|
+
// Phase C: write to canonical project root. copyPlanningArtifacts
|
|
779
|
+
// has been deleted, so triage writes land where readers consult.
|
|
780
|
+
const triageResult = executeTriageResolutions(s.canonicalProjectRoot, mid, sid);
|
|
772
781
|
|
|
773
782
|
if (triageResult.injected > 0) {
|
|
774
783
|
ctx.ui.notify(
|
|
@@ -933,10 +942,14 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
933
942
|
try {
|
|
934
943
|
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
935
944
|
if (mid && sid) {
|
|
936
|
-
|
|
945
|
+
// Phase C: write to the canonical project root (#5236 scope)
|
|
946
|
+
// so non-symlinked worktrees no longer maintain a separate
|
|
947
|
+
// local .gsd/ projection. copyPlanningArtifacts has been
|
|
948
|
+
// deleted; reads + writes converge at projectRoot.
|
|
949
|
+
const regenerated = await regenerateIfMissing(s.canonicalProjectRoot, mid, sid, "PLAN");
|
|
937
950
|
if (regenerated) {
|
|
938
951
|
// Re-check after regeneration
|
|
939
|
-
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.
|
|
952
|
+
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.canonicalProjectRoot);
|
|
940
953
|
if (triggerArtifactVerified) {
|
|
941
954
|
invalidateAllCaches();
|
|
942
955
|
}
|
|
@@ -1171,7 +1184,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1171
1184
|
if (mid && sid && tid) {
|
|
1172
1185
|
try {
|
|
1173
1186
|
updateTaskStatus(mid, sid, tid, "pending");
|
|
1174
|
-
await renderPlanCheckboxes(s.
|
|
1187
|
+
await renderPlanCheckboxes(s.canonicalProjectRoot, mid, sid);
|
|
1175
1188
|
} catch (dbErr) {
|
|
1176
1189
|
// DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
|
|
1177
1190
|
// Use 'gsd recover' to rebuild DB state from disk if needed.
|
|
@@ -1181,7 +1194,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1181
1194
|
|
|
1182
1195
|
// 2. Delete SUMMARY.md for the task
|
|
1183
1196
|
if (mid && sid && tid) {
|
|
1184
|
-
|
|
1197
|
+
// Phase C: read+delete via canonical project root.
|
|
1198
|
+
const tasksDir = resolveTasksDir(s.canonicalProjectRoot, mid, sid);
|
|
1185
1199
|
if (tasksDir) {
|
|
1186
1200
|
const summaryFile = join(tasksDir, buildTaskFileName(tid, "SUMMARY"));
|
|
1187
1201
|
if (existsSync(summaryFile)) {
|
|
@@ -1192,7 +1206,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1192
1206
|
|
|
1193
1207
|
// 3. Delete the retry_on artifact (e.g. NEEDS-REWORK.md)
|
|
1194
1208
|
if (trigger.retryArtifact) {
|
|
1195
|
-
const retryArtifactPath = resolveHookArtifactPath(s.
|
|
1209
|
+
const retryArtifactPath = resolveHookArtifactPath(s.canonicalProjectRoot, trigger.unitId, trigger.retryArtifact);
|
|
1196
1210
|
if (existsSync(retryArtifactPath)) {
|
|
1197
1211
|
unlinkSync(retryArtifactPath);
|
|
1198
1212
|
}
|
|
@@ -1470,16 +1484,17 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1470
1484
|
if (hasPendingCaptures(s.basePath)) {
|
|
1471
1485
|
const pending = loadPendingCaptures(s.basePath);
|
|
1472
1486
|
if (pending.length > 0) {
|
|
1473
|
-
const
|
|
1487
|
+
const readRoot = s.canonicalProjectRoot;
|
|
1488
|
+
const state = await deriveState(readRoot);
|
|
1474
1489
|
const mid = state.activeMilestone?.id;
|
|
1475
1490
|
const sid = state.activeSlice?.id;
|
|
1476
1491
|
|
|
1477
1492
|
if (mid && sid) {
|
|
1478
1493
|
let currentPlan = "";
|
|
1479
1494
|
let roadmapContext = "";
|
|
1480
|
-
const planFile = resolveSliceFile(
|
|
1495
|
+
const planFile = resolveSliceFile(readRoot, mid, sid, "PLAN");
|
|
1481
1496
|
if (planFile) currentPlan = (await loadFile(planFile)) ?? "";
|
|
1482
|
-
const roadmapFile = resolveMilestoneFile(
|
|
1497
|
+
const roadmapFile = resolveMilestoneFile(readRoot, mid, "ROADMAP");
|
|
1483
1498
|
if (roadmapFile) roadmapContext = (await loadFile(roadmapFile)) ?? "";
|
|
1484
1499
|
|
|
1485
1500
|
const capturesList = pending.map(c =>
|
|
@@ -1547,7 +1562,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
1547
1562
|
// exits the loop, leaving the user with no hint to /clear and /gsd again.
|
|
1548
1563
|
if (s.stepMode) {
|
|
1549
1564
|
try {
|
|
1550
|
-
const nextState = await deriveState(s.
|
|
1565
|
+
const nextState = await deriveState(s.canonicalProjectRoot);
|
|
1551
1566
|
ctx.ui.notify(buildStepCompleteMessage(nextState), "info");
|
|
1552
1567
|
} catch (e) {
|
|
1553
1568
|
debugLog("postUnit", { phase: "step-wizard-notify", error: String(e) });
|