gsd-pi 2.78.1-dev.b0759e59b → 2.78.1-dev.d8826a445
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 +8 -5
- package/dist/headless-recover.d.ts +23 -0
- package/dist/headless-recover.js +93 -0
- package/dist/headless.js +9 -0
- package/dist/help-text.js +1 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +8 -1
- package/dist/resources/extensions/gsd/auto/phases.js +7 -2
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +7 -58
- package/dist/resources/extensions/gsd/auto-post-unit.js +14 -28
- package/dist/resources/extensions/gsd/auto-start.js +1 -8
- package/dist/resources/extensions/gsd/auto-worktree.js +244 -216
- package/dist/resources/extensions/gsd/auto.js +86 -7
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +9 -77
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -16
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -55
- package/dist/resources/extensions/gsd/commands-codebase.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +5 -5
- package/dist/resources/extensions/gsd/commands-logs.js +2 -2
- package/dist/resources/extensions/gsd/commands-scan.js +2 -2
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +5 -5
- package/dist/resources/extensions/gsd/db-writer.js +106 -95
- package/dist/resources/extensions/gsd/delegation-policy.js +155 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +6 -10
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +2 -2
- package/dist/resources/extensions/gsd/gsd-db.js +268 -8
- package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +141 -32
- package/dist/resources/extensions/gsd/markdown-renderer.js +14 -51
- package/dist/resources/extensions/gsd/metrics.js +287 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +5 -2
- package/dist/resources/extensions/gsd/paths.js +114 -9
- 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/prompts/plan-milestone.md +6 -0
- package/dist/resources/extensions/gsd/queue-order.js +6 -1
- package/dist/resources/extensions/gsd/rethink.js +2 -2
- package/dist/resources/extensions/gsd/state.js +91 -372
- package/dist/resources/extensions/gsd/templates/project.md +10 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -5
- package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -12
- package/dist/resources/extensions/gsd/tools/complete-task.js +19 -31
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -5
- package/dist/resources/extensions/gsd/workflow-manifest.js +2 -1
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -21
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/workflow-reconcile.js +3 -3
- package/dist/resources/extensions/gsd/workspace.js +59 -0
- package/dist/resources/extensions/gsd/worktree-command.js +4 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +15 -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 +12 -12
- 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/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +12 -12
- package/dist/web/standalone/.next/server/chunks/6336.js +1 -0
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- 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.d.ts +6 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +56 -2
- 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/parse-workflow-args.test.ts +80 -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 +62 -3
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +13 -2
- package/src/resources/extensions/gsd/auto/phases.ts +8 -2
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +14 -62
- package/src/resources/extensions/gsd/auto-post-unit.ts +15 -27
- package/src/resources/extensions/gsd/auto-start.ts +1 -8
- package/src/resources/extensions/gsd/auto-worktree.ts +286 -251
- package/src/resources/extensions/gsd/auto.ts +102 -7
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +9 -84
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -17
- 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/commands-codebase.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +5 -5
- package/src/resources/extensions/gsd/commands-logs.ts +2 -2
- package/src/resources/extensions/gsd/commands-scan.ts +2 -2
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +5 -5
- package/src/resources/extensions/gsd/db-writer.ts +123 -94
- package/src/resources/extensions/gsd/delegation-policy.ts +197 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +6 -11
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +2 -2
- package/src/resources/extensions/gsd/gsd-db.ts +269 -8
- package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +181 -32
- package/src/resources/extensions/gsd/markdown-renderer.ts +13 -64
- package/src/resources/extensions/gsd/metrics.ts +321 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +14 -13
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +5 -2
- package/src/resources/extensions/gsd/paths.ts +122 -9
- 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/prompts/plan-milestone.md +6 -0
- package/src/resources/extensions/gsd/queue-order.ts +6 -1
- package/src/resources/extensions/gsd/rethink.ts +2 -2
- package/src/resources/extensions/gsd/state.ts +91 -389
- package/src/resources/extensions/gsd/templates/project.md +10 -0
- package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +14 -14
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +21 -34
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +331 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +6 -7
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +12 -27
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +18 -5
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
- 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/db-writer.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/delegation-policy.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +10 -38
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +136 -56
- package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +119 -61
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/dispatch-backgroundable-annotation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +6 -20
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +14 -15
- package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +3 -23
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +11 -16
- package/src/resources/extensions/gsd/tests/escalation.test.ts +2 -1
- 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-db.test.ts +2 -1
- 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/gsdroot-worktree-detection.test.ts +15 -36
- package/src/resources/extensions/gsd/tests/guided-flow-prompt-consolidation.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/handler-worktree-write-isolation.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +15 -15
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +15 -5
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +371 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +14 -8
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +3 -2
- 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/originalbase-path-comparison.test.ts +329 -0
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +2 -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/pending-autostart-scope.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +25 -16
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +150 -7
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +184 -0
- package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +28 -16
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/resolve-ts.mjs +4 -0
- package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +10 -56
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +15 -16
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +23 -27
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +13 -14
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +10 -33
- 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 +102 -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/validate-milestone-write-order.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +239 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +12 -7
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +26 -3
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/workspace.test.ts +190 -0
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +65 -71
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +26 -151
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +35 -35
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -52
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +1 -1
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -5
- package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -14
- package/src/resources/extensions/gsd/tools/complete-task.ts +19 -34
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +7 -5
- package/src/resources/extensions/gsd/workflow-manifest.ts +4 -1
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -18
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workspace.ts +95 -0
- package/src/resources/extensions/gsd/worktree-command.ts +4 -3
- package/src/resources/extensions/gsd/worktree-resolver.ts +16 -2
- package/src/resources/extensions/gsd/write-intercept.ts +3 -3
- package/dist/web/standalone/.next/server/chunks/8527.js +0 -1
- /package/dist/web/standalone/.next/static/{rk1EN3FQTE6Z1yalkW_GE → AT5qi39nKXkdmQIOIoh0f}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{rk1EN3FQTE6Z1yalkW_GE → AT5qi39nKXkdmQIOIoh0f}/_ssgManifest.js +0 -0
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GSD2 — regression
|
|
3
|
-
* GSD home (~/.gsd) as a project .gsd directory when basePath resolves to
|
|
4
|
-
* $HOME. Paths under ~/.gsd/projects/<hash>/ remain valid.
|
|
2
|
+
* GSD2 — regression tests for #5187 and git-root anchor guard:
|
|
5
3
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* #5187: gsdRoot() must refuse to use the global GSD home (~/.gsd) as a
|
|
5
|
+
* project .gsd directory when basePath resolves to $HOME. Paths under
|
|
6
|
+
* ~/.gsd/projects/<hash>/ remain valid.
|
|
7
|
+
*
|
|
8
|
+
* git-root anchor guard: when $HOME is itself a git repo and ~/.gsd exists,
|
|
9
|
+
* gsdRoot() must NOT return ~/.gsd for a subdir basePath like ~/projects/foo.
|
|
10
|
+
* It should fall through to step 4 (creation fallback) instead.
|
|
8
11
|
*/
|
|
9
12
|
|
|
10
13
|
import { describe, test, beforeEach, afterEach } from 'node:test';
|
|
@@ -12,6 +15,7 @@ import assert from 'node:assert/strict';
|
|
|
12
15
|
import { mkdtempSync, mkdirSync, rmSync, realpathSync } from 'node:fs';
|
|
13
16
|
import { tmpdir } from 'node:os';
|
|
14
17
|
import { join } from 'node:path';
|
|
18
|
+
import { spawnSync } from 'node:child_process';
|
|
15
19
|
|
|
16
20
|
import { gsdRoot, _clearGsdRootCache } from '../paths.ts';
|
|
17
21
|
|
|
@@ -84,3 +88,62 @@ describe('gsdRoot() refuses ~/.gsd as project state when basePath is $HOME (#518
|
|
|
84
88
|
}
|
|
85
89
|
});
|
|
86
90
|
});
|
|
91
|
+
|
|
92
|
+
describe('git-root anchor guard: subdir basePath must not resolve to ~/.gsd', () => {
|
|
93
|
+
let fakeHome: string;
|
|
94
|
+
let subDir: string;
|
|
95
|
+
let savedHome: string | undefined;
|
|
96
|
+
let savedUserProfile: string | undefined;
|
|
97
|
+
let savedGsdHome: string | undefined;
|
|
98
|
+
|
|
99
|
+
beforeEach(() => {
|
|
100
|
+
// Create a tmpdir that will act as both $HOME and a git repo root.
|
|
101
|
+
fakeHome = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-anchor-guard-')));
|
|
102
|
+
// Init a bare-minimum git repo so git rev-parse --show-toplevel returns fakeHome.
|
|
103
|
+
spawnSync('git', ['init', fakeHome], { encoding: 'utf-8' });
|
|
104
|
+
// Create ~/.gsd (the global home that must NOT be used for project subdirs).
|
|
105
|
+
mkdirSync(join(fakeHome, '.gsd'), { recursive: true });
|
|
106
|
+
// Create a subdir inside the git repo — this is the project basePath.
|
|
107
|
+
subDir = join(fakeHome, 'projects', 'foo');
|
|
108
|
+
mkdirSync(subDir, { recursive: true });
|
|
109
|
+
|
|
110
|
+
savedHome = process.env.HOME;
|
|
111
|
+
savedUserProfile = process.env.USERPROFILE;
|
|
112
|
+
savedGsdHome = process.env.GSD_HOME;
|
|
113
|
+
|
|
114
|
+
process.env.HOME = fakeHome;
|
|
115
|
+
process.env.USERPROFILE = fakeHome;
|
|
116
|
+
delete process.env.GSD_HOME;
|
|
117
|
+
|
|
118
|
+
_clearGsdRootCache();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
afterEach(() => {
|
|
122
|
+
if (savedHome === undefined) delete process.env.HOME;
|
|
123
|
+
else process.env.HOME = savedHome;
|
|
124
|
+
if (savedUserProfile === undefined) delete process.env.USERPROFILE;
|
|
125
|
+
else process.env.USERPROFILE = savedUserProfile;
|
|
126
|
+
if (savedGsdHome === undefined) delete process.env.GSD_HOME;
|
|
127
|
+
else process.env.GSD_HOME = savedGsdHome;
|
|
128
|
+
|
|
129
|
+
_clearGsdRootCache();
|
|
130
|
+
rmSync(fakeHome, { recursive: true, force: true });
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('does NOT return ~/.gsd when $HOME is a git repo and basePath is a subdir', () => {
|
|
134
|
+
// fakeHome IS the git root AND $HOME, so git rev-parse returns fakeHome,
|
|
135
|
+
// and ~/.gsd (fakeHome/.gsd) exists. The guard must skip that candidate
|
|
136
|
+
// and fall through to the creation fallback: subDir/.gsd.
|
|
137
|
+
const result = gsdRoot(subDir);
|
|
138
|
+
assert.notEqual(
|
|
139
|
+
result,
|
|
140
|
+
join(fakeHome, '.gsd'),
|
|
141
|
+
'gsdRoot must not return ~/.gsd for a subdir basePath',
|
|
142
|
+
);
|
|
143
|
+
assert.equal(
|
|
144
|
+
result,
|
|
145
|
+
join(subDir, '.gsd'),
|
|
146
|
+
'gsdRoot should fall through to the creation fallback for a subdir',
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* gsdroot-worktree-detection.test.ts — Regression test for #2594.
|
|
3
3
|
*
|
|
4
|
-
* gsdRoot() must return the
|
|
5
|
-
* is inside a .gsd/worktrees/<name>/ structure
|
|
6
|
-
*
|
|
4
|
+
* gsdRoot() must return the canonical project .gsd directory when basePath
|
|
5
|
+
* is inside a .gsd/worktrees/<name>/ structure. Worktree-local .gsd folders
|
|
6
|
+
* are legacy projection roots only; runtime state is DB-authoritative at the
|
|
7
|
+
* project .gsd.
|
|
7
8
|
*
|
|
8
9
|
* The bug: when a git worktree lives at /project/.gsd/worktrees/M008/,
|
|
9
10
|
* probeGsdRoot() runs `git rev-parse --show-toplevel` which can return the
|
|
@@ -20,7 +21,7 @@ import { mkdtempSync, realpathSync } from "node:fs";
|
|
|
20
21
|
import { tmpdir } from "node:os";
|
|
21
22
|
import { spawnSync } from "node:child_process";
|
|
22
23
|
|
|
23
|
-
import { gsdRoot, _clearGsdRootCache } from "../paths.ts";
|
|
24
|
+
import { gsdRoot, resolveGsdPathContract, _clearGsdRootCache } from "../paths.ts";
|
|
24
25
|
|
|
25
26
|
describe("gsdRoot() worktree detection (#2594)", () => {
|
|
26
27
|
let projectRoot: string;
|
|
@@ -61,7 +62,7 @@ describe("gsdRoot() worktree detection (#2594)", () => {
|
|
|
61
62
|
rmSync(projectRoot, { recursive: true, force: true });
|
|
62
63
|
});
|
|
63
64
|
|
|
64
|
-
test("returns
|
|
65
|
+
test("returns project .gsd when basePath is a worktree with its own .gsd", () => {
|
|
65
66
|
// Simulates a worktree that already had copyPlanningArtifacts() run,
|
|
66
67
|
// so it has its own .gsd/ directory.
|
|
67
68
|
const worktreeBase = join(projectGsd, "worktrees", "M008");
|
|
@@ -71,41 +72,26 @@ describe("gsdRoot() worktree detection (#2594)", () => {
|
|
|
71
72
|
const result = gsdRoot(worktreeBase);
|
|
72
73
|
assert.equal(
|
|
73
74
|
result,
|
|
74
|
-
|
|
75
|
-
`Expected
|
|
76
|
-
"gsdRoot() should use the fast path for an existing worktree .gsd.",
|
|
75
|
+
projectGsd,
|
|
76
|
+
`Expected canonical project .gsd (${projectGsd}), got ${result}.`,
|
|
77
77
|
);
|
|
78
|
+
assert.equal(resolveGsdPathContract(worktreeBase).worktreeGsd, worktreeGsd);
|
|
78
79
|
});
|
|
79
80
|
|
|
80
|
-
test("returns
|
|
81
|
-
// This is the core #2594 bug: the worktree directory exists but its .gsd
|
|
82
|
-
// subdirectory hasn't been created yet. Without the fix, probeGsdRoot()
|
|
83
|
-
// walks up from the worktree path, finds /project/.gsd, and returns it.
|
|
84
|
-
// With the fix, it detects the .gsd/worktrees/<name>/ pattern and returns
|
|
85
|
-
// the worktree-local .gsd path as the creation fallback.
|
|
81
|
+
test("returns project .gsd when worktree .gsd does not exist yet", () => {
|
|
86
82
|
const worktreeBase = join(projectGsd, "worktrees", "M008");
|
|
87
83
|
mkdirSync(worktreeBase, { recursive: true });
|
|
88
84
|
// NOTE: no .gsd/ inside worktreeBase
|
|
89
85
|
|
|
90
86
|
const result = gsdRoot(worktreeBase);
|
|
91
|
-
const expected = join(worktreeBase, ".gsd");
|
|
92
|
-
|
|
93
|
-
// Without the fix, this returns projectGsd (/project/.gsd) because the
|
|
94
|
-
// walk-up from worktreeBase finds it. With the fix, it returns the
|
|
95
|
-
// worktree-local path.
|
|
96
|
-
assert.notEqual(
|
|
97
|
-
result,
|
|
98
|
-
projectGsd,
|
|
99
|
-
"gsdRoot() must NOT return the project root .gsd when basePath is inside .gsd/worktrees/",
|
|
100
|
-
);
|
|
101
87
|
assert.equal(
|
|
102
88
|
result,
|
|
103
|
-
|
|
104
|
-
`Expected
|
|
89
|
+
projectGsd,
|
|
90
|
+
`Expected canonical project .gsd (${projectGsd}), got ${result}.`,
|
|
105
91
|
);
|
|
106
92
|
});
|
|
107
93
|
|
|
108
|
-
test("returns
|
|
94
|
+
test("returns project .gsd when basePath is a real git worktree inside .gsd/worktrees/", () => {
|
|
109
95
|
// Create a real git worktree at .gsd/worktrees/M010
|
|
110
96
|
const worktreeName = "M010";
|
|
111
97
|
const worktreeBase = join(projectGsd, "worktrees", worktreeName);
|
|
@@ -125,17 +111,10 @@ describe("gsdRoot() worktree detection (#2594)", () => {
|
|
|
125
111
|
|
|
126
112
|
// The real git worktree exists at worktreeBase but has NO .gsd/ subdir yet
|
|
127
113
|
const gsdResult = gsdRoot(worktreeBase);
|
|
128
|
-
const expected = join(worktreeBase, ".gsd");
|
|
129
|
-
|
|
130
|
-
assert.notEqual(
|
|
131
|
-
gsdResult,
|
|
132
|
-
projectGsd,
|
|
133
|
-
"gsdRoot() must NOT escape to project root .gsd from inside a git worktree",
|
|
134
|
-
);
|
|
135
114
|
assert.equal(
|
|
136
115
|
gsdResult,
|
|
137
|
-
|
|
138
|
-
`Expected
|
|
116
|
+
projectGsd,
|
|
117
|
+
`Expected canonical project .gsd (${projectGsd}), got ${gsdResult}`,
|
|
139
118
|
);
|
|
140
119
|
|
|
141
120
|
// Cleanup worktree
|
|
@@ -86,8 +86,8 @@ describe("guided-flow → auto-prompts consolidation (#5183)", () => {
|
|
|
86
86
|
assert.ok(prompt.includes(TID), "must mention task id");
|
|
87
87
|
assert.ok(prompt.includes(T_TITLE), "must mention task title");
|
|
88
88
|
assert.ok(
|
|
89
|
-
prompt.includes("
|
|
90
|
-
"must instruct calling the canonical
|
|
89
|
+
prompt.includes("gsd_task_complete"),
|
|
90
|
+
"must instruct calling the canonical gsd_task_complete tool",
|
|
91
91
|
);
|
|
92
92
|
assert.ok(
|
|
93
93
|
prompt.includes(base),
|
|
@@ -110,8 +110,8 @@ describe("guided-flow → auto-prompts consolidation (#5183)", () => {
|
|
|
110
110
|
assert.ok(prompt.includes(SID), "must mention slice id");
|
|
111
111
|
assert.ok(prompt.includes(S_TITLE), "must mention slice title");
|
|
112
112
|
assert.ok(
|
|
113
|
-
prompt.includes("
|
|
114
|
-
"must instruct calling
|
|
113
|
+
prompt.includes("gsd_slice_complete"),
|
|
114
|
+
"must instruct calling gsd_slice_complete (was in guided-complete-slice.md)",
|
|
115
115
|
);
|
|
116
116
|
assert.ok(
|
|
117
117
|
prompt.includes(base),
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression: when /gsd handlers run with cwd inside a worktree, writes must
|
|
3
|
+
* land in the worktree's .gsd/, not the parent project's .gsd/.
|
|
4
|
+
*
|
|
5
|
+
* The fix in 01464a97 replaced `process.cwd()` with `projectRoot()` to block
|
|
6
|
+
* $HOME pollution, but `projectRoot()` walks UP from a worktree path to the
|
|
7
|
+
* outer project root — breaking the worktree isolation invariant agents rely
|
|
8
|
+
* on. The corrected pattern: handlers use `currentDirectoryRoot()`, which
|
|
9
|
+
* preserves the active cwd (worktree or project) and still throws when cwd
|
|
10
|
+
* is $HOME.
|
|
11
|
+
*/
|
|
12
|
+
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
13
|
+
import assert from "node:assert/strict";
|
|
14
|
+
import { mkdtempSync, mkdirSync, rmSync, realpathSync } from "node:fs";
|
|
15
|
+
import { tmpdir, homedir } from "node:os";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
|
|
18
|
+
import { currentDirectoryRoot, projectRoot, withCommandCwd, GSDNoProjectError } from "../commands/context.ts";
|
|
19
|
+
|
|
20
|
+
describe("handlers preserve worktree cwd via currentDirectoryRoot()", () => {
|
|
21
|
+
let project: string;
|
|
22
|
+
let worktree: string;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
project = realpathSync(mkdtempSync(join(tmpdir(), "gsd-wt-iso-")));
|
|
26
|
+
mkdirSync(join(project, ".gsd"), { recursive: true });
|
|
27
|
+
mkdirSync(join(project, ".git"), { recursive: true });
|
|
28
|
+
worktree = join(project, ".gsd", "worktrees", "M001");
|
|
29
|
+
mkdirSync(join(worktree, ".gsd"), { recursive: true });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
rmSync(project, { recursive: true, force: true });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("currentDirectoryRoot() returns the worktree path when cwd is the worktree", async () => {
|
|
37
|
+
const resolved = await withCommandCwd(worktree, async () => currentDirectoryRoot());
|
|
38
|
+
assert.equal(resolved, worktree, "must keep worktree path so writes isolate");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("projectRoot() walks UP from worktree to the project root (legacy semantics)", async () => {
|
|
42
|
+
const resolved = await withCommandCwd(worktree, async () => projectRoot());
|
|
43
|
+
assert.equal(resolved, project, "projectRoot intentionally returns project, not worktree");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("currentDirectoryRoot() throws GSDNoProjectError when cwd is $HOME", async () => {
|
|
47
|
+
await assert.rejects(
|
|
48
|
+
withCommandCwd(homedir(), async () => currentDirectoryRoot()),
|
|
49
|
+
(err: unknown) => err instanceof GSDNoProjectError,
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("currentDirectoryRoot() returns project root when cwd is project root", async () => {
|
|
54
|
+
const resolved = await withCommandCwd(project, async () => currentDirectoryRoot());
|
|
55
|
+
assert.equal(resolved, project);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -473,26 +473,26 @@ test("mergeAllCompleted — by-completion order respects startedAt", async () =>
|
|
|
473
473
|
});
|
|
474
474
|
|
|
475
475
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
476
|
-
// Bug #2812 — determineMergeOrder should use
|
|
476
|
+
// Bug #2812 — determineMergeOrder should use DB state as source of truth
|
|
477
477
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
478
478
|
|
|
479
|
-
/** Set up
|
|
480
|
-
function
|
|
481
|
-
|
|
482
|
-
mkdirSync(
|
|
483
|
-
const dbPath = join(
|
|
479
|
+
/** Set up canonical DB with a milestone marked complete and a worktree marker dir */
|
|
480
|
+
function setupCanonicalDbWithWorktree(basePath: string, mid: string): void {
|
|
481
|
+
mkdirSync(join(basePath, ".gsd", "worktrees", mid), { recursive: true });
|
|
482
|
+
mkdirSync(join(basePath, ".gsd"), { recursive: true });
|
|
483
|
+
const dbPath = join(basePath, ".gsd", "gsd.db");
|
|
484
484
|
openDatabase(dbPath);
|
|
485
485
|
insertMilestone({ id: mid, title: `Milestone ${mid}`, status: "complete" });
|
|
486
486
|
updateMilestoneStatus(mid, "complete", new Date().toISOString());
|
|
487
487
|
closeDatabase();
|
|
488
488
|
}
|
|
489
489
|
|
|
490
|
-
test("determineMergeOrder — finds milestones completed in
|
|
490
|
+
test("determineMergeOrder — finds milestones completed in canonical DB even when worker state is 'error' (#2812)", () => {
|
|
491
491
|
const base = realpathSync(mkdtempSync(join(tmpdir(), "merge-db-bug-")));
|
|
492
492
|
try {
|
|
493
493
|
// Simulate the bug scenario: orchestrator has stale "error" state
|
|
494
|
-
// but the
|
|
495
|
-
|
|
494
|
+
// but the canonical DB shows milestone is actually complete.
|
|
495
|
+
setupCanonicalDbWithWorktree(base, "M011");
|
|
496
496
|
|
|
497
497
|
const workers = [
|
|
498
498
|
makeWorker({ milestoneId: "M010", state: "error" }),
|
|
@@ -502,12 +502,12 @@ test("determineMergeOrder — finds milestones completed in worktree DB even whe
|
|
|
502
502
|
|
|
503
503
|
const order = determineMergeOrder(workers, "sequential", base);
|
|
504
504
|
|
|
505
|
-
// M011 should be included because
|
|
505
|
+
// M011 should be included because the canonical DB says status='complete'
|
|
506
506
|
assert.ok(
|
|
507
507
|
order.includes("M011"),
|
|
508
|
-
`Expected M011 in merge order (
|
|
508
|
+
`Expected M011 in merge order (canonical DB says complete), got: [${order}]`,
|
|
509
509
|
);
|
|
510
|
-
// M010 and M012 should NOT be included (no
|
|
510
|
+
// M010 and M012 should NOT be included (no canonical complete status)
|
|
511
511
|
assert.ok(!order.includes("M010"), "M010 should not be in merge order (error, no DB)");
|
|
512
512
|
assert.ok(!order.includes("M012"), "M012 should not be in merge order (running, no DB)");
|
|
513
513
|
} finally {
|
|
@@ -529,7 +529,7 @@ test("determineMergeOrder — combines stopped workers and DB-complete milestone
|
|
|
529
529
|
const base = realpathSync(mkdtempSync(join(tmpdir(), "merge-dedup-")));
|
|
530
530
|
try {
|
|
531
531
|
// M001 is stopped in orchestrator AND complete in worktree DB
|
|
532
|
-
|
|
532
|
+
setupCanonicalDbWithWorktree(base, "M001");
|
|
533
533
|
|
|
534
534
|
const workers = [
|
|
535
535
|
makeWorker({ milestoneId: "M001", state: "stopped" }),
|
|
@@ -555,8 +555,8 @@ test("mergeAllCompleted — discovers DB-complete milestones when workers show e
|
|
|
555
555
|
]);
|
|
556
556
|
setupRoadmap(repo, "M011", "Feature System", ["S01: Feature module"]);
|
|
557
557
|
|
|
558
|
-
// Set up
|
|
559
|
-
|
|
558
|
+
// Set up canonical DB showing M011 is complete
|
|
559
|
+
setupCanonicalDbWithWorktree(repo, "M011");
|
|
560
560
|
|
|
561
561
|
// Orchestrator thinks M011 is in error (stale state)
|
|
562
562
|
const workers = [
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
updateTaskStatus,
|
|
47
47
|
updateSliceStatus,
|
|
48
48
|
updateMilestoneStatus,
|
|
49
|
+
insertAssessment,
|
|
49
50
|
insertReplanHistory,
|
|
50
51
|
getReplanHistory,
|
|
51
52
|
insertGateRow,
|
|
@@ -363,13 +364,13 @@ describe("state derivation failures", () => {
|
|
|
363
364
|
const state2 = await deriveState(base);
|
|
364
365
|
assert.equal(state2.phase, "executing", "cached result should still show executing");
|
|
365
366
|
|
|
366
|
-
// After explicit invalidation,
|
|
367
|
-
//
|
|
367
|
+
// After explicit invalidation, DB rows remain authoritative; PLAN.md is a
|
|
368
|
+
// projection and must not import missing task rows.
|
|
368
369
|
invalidateStateCache();
|
|
369
370
|
const state3 = await deriveState(base);
|
|
370
|
-
assert.equal(state3.phase, "
|
|
371
|
-
assert.equal(state3.activeTask
|
|
372
|
-
assert.deepEqual(state3.progress?.tasks, { done: 1, total:
|
|
371
|
+
assert.equal(state3.phase, "summarizing", "after cache invalidation should follow DB tasks only");
|
|
372
|
+
assert.equal(state3.activeTask, null, "disk-only plan task T02 should not be imported");
|
|
373
|
+
assert.deepEqual(state3.progress?.tasks, { done: 1, total: 1 });
|
|
373
374
|
});
|
|
374
375
|
|
|
375
376
|
test("corrupt ROADMAP: binary content does not crash deriveState", async () => {
|
|
@@ -486,12 +487,14 @@ describe("transition boundary failures", () => {
|
|
|
486
487
|
writeFileSync(join(mDir, "M001-CONTEXT-DRAFT.md"), "# Draft\nSome draft.\n");
|
|
487
488
|
|
|
488
489
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
490
|
+
insertMilestone({ id: "M001", title: "Draft", status: "needs-discussion" });
|
|
489
491
|
invalidateAllCaches();
|
|
490
492
|
const state1 = await deriveState(base);
|
|
491
493
|
assert.equal(state1.phase, "needs-discussion");
|
|
492
494
|
|
|
493
495
|
// Now write the full CONTEXT (simulates discussion completion)
|
|
494
496
|
writeFileSync(join(mDir, "M001-CONTEXT.md"), "# M001: Resolved\n\n## Purpose\nDone.\n");
|
|
497
|
+
updateMilestoneStatus("M001", "active");
|
|
495
498
|
|
|
496
499
|
invalidateAllCaches();
|
|
497
500
|
const state2 = await deriveState(base);
|
|
@@ -1148,6 +1151,13 @@ describe("completion and verification failures", () => {
|
|
|
1148
1151
|
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "complete" });
|
|
1149
1152
|
insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", status: "complete" });
|
|
1150
1153
|
insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", status: "complete" });
|
|
1154
|
+
insertAssessment({
|
|
1155
|
+
path: "milestones/M001/M001-VALIDATION.md",
|
|
1156
|
+
milestoneId: "M001",
|
|
1157
|
+
status: "pass",
|
|
1158
|
+
scope: "milestone-validation",
|
|
1159
|
+
fullContent: "verdict: pass",
|
|
1160
|
+
});
|
|
1151
1161
|
|
|
1152
1162
|
invalidateAllCaches();
|
|
1153
1163
|
const state = await deriveStateFromDb(base);
|