@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.75048e7
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/dist/cli.js +3 -2
- package/dist/help-text.js +10 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
- package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
- package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/dist/resources/extensions/browser-tools/index.js +57 -9
- package/dist/resources/extensions/browser-tools/package.json +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
- package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
- package/dist/resources/extensions/gsd/auto/phases.js +4 -3
- package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
- package/dist/resources/extensions/gsd/auto-dispatch.js +55 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +72 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +7 -8
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +94 -15
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +18 -65
- package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
- package/dist/resources/extensions/gsd/auto.js +31 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -4
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +56 -20
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +33 -38
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
- package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
- package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
- package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
- package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +2 -1
- package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
- package/dist/resources/extensions/gsd/error-classifier.js +2 -1
- package/dist/resources/extensions/gsd/escalation.js +4 -4
- package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
- package/dist/resources/extensions/gsd/forensics.js +74 -2
- package/dist/resources/extensions/gsd/gsd-db.js +42 -6
- package/dist/resources/extensions/gsd/guided-flow.js +119 -176
- package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
- package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
- package/dist/resources/extensions/gsd/memory-store.js +4 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
- package/dist/resources/extensions/gsd/milestone-closeout.js +3 -1
- package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
- package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +33 -23
- package/dist/resources/extensions/gsd/prompts/system.md +3 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/dist/resources/extensions/gsd/recovery-classification.js +20 -0
- package/dist/resources/extensions/gsd/rule-registry.js +428 -52
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
- package/dist/resources/extensions/gsd/skill-activation.js +20 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
- package/dist/resources/extensions/gsd/state.js +17 -14
- package/dist/resources/extensions/gsd/templates/plan.md +3 -1
- package/dist/resources/extensions/gsd/tool-contract.js +5 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +143 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
- package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +483 -6
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
- package/dist/resources/extensions/gsd/verification-gate.js +72 -1
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -73
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
- package/dist/resources/extensions/mcp-client/manager.js +31 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
- package/dist/rtk.d.ts +7 -1
- package/dist/rtk.js +27 -11
- package/dist/update-check.d.ts +15 -1
- package/dist/update-check.js +87 -12
- package/dist/update-cmd.d.ts +1 -0
- package/dist/update-cmd.js +53 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
- 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/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/update/route.js +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 +5 -5
- package/dist/web/standalone/.next/server/chunks/8357.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/package.json +5 -3
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +32 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/index.d.ts +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +1 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
- package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
- package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
- package/packages/gsd-agent-core/package.json +6 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +23 -9
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +84 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +42 -3
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +6 -1
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/api-registry.d.ts +2 -0
- package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/packages/pi-ai/dist/api-registry.js +23 -0
- package/packages/pi-ai/dist/api-registry.js.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +15 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +411 -39
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +504 -153
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/stream.js +6 -6
- package/packages/pi-ai/dist/stream.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +2 -2
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/terminal.d.ts +1 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +8 -4
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
- package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
- package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/src/resources/extensions/browser-tools/index.ts +60 -9
- package/src/resources/extensions/browser-tools/package.json +5 -1
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
- package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
- package/src/resources/extensions/gsd/auto/phases.ts +5 -3
- package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
- package/src/resources/extensions/gsd/auto-dispatch.ts +67 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
- package/src/resources/extensions/gsd/auto-prompts.ts +106 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +7 -7
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
- package/src/resources/extensions/gsd/auto-start.ts +112 -17
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +43 -73
- package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
- package/src/resources/extensions/gsd/auto.ts +47 -5
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +96 -4
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +81 -25
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +70 -63
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
- package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
- package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
- package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
- package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +3 -1
- package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
- package/src/resources/extensions/gsd/error-classifier.ts +2 -1
- package/src/resources/extensions/gsd/escalation.ts +4 -4
- package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
- package/src/resources/extensions/gsd/forensics.ts +99 -5
- package/src/resources/extensions/gsd/gsd-db.ts +46 -8
- package/src/resources/extensions/gsd/guided-flow.ts +215 -217
- package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
- package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
- package/src/resources/extensions/gsd/memory-store.ts +4 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
- package/src/resources/extensions/gsd/milestone-closeout.ts +3 -1
- package/src/resources/extensions/gsd/pending-auto-start.ts +0 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +33 -23
- package/src/resources/extensions/gsd/prompts/system.md +3 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/src/resources/extensions/gsd/recovery-classification.ts +20 -0
- package/src/resources/extensions/gsd/rule-registry.ts +558 -58
- package/src/resources/extensions/gsd/rule-types.ts +2 -0
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
- package/src/resources/extensions/gsd/skill-activation.ts +20 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
- package/src/resources/extensions/gsd/state.ts +18 -14
- package/src/resources/extensions/gsd/templates/plan.md +3 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
- package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +31 -79
- package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -10
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +83 -1
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +493 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
- package/src/resources/extensions/gsd/tool-contract.ts +6 -0
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +223 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +589 -8
- package/src/resources/extensions/gsd/types.ts +69 -5
- package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +186 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
- package/src/resources/extensions/gsd/verification-gate.ts +87 -1
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -73
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
- package/src/resources/extensions/mcp-client/manager.ts +33 -1
- package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
|
@@ -123,6 +123,10 @@ test("#4782 phase 3: buildRunUatPrompt inlines UAT and keeps summary/project con
|
|
|
123
123
|
// Project path is advertised on-demand; full project body is not inlined.
|
|
124
124
|
assert.match(prompt, /\.gsd\/PROJECT\.md/);
|
|
125
125
|
assert.ok(!prompt.includes("Run-UAT composer fixture project"), "run-uat should not inline full project context");
|
|
126
|
+
|
|
127
|
+
assert.match(prompt, /"toolPresentationPlanId": "run-uat\/default-v1"/);
|
|
128
|
+
assert.match(prompt, /"gsd_uat_result_save"/);
|
|
129
|
+
assert.match(prompt, /"read"/);
|
|
126
130
|
});
|
|
127
131
|
|
|
128
132
|
test("#4782 phase 3: buildRunUatPrompt omits optional slice summary when file is missing", async (t) => {
|
|
@@ -7,6 +7,7 @@ import assert from "node:assert/strict";
|
|
|
7
7
|
import { classifyFailure } from "../recovery-classification.js";
|
|
8
8
|
import { reconcileBeforeDispatch } from "../state-reconciliation.js";
|
|
9
9
|
import { compileUnitToolContract } from "../tool-contract.js";
|
|
10
|
+
import { shouldBlockAutoUnitToolCall } from "../auto-unit-tool-scope.js";
|
|
10
11
|
import type { GSDState } from "../types.js";
|
|
11
12
|
|
|
12
13
|
function makeState(overrides: Partial<GSDState> = {}): GSDState {
|
|
@@ -63,10 +64,35 @@ test("Tool Contract compiles known Unit prompt and tool policy", () => {
|
|
|
63
64
|
assert.equal(result.ok, true);
|
|
64
65
|
assert.equal(result.ok && result.contract.unitType, "execute-task");
|
|
65
66
|
assert.deepEqual(result.ok && result.contract.requiredWorkflowTools, ["gsd_task_complete"]);
|
|
67
|
+
assert.deepEqual(result.ok && result.contract.forbiddenWorkflowTools, []);
|
|
66
68
|
assert.equal(result.ok && result.contract.toolsPolicy.mode, "all");
|
|
67
69
|
assert.ok(result.ok && result.contract.validationRules.includes("closeout-tool-present"));
|
|
68
70
|
});
|
|
69
71
|
|
|
72
|
+
test("Tool Contract records high-risk cross-phase tool boundaries without single-owning every tool", () => {
|
|
73
|
+
const completeSlice = compileUnitToolContract("complete-slice");
|
|
74
|
+
const runUat = compileUnitToolContract("run-uat");
|
|
75
|
+
|
|
76
|
+
assert.equal(completeSlice.ok, true);
|
|
77
|
+
assert.ok(
|
|
78
|
+
completeSlice.ok &&
|
|
79
|
+
completeSlice.contract.forbiddenWorkflowTools.some((tool) => tool.name === "gsd_uat_result_save"),
|
|
80
|
+
"complete-slice should explicitly forbid saving UAT Assessments",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
assert.equal(runUat.ok, true);
|
|
84
|
+
assert.ok(
|
|
85
|
+
runUat.ok &&
|
|
86
|
+
runUat.contract.requiredWorkflowTools.includes("gsd_uat_result_save"),
|
|
87
|
+
"run-uat should own the UAT result-save tool",
|
|
88
|
+
);
|
|
89
|
+
assert.ok(
|
|
90
|
+
runUat.ok &&
|
|
91
|
+
runUat.contract.forbiddenWorkflowTools.some((tool) => tool.name === "gsd_exec"),
|
|
92
|
+
"run-uat should prefer typed UAT execution over generic gsd_exec",
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
70
96
|
test("Tool Contract fails closed for unknown Units", () => {
|
|
71
97
|
const result = compileUnitToolContract("custom-step");
|
|
72
98
|
|
|
@@ -74,10 +100,20 @@ test("Tool Contract fails closed for unknown Units", () => {
|
|
|
74
100
|
assert.equal(!result.ok && result.reason, "unknown-unit-type");
|
|
75
101
|
});
|
|
76
102
|
|
|
103
|
+
test("auto Unit tool scope blocks complete-slice from saving UAT Assessment", () => {
|
|
104
|
+
const result = shouldBlockAutoUnitToolCall("complete-slice", "gsd_uat_result_save");
|
|
105
|
+
|
|
106
|
+
assert.equal(result.block, true);
|
|
107
|
+
assert.match(result.reason ?? "", /Tool Contract failure/);
|
|
108
|
+
assert.match(result.reason ?? "", /Run UAT owns persisted UAT Assessment/);
|
|
109
|
+
});
|
|
110
|
+
|
|
77
111
|
test("Recovery Classification covers ADR-015 failure families", () => {
|
|
78
112
|
const cases = [
|
|
79
113
|
["invalid tool schema enum", "tool-schema", "stop"],
|
|
114
|
+
["Tool Contract failure: complete-slice cannot use gsd_uat_result_save", "tool-contract", "stop"],
|
|
80
115
|
["deterministic policy rejection", "deterministic-policy", "stop"],
|
|
116
|
+
["cannot legally advance because required UAT Assessment artifact is missing", "lifecycle-progression", "stop"],
|
|
81
117
|
["stale worker lease", "stale-worker", "stop"],
|
|
82
118
|
["worktree root missing .git", "worktree-invalid", "stop"],
|
|
83
119
|
["verification drift in state snapshot", "verification-drift", "escalate"],
|
|
@@ -298,6 +298,106 @@ test("session_start installs the welcome screen as the TUI header", async (t) =>
|
|
|
298
298
|
assert.deepEqual(header.render(123), ["welcome 9.9.9-test none 123"]);
|
|
299
299
|
});
|
|
300
300
|
|
|
301
|
+
test("session hooks preserve closeout-boundary UI during completion reroot", async (t) => {
|
|
302
|
+
const dir = join(
|
|
303
|
+
tmpdir(),
|
|
304
|
+
`gsd-closeout-session-hooks-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
305
|
+
);
|
|
306
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
307
|
+
mkdirSync(join(dir, "dist"), { recursive: true });
|
|
308
|
+
const tempGsdHome = join(dir, "home");
|
|
309
|
+
mkdirSync(tempGsdHome, { recursive: true });
|
|
310
|
+
writeFileSync(
|
|
311
|
+
join(dir, "dist", "welcome-screen.js"),
|
|
312
|
+
"export function buildWelcomeScreenLines() { return ['welcome header']; }\n",
|
|
313
|
+
"utf-8",
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
const originalCwd = process.cwd();
|
|
317
|
+
const originalGsdHome = process.env.GSD_HOME;
|
|
318
|
+
const originalGsdPkgRoot = process.env.GSD_PKG_ROOT;
|
|
319
|
+
process.chdir(dir);
|
|
320
|
+
process.env.GSD_HOME = tempGsdHome;
|
|
321
|
+
process.env.GSD_PKG_ROOT = dir;
|
|
322
|
+
autoSession.reset();
|
|
323
|
+
autoSession.completionStopInProgress = true;
|
|
324
|
+
t.after(() => {
|
|
325
|
+
autoSession.reset();
|
|
326
|
+
process.chdir(originalCwd);
|
|
327
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
328
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
329
|
+
if (originalGsdPkgRoot === undefined) delete process.env.GSD_PKG_ROOT;
|
|
330
|
+
else process.env.GSD_PKG_ROOT = originalGsdPkgRoot;
|
|
331
|
+
try { rmSync(dir, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
const handlers = new Map<string, (event: unknown, ctx: any) => Promise<void> | void>();
|
|
335
|
+
const pi = {
|
|
336
|
+
on(event: string, handler: (event: unknown, ctx: any) => Promise<void> | void) {
|
|
337
|
+
handlers.set(event, handler);
|
|
338
|
+
},
|
|
339
|
+
} as any;
|
|
340
|
+
|
|
341
|
+
registerHooks(pi, []);
|
|
342
|
+
|
|
343
|
+
const sessionStart = handlers.get("session_start");
|
|
344
|
+
const sessionSwitch = handlers.get("session_switch");
|
|
345
|
+
assert.ok(sessionStart, "session_start handler must be registered");
|
|
346
|
+
assert.ok(sessionSwitch, "session_switch handler must be registered");
|
|
347
|
+
|
|
348
|
+
const widgetCalls: Array<{ key: string; value: unknown }> = [];
|
|
349
|
+
let headerInstallCount = 0;
|
|
350
|
+
const ctx = {
|
|
351
|
+
hasUI: true,
|
|
352
|
+
ui: {
|
|
353
|
+
notify: () => {},
|
|
354
|
+
setStatus: () => {},
|
|
355
|
+
setFooter: () => {},
|
|
356
|
+
setHeader: () => {
|
|
357
|
+
headerInstallCount++;
|
|
358
|
+
},
|
|
359
|
+
setWorkingMessage: () => {},
|
|
360
|
+
onTerminalInput: () => () => {},
|
|
361
|
+
setWidget: (key: string, value: unknown) => {
|
|
362
|
+
widgetCalls.push({ key, value });
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
sessionManager: { getSessionId: () => null },
|
|
366
|
+
model: null,
|
|
367
|
+
setCompactionThresholdOverride: () => {},
|
|
368
|
+
modelRegistry: {
|
|
369
|
+
setDisabledModelProviders: () => {},
|
|
370
|
+
getProviderAuthMode: () => undefined,
|
|
371
|
+
isProviderRequestReady: () => false,
|
|
372
|
+
},
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
await sessionStart!({}, ctx);
|
|
376
|
+
assert.equal(
|
|
377
|
+
headerInstallCount,
|
|
378
|
+
0,
|
|
379
|
+
"completion reroot session_start must not reinstall the welcome/project-console header",
|
|
380
|
+
);
|
|
381
|
+
assert.ok(
|
|
382
|
+
widgetCalls.some((call) => call.key === "gsd-health" && call.value === undefined),
|
|
383
|
+
"completion reroot session_start should hide the ambient health widget",
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
widgetCalls.length = 0;
|
|
387
|
+
await sessionSwitch!({ reason: "reroot" }, ctx);
|
|
388
|
+
assert.deepEqual(
|
|
389
|
+
widgetCalls
|
|
390
|
+
.filter((call) => call.key === "gsd-progress" || call.key === "gsd-outcome")
|
|
391
|
+
.map((call) => [call.key, call.value]),
|
|
392
|
+
[],
|
|
393
|
+
"completion reroot session_switch must not clear the preserved closeout surface",
|
|
394
|
+
);
|
|
395
|
+
assert.ok(
|
|
396
|
+
widgetCalls.some((call) => call.key === "gsd-health" && call.value === undefined),
|
|
397
|
+
"completion reroot session_switch should keep the ambient health widget hidden",
|
|
398
|
+
);
|
|
399
|
+
});
|
|
400
|
+
|
|
301
401
|
test("session_start and session_switch apply disabled model provider policy from current preferences", async (t) => {
|
|
302
402
|
const dir = join(
|
|
303
403
|
tmpdir(),
|
|
@@ -5,6 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { loadSkills } from "@gsd/pi-coding-agent";
|
|
7
7
|
import {
|
|
8
|
+
buildCompleteSlicePrompt,
|
|
8
9
|
buildPlanMilestonePrompt,
|
|
9
10
|
buildResearchMilestonePrompt,
|
|
10
11
|
buildSkillActivationBlock,
|
|
@@ -143,6 +144,29 @@ test("buildSkillActivationBlock includes skill_rules matches and task-plan skill
|
|
|
143
144
|
}
|
|
144
145
|
});
|
|
145
146
|
|
|
147
|
+
test("buildSkillActivationBlock matches skill_rules against exact unit type context", () => {
|
|
148
|
+
const base = makeTempBase();
|
|
149
|
+
try {
|
|
150
|
+
writeSkill(base, "complete-slice-policies", "Use for complete-slice closeout policy checks.");
|
|
151
|
+
writeSkill(base, "slice-broad", "Use for broad slice work.");
|
|
152
|
+
loadOnlyTestSkills(base);
|
|
153
|
+
|
|
154
|
+
const result = buildBlock(base, {
|
|
155
|
+
unitType: "complete-slice",
|
|
156
|
+
}, {
|
|
157
|
+
skill_rules: [
|
|
158
|
+
{ when: "complete-slice", use: ["complete-slice-policies"] },
|
|
159
|
+
{ when: "slice", use: ["slice-broad"] },
|
|
160
|
+
],
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
assert.match(result, /Call Skill\(\{ skill: 'complete-slice-policies' \}\)/);
|
|
164
|
+
assert.doesNotMatch(result, /slice-broad/);
|
|
165
|
+
} finally {
|
|
166
|
+
cleanup(base);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
146
170
|
test("buildSkillActivationBlock honors avoid_skills against always_use_skills", () => {
|
|
147
171
|
const base = makeTempBase();
|
|
148
172
|
try {
|
|
@@ -328,6 +352,37 @@ test("milestone prompt builders propagate always_use_skills through buildSkillAc
|
|
|
328
352
|
}
|
|
329
353
|
});
|
|
330
354
|
|
|
355
|
+
test("complete-slice prompt propagates always_use_skills through buildSkillActivationBlock", async () => {
|
|
356
|
+
const base = makeTempBase();
|
|
357
|
+
try {
|
|
358
|
+
writeSkill(base, "write-docs", "Use when writing docs or RFCs.");
|
|
359
|
+
writeProjectPreferences(base, "always_use_skills:\n - write-docs\n");
|
|
360
|
+
loadOnlyTestSkills(base);
|
|
361
|
+
|
|
362
|
+
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
363
|
+
const sliceDir = join(milestoneDir, "slices", "S01");
|
|
364
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
365
|
+
writeFileSync(
|
|
366
|
+
join(milestoneDir, "M001-ROADMAP.md"),
|
|
367
|
+
[
|
|
368
|
+
"# M001: Test",
|
|
369
|
+
"",
|
|
370
|
+
"## Slices",
|
|
371
|
+
"",
|
|
372
|
+
"- [ ] **S01: Slice** `risk:low` `depends:[]`",
|
|
373
|
+
"",
|
|
374
|
+
].join("\n"),
|
|
375
|
+
);
|
|
376
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), "# S01: Slice\n\n## Tasks\n\n- [x] **T01: Done**\n");
|
|
377
|
+
|
|
378
|
+
const prompt = await buildCompleteSlicePrompt("M001", "Test", "S01", "Slice", base);
|
|
379
|
+
|
|
380
|
+
assert.match(prompt, /Call Skill\(\{ skill: 'write-docs' \}\)/);
|
|
381
|
+
} finally {
|
|
382
|
+
cleanup(base);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
331
386
|
test("skill manifest strict warnings require GSD_SKILL_MANIFEST_STRICT=1", (t) => {
|
|
332
387
|
const previousStrict = process.env.GSD_SKILL_MANIFEST_STRICT;
|
|
333
388
|
const previousStderr = setStderrLoggingEnabled(false);
|
|
@@ -148,6 +148,7 @@ test("fresh start registers the auto worker before bootstrap enters worktree flo
|
|
|
148
148
|
const freshStartSectionIdx = startAutoBody.indexOf("// ── Fresh start path — delegated to auto-start.ts ──");
|
|
149
149
|
const resumeBody = startAutoBody.slice(resumeSectionIdx, freshStartSectionIdx);
|
|
150
150
|
const resumeDbOpenIdx = resumeBody.indexOf("await openProjectDbIfPresent(base);");
|
|
151
|
+
const resumeMergeReconcileIdx = resumeBody.indexOf("reconcileMergedMilestonesFromJournal(base);");
|
|
151
152
|
const resumeRegisterIdx = resumeBody.indexOf("registerAutoWorkerForSession(s, base);");
|
|
152
153
|
const resumeEnterMilestoneIdx = resumeBody.indexOf("buildLifecycle().enterMilestone");
|
|
153
154
|
const dbOpenIdx = bootstrapBody.indexOf("await openProjectDbIfPresent(base);");
|
|
@@ -164,6 +165,7 @@ test("fresh start registers the auto worker before bootstrap enters worktree flo
|
|
|
164
165
|
assert.ok(resumeSectionIdx > -1, "startAuto should have resume milestone entry flow");
|
|
165
166
|
assert.ok(freshStartSectionIdx > resumeSectionIdx, "resume assertions should be scoped before fresh start");
|
|
166
167
|
assert.ok(resumeDbOpenIdx > -1, "resume should open DB before milestone entry");
|
|
168
|
+
assert.ok(resumeMergeReconcileIdx > -1, "resume should reconcile merged milestones before deriving dispatch state");
|
|
167
169
|
assert.ok(resumeRegisterIdx > -1, "resume should register worker before milestone entry");
|
|
168
170
|
assert.ok(resumeEnterMilestoneIdx > -1, "resume should enter milestones through lifecycle");
|
|
169
171
|
assert.ok(bootstrapIdx > -1, "bootstrapAutoSession should exist");
|
|
@@ -179,8 +181,10 @@ test("fresh start registers the auto worker before bootstrap enters worktree flo
|
|
|
179
181
|
"bootstrap must open DB and register worker before first enterMilestone",
|
|
180
182
|
);
|
|
181
183
|
assert.ok(
|
|
182
|
-
resumeDbOpenIdx <
|
|
183
|
-
|
|
184
|
+
resumeDbOpenIdx < resumeMergeReconcileIdx &&
|
|
185
|
+
resumeMergeReconcileIdx < resumeRegisterIdx &&
|
|
186
|
+
resumeRegisterIdx < resumeEnterMilestoneIdx,
|
|
187
|
+
"resume must open DB, reconcile merged milestones, and register worker before first enterMilestone",
|
|
184
188
|
);
|
|
185
189
|
});
|
|
186
190
|
|
|
@@ -906,6 +906,51 @@ test("ADR-017 (#5704): registered milestone (DB row present) → no drift", asyn
|
|
|
906
906
|
|
|
907
907
|
// ─── #5705: roadmap-divergence drift ─────────────────────────────────────────
|
|
908
908
|
|
|
909
|
+
test("ADR-017 (#391): roadmap-divergence skips slices before task planning completes", async (t) => {
|
|
910
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-unplanned-"));
|
|
911
|
+
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
912
|
+
const roadmapPath = join(milestoneDir, "M001-ROADMAP.md");
|
|
913
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
914
|
+
const originalRoadmap = [
|
|
915
|
+
"# M001: Test",
|
|
916
|
+
"",
|
|
917
|
+
"**Vision:** Verify transient milestone planning state",
|
|
918
|
+
"",
|
|
919
|
+
"## Slices",
|
|
920
|
+
"",
|
|
921
|
+
"- [ ] **S01: Foundation** `risk:medium` `depends:[]`",
|
|
922
|
+
"- [ ] **S02: Feature** `risk:medium` `depends:[S01]`",
|
|
923
|
+
"",
|
|
924
|
+
].join("\n");
|
|
925
|
+
writeFileSync(roadmapPath, originalRoadmap);
|
|
926
|
+
t.after(() => {
|
|
927
|
+
try { closeDatabase(); } catch { /* noop */ }
|
|
928
|
+
rmSync(base, { recursive: true, force: true });
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
932
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
933
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
|
|
934
|
+
insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
|
|
935
|
+
|
|
936
|
+
assert.equal(getSliceTasks("M001", "S01").length, 0, "pre: S01 has not been planned");
|
|
937
|
+
assert.equal(getSliceTasks("M001", "S02").length, 0, "pre: S02 has not been planned");
|
|
938
|
+
|
|
939
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
940
|
+
invalidateStateCache: () => {},
|
|
941
|
+
deriveState: async () => makeState(),
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
assert.equal(result.ok, true);
|
|
945
|
+
assert.equal(
|
|
946
|
+
result.repaired.some((d) => d.kind === "roadmap-divergence"),
|
|
947
|
+
false,
|
|
948
|
+
"unplanned slices should not trigger roadmap-divergence repair",
|
|
949
|
+
);
|
|
950
|
+
assert.equal(readFileSync(roadmapPath, "utf-8"), originalRoadmap);
|
|
951
|
+
assert.deepEqual(getSlice("M001", "S02")?.depends, [], "DB remains unchanged");
|
|
952
|
+
});
|
|
953
|
+
|
|
909
954
|
test("ADR-017 (#5705): roadmap-divergence re-renders projection without syncing depends into DB", async (t) => {
|
|
910
955
|
const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-"));
|
|
911
956
|
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
@@ -936,6 +981,8 @@ test("ADR-017 (#5705): roadmap-divergence re-renders projection without syncing
|
|
|
936
981
|
// Seed DB with S02 depending on [] — diverges from ROADMAP.md
|
|
937
982
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
|
|
938
983
|
insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
|
|
984
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
|
|
985
|
+
insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Plan S02", status: "pending" });
|
|
939
986
|
|
|
940
987
|
assert.deepEqual(getSlice("M001", "S02")?.depends, [], "pre: DB has S02.depends = []");
|
|
941
988
|
|
|
@@ -987,6 +1034,7 @@ test("ADR-017 (#5705): ROADMAP-only slice is removed from projection and not ins
|
|
|
987
1034
|
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
988
1035
|
// Only insert S01 — S02 is intentionally absent from the DB.
|
|
989
1036
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
|
|
1037
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
|
|
990
1038
|
|
|
991
1039
|
assert.equal(getSlice("M001", "S02"), null, "pre: S02 has no DB row");
|
|
992
1040
|
|
|
@@ -1035,6 +1083,8 @@ test("ADR-017 (#5705): ROADMAP sequence drift re-renders from DB order without m
|
|
|
1035
1083
|
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
1036
1084
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
|
|
1037
1085
|
insertSlice({ id: "S02", milestoneId: "M001", title: "Feature", status: "pending", risk: "medium", depends: [], demo: "", sequence: 2 });
|
|
1086
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
|
|
1087
|
+
insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Plan S02", status: "pending" });
|
|
1038
1088
|
|
|
1039
1089
|
const result = await reconcileBeforeDispatch(base, {
|
|
1040
1090
|
invalidateStateCache: () => {},
|
|
@@ -1078,6 +1128,7 @@ test("ADR-017 (#5705): ROADMAP checkbox drift re-renders from DB status without
|
|
|
1078
1128
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1079
1129
|
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
1080
1130
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "medium", depends: [], demo: "", sequence: 1 });
|
|
1131
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
|
|
1081
1132
|
|
|
1082
1133
|
const result = await reconcileBeforeDispatch(base, {
|
|
1083
1134
|
invalidateStateCache: () => {},
|
|
@@ -1119,6 +1170,7 @@ test("ADR-017 (#5705): in-sync ROADMAP and DB → no roadmap-divergence drift",
|
|
|
1119
1170
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1120
1171
|
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
1121
1172
|
insertSlice({ id: "S01", milestoneId: "M001", title: "Foundation", status: "pending", risk: "low", depends: [], demo: "", sequence: 1 });
|
|
1173
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Plan S01", status: "pending" });
|
|
1122
1174
|
|
|
1123
1175
|
const result = await reconcileBeforeDispatch(base, {
|
|
1124
1176
|
invalidateStateCache: () => {},
|
|
@@ -1300,6 +1352,145 @@ test("ADR-017: orphan task completion artifact fails closed", async (t) => {
|
|
|
1300
1352
|
assert.match(result.blockers.join("\n"), /Artifact\/DB status drift/);
|
|
1301
1353
|
});
|
|
1302
1354
|
|
|
1355
|
+
test("ADR-017 (#414): failure-path summary artifact blocker matches auto.ts filter phrase", async (t) => {
|
|
1356
|
+
// When gsd_summary_save writes a SUMMARY artifact row for a task that never
|
|
1357
|
+
// called gsd_task_complete, the task stays pending and the artifact DB row
|
|
1358
|
+
// produces an artifact-db-status-divergence blocker. The auto.ts dispatch
|
|
1359
|
+
// wrapper must be able to filter this class of blocker to allow re-dispatch.
|
|
1360
|
+
// If this test fails, update the filter strings in auto.ts to match.
|
|
1361
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-failure-path-summary-drift-"));
|
|
1362
|
+
t.after(() => cleanup(base));
|
|
1363
|
+
|
|
1364
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S04"), { recursive: true });
|
|
1365
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1366
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
1367
|
+
insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
|
|
1368
|
+
insertTask({ id: "T01", sliceId: "S04", milestoneId: "M001", title: "Task", status: "pending" });
|
|
1369
|
+
insertArtifact({
|
|
1370
|
+
path: join(base, ".gsd", "milestones", "M001", "slices", "S04", "tasks", "T01", "T01-SUMMARY.md"),
|
|
1371
|
+
artifact_type: "SUMMARY",
|
|
1372
|
+
milestone_id: "M001",
|
|
1373
|
+
slice_id: "S04",
|
|
1374
|
+
task_id: "T01",
|
|
1375
|
+
full_content: "# T01 Failure Summary\n",
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1379
|
+
invalidateStateCache: () => {},
|
|
1380
|
+
deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
assert.equal(result.ok, true);
|
|
1384
|
+
assert.ok(result.blockers.length > 0, "blocker must be produced for pending-task SUMMARY drift");
|
|
1385
|
+
const blocker = result.blockers.join("\n");
|
|
1386
|
+
assert.match(
|
|
1387
|
+
blocker,
|
|
1388
|
+
/has SUMMARY artifact while DB status is/,
|
|
1389
|
+
"blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
|
|
1390
|
+
);
|
|
1391
|
+
});
|
|
1392
|
+
|
|
1393
|
+
test("ADR-017 (#414): no-db-tasks summary artifact blocker matches auto.ts filter phrase", async (t) => {
|
|
1394
|
+
// When a slice has SUMMARY artifacts in the DB but no DB tasks, the auto.ts
|
|
1395
|
+
// filter must be able to recognise this as a failure-path case and skip it.
|
|
1396
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-no-db-tasks-summary-drift-"));
|
|
1397
|
+
t.after(() => cleanup(base));
|
|
1398
|
+
|
|
1399
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S04"), { recursive: true });
|
|
1400
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1401
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
1402
|
+
insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
|
|
1403
|
+
// No tasks inserted — slice has SUMMARY artifacts for a task that no longer exists.
|
|
1404
|
+
insertArtifact({
|
|
1405
|
+
path: join(base, ".gsd", "milestones", "M001", "slices", "S04", "tasks", "T01", "T01-SUMMARY.md"),
|
|
1406
|
+
artifact_type: "SUMMARY",
|
|
1407
|
+
milestone_id: "M001",
|
|
1408
|
+
slice_id: "S04",
|
|
1409
|
+
task_id: "T01",
|
|
1410
|
+
full_content: "# T01 Failure Summary\n",
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1414
|
+
invalidateStateCache: () => {},
|
|
1415
|
+
deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
|
|
1416
|
+
});
|
|
1417
|
+
|
|
1418
|
+
assert.equal(result.ok, true);
|
|
1419
|
+
assert.ok(result.blockers.length > 0, "blocker must be produced for no-db-tasks SUMMARY drift");
|
|
1420
|
+
const blocker = result.blockers.join("\n");
|
|
1421
|
+
assert.match(
|
|
1422
|
+
blocker,
|
|
1423
|
+
/has task SUMMARY artifacts but no DB tasks/,
|
|
1424
|
+
"blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
|
|
1425
|
+
);
|
|
1426
|
+
});
|
|
1427
|
+
|
|
1428
|
+
test("ADR-017 (#414): task-level on-disk summary blocker matches auto.ts filter phrase", async (t) => {
|
|
1429
|
+
// When gsd_summary_save writes a SUMMARY file to disk for a task that never
|
|
1430
|
+
// called gsd_task_complete, but the artifact DB row was not yet written (or
|
|
1431
|
+
// the process crashed before insertion), reconciliation emits
|
|
1432
|
+
// "has SUMMARY on disk while DB status is". The auto.ts filter must match
|
|
1433
|
+
// this phrase so re-dispatch is not blocked.
|
|
1434
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-task-disk-summary-drift-"));
|
|
1435
|
+
t.after(() => cleanup(base));
|
|
1436
|
+
|
|
1437
|
+
const tasksDir = join(base, ".gsd", "milestones", "M001", "slices", "S04", "tasks");
|
|
1438
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
1439
|
+
writeFileSync(join(tasksDir, "T01-SUMMARY.md"), "# T01 Failure Summary\n");
|
|
1440
|
+
|
|
1441
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1442
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
1443
|
+
insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
|
|
1444
|
+
insertTask({ id: "T01", sliceId: "S04", milestoneId: "M001", title: "Task", status: "pending" });
|
|
1445
|
+
// No artifact row inserted — SUMMARY exists only on disk.
|
|
1446
|
+
|
|
1447
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1448
|
+
invalidateStateCache: () => {},
|
|
1449
|
+
deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
|
|
1450
|
+
});
|
|
1451
|
+
|
|
1452
|
+
assert.equal(result.ok, true);
|
|
1453
|
+
assert.ok(result.blockers.length > 0, "blocker must be produced for on-disk task SUMMARY drift");
|
|
1454
|
+
const blocker = result.blockers.join("\n");
|
|
1455
|
+
assert.match(
|
|
1456
|
+
blocker,
|
|
1457
|
+
/has SUMMARY on disk while DB status is/,
|
|
1458
|
+
"blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
|
|
1459
|
+
);
|
|
1460
|
+
});
|
|
1461
|
+
|
|
1462
|
+
test("ADR-017 (#414): slice-level on-disk summary blocker matches auto.ts filter phrase", async (t) => {
|
|
1463
|
+
// When a SUMMARY file exists on disk for a slice that is still pending
|
|
1464
|
+
// (no gsd_task_complete for the slice), reconciliation emits
|
|
1465
|
+
// "has SUMMARY on disk while DB status is". The auto.ts filter must match
|
|
1466
|
+
// this phrase so re-dispatch is not blocked.
|
|
1467
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-slice-disk-summary-drift-"));
|
|
1468
|
+
t.after(() => cleanup(base));
|
|
1469
|
+
|
|
1470
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S04");
|
|
1471
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
1472
|
+
writeFileSync(join(sliceDir, "S04-SUMMARY.md"), "# S04 Failure Summary\n");
|
|
1473
|
+
|
|
1474
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1475
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
1476
|
+
insertSlice({ id: "S04", milestoneId: "M001", title: "Slice", status: "pending" });
|
|
1477
|
+
// No artifact row inserted — SUMMARY exists only on disk.
|
|
1478
|
+
|
|
1479
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1480
|
+
invalidateStateCache: () => {},
|
|
1481
|
+
deriveState: async () => makeState({ activeMilestone: { id: "M001", title: "Milestone" } }),
|
|
1482
|
+
});
|
|
1483
|
+
|
|
1484
|
+
assert.equal(result.ok, true);
|
|
1485
|
+
assert.ok(result.blockers.length > 0, "blocker must be produced for on-disk slice SUMMARY drift");
|
|
1486
|
+
const blocker = result.blockers.join("\n");
|
|
1487
|
+
assert.match(
|
|
1488
|
+
blocker,
|
|
1489
|
+
/has SUMMARY on disk while DB status is/,
|
|
1490
|
+
"blocker phrase must match the filter in auto.ts reconcileBeforeDispatch wrapper",
|
|
1491
|
+
);
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1303
1494
|
test("ADR-017: completed milestone dispatch history blocks accidental re-planning", async (t) => {
|
|
1304
1495
|
const base = mkdtempSync(join(tmpdir(), "gsd-completed-reopened-drift-"));
|
|
1305
1496
|
t.after(() => cleanup(base));
|