@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.9bb7453
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 +44 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -4
- 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 +2 -1
- package/dist/resources/extensions/gsd/auto.js +31 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +83 -4
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +39 -14
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- 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 +30 -69
- 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/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 +48 -24
- 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/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-presentation-plan.js +120 -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 +403 -3
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- 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 -1
- 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 +6 -6
- 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 +6 -6
- 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/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 +38 -0
- 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/types.d.ts +3 -0
- 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 +406 -17
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +484 -116
- 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/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/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 +53 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
- package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +4 -4
- 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 +2 -1
- package/src/resources/extensions/gsd/auto.ts +47 -5
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +90 -4
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +60 -19
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- 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 +91 -83
- 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/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 +48 -24
- 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/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-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/browser-evidence.test.ts +142 -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-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/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.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +66 -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/migration-auto-check.test.ts +3 -3
- 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 +53 -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 +35 -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/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 +213 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +167 -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 +489 -3
- 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/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 -1
- 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/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_ssgManifest.js +0 -0
|
@@ -10,19 +10,21 @@ import {
|
|
|
10
10
|
getMilestone,
|
|
11
11
|
getSliceStatusSummary,
|
|
12
12
|
getSliceTaskCounts,
|
|
13
|
+
insertGateRun,
|
|
13
14
|
readTransaction,
|
|
14
15
|
saveGateResult,
|
|
16
|
+
upsertQualityGate,
|
|
15
17
|
} from "../gsd-db.js";
|
|
16
18
|
import { GATE_REGISTRY } from "../gate-registry.js";
|
|
17
19
|
import { generateRequirementsMd, saveArtifactToDb } from "../db-writer.js";
|
|
18
20
|
import { clearPathCache, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
|
|
19
21
|
import { saveFile, clearParseCache } from "../files.js";
|
|
20
|
-
import { unlinkSync } from "node:fs";
|
|
21
|
-
import { join } from "node:path";
|
|
22
|
+
import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
23
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
22
24
|
import type { CompleteMilestoneParams } from "./complete-milestone.js";
|
|
23
25
|
import { handleCompleteMilestone } from "./complete-milestone.js";
|
|
24
26
|
import { handleCompleteTask } from "./complete-task.js";
|
|
25
|
-
import type { CompleteSliceParams } from "../types.js";
|
|
27
|
+
import type { CompleteSliceParams, EscalationOption } from "../types.js";
|
|
26
28
|
import { handleCompleteSlice } from "./complete-slice.js";
|
|
27
29
|
import type { PlanMilestoneParams } from "./plan-milestone.js";
|
|
28
30
|
import { handlePlanMilestone } from "./plan-milestone.js";
|
|
@@ -45,6 +47,12 @@ import { invalidateStateCache } from "../state.js";
|
|
|
45
47
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
46
48
|
import { parseProject } from "../schemas/parsers.js";
|
|
47
49
|
import { getAutoRuntimeSnapshot } from "../auto-runtime-state.js";
|
|
50
|
+
import {
|
|
51
|
+
canonicalWorkflowToolName,
|
|
52
|
+
parseMcpToolName,
|
|
53
|
+
RUN_UAT_FORBIDDEN_TOOL_NAMES,
|
|
54
|
+
RUN_UAT_WORKFLOW_TOOL_NAMES,
|
|
55
|
+
} from "../tool-presentation-plan.js";
|
|
48
56
|
|
|
49
57
|
export const SUPPORTED_SUMMARY_ARTIFACT_TYPES = [
|
|
50
58
|
"SUMMARY",
|
|
@@ -339,6 +347,14 @@ type VerificationEvidenceInput =
|
|
|
339
347
|
}
|
|
340
348
|
| string;
|
|
341
349
|
|
|
350
|
+
interface TaskEscalationInput {
|
|
351
|
+
question: string;
|
|
352
|
+
options: EscalationOption[];
|
|
353
|
+
recommendation: string;
|
|
354
|
+
recommendationRationale: string;
|
|
355
|
+
continueWithDefault: boolean;
|
|
356
|
+
}
|
|
357
|
+
|
|
342
358
|
export interface TaskCompleteParams {
|
|
343
359
|
taskId: string;
|
|
344
360
|
sliceId: string;
|
|
@@ -351,6 +367,7 @@ export interface TaskCompleteParams {
|
|
|
351
367
|
keyFiles?: string[];
|
|
352
368
|
keyDecisions?: string[];
|
|
353
369
|
blockerDiscovered?: boolean;
|
|
370
|
+
escalation?: TaskEscalationInput;
|
|
354
371
|
verificationEvidence?: VerificationEvidenceInput[];
|
|
355
372
|
}
|
|
356
373
|
|
|
@@ -409,6 +426,56 @@ export interface SaveGateResultParams {
|
|
|
409
426
|
findings?: string;
|
|
410
427
|
}
|
|
411
428
|
|
|
429
|
+
export type UatType =
|
|
430
|
+
| "artifact-driven"
|
|
431
|
+
| "browser-executable"
|
|
432
|
+
| "runtime-executable"
|
|
433
|
+
| "live-runtime"
|
|
434
|
+
| "mixed"
|
|
435
|
+
| "human-experience";
|
|
436
|
+
|
|
437
|
+
export type UatVerdict = "PASS" | "FAIL" | "PARTIAL";
|
|
438
|
+
export type UatCheckResult = "PASS" | "FAIL" | "NEEDS-HUMAN";
|
|
439
|
+
|
|
440
|
+
export interface UatEvidenceRef {
|
|
441
|
+
kind: "gsd_uat_exec" | "gsd_exec" | "screenshot" | "log" | "url" | "browser";
|
|
442
|
+
ref: string;
|
|
443
|
+
note?: string;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export interface UatCheckResultInput {
|
|
447
|
+
id: string;
|
|
448
|
+
description: string;
|
|
449
|
+
mode: "artifact" | "runtime" | "browser" | "human-follow-up";
|
|
450
|
+
result: UatCheckResult;
|
|
451
|
+
evidence?: UatEvidenceRef[];
|
|
452
|
+
notes?: string;
|
|
453
|
+
nonAutomatable?: boolean;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
export interface UatPresentationInput {
|
|
457
|
+
surface: "provider-tools" | "claude-code-sdk" | "mcp" | "hybrid";
|
|
458
|
+
model?: { provider?: string; api?: string; id?: string };
|
|
459
|
+
presentedTools: string[];
|
|
460
|
+
blockedTools: Array<{ name: string; reason: string }>;
|
|
461
|
+
aliases?: Array<{ requested: string; canonical: string }>;
|
|
462
|
+
fallbackToolsUsed?: string[];
|
|
463
|
+
toolPresentationPlanId?: string;
|
|
464
|
+
notes?: string;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export interface UatResultSaveParams {
|
|
468
|
+
milestoneId: string;
|
|
469
|
+
sliceId: string;
|
|
470
|
+
uatType: UatType;
|
|
471
|
+
verdict: UatVerdict;
|
|
472
|
+
checks: UatCheckResultInput[];
|
|
473
|
+
presentation: UatPresentationInput;
|
|
474
|
+
notes?: string;
|
|
475
|
+
attempt?: number | string | "auto";
|
|
476
|
+
previousAttemptId?: string;
|
|
477
|
+
}
|
|
478
|
+
|
|
412
479
|
export async function executeTaskComplete(
|
|
413
480
|
params: TaskCompleteParams,
|
|
414
481
|
basePath: string = process.cwd(),
|
|
@@ -453,6 +520,28 @@ export async function executeTaskComplete(
|
|
|
453
520
|
isError: true,
|
|
454
521
|
};
|
|
455
522
|
}
|
|
523
|
+
if (result.escalation) {
|
|
524
|
+
const recommended = result.escalation.options.find((option) => option.id === result.escalation?.recommendation);
|
|
525
|
+
const optionIds = result.escalation.options.map((option) => option.id).join("|");
|
|
526
|
+
return {
|
|
527
|
+
content: [{
|
|
528
|
+
type: "text",
|
|
529
|
+
text: [
|
|
530
|
+
`Task completed with escalation decision required: ${result.escalation.question}`,
|
|
531
|
+
`Recommendation: ${result.escalation.recommendation}${recommended ? ` (${recommended.label})` : ""} — ${result.escalation.recommendationRationale}`,
|
|
532
|
+
`Resolve with: /gsd escalate resolve ${result.taskId} <${optionIds}|accept|reject-blocker> [rationale...]`,
|
|
533
|
+
].join("\n"),
|
|
534
|
+
}],
|
|
535
|
+
details: {
|
|
536
|
+
operation: "complete_task",
|
|
537
|
+
taskId: result.taskId,
|
|
538
|
+
sliceId: result.sliceId,
|
|
539
|
+
milestoneId: result.milestoneId,
|
|
540
|
+
summaryPath: result.summaryPath,
|
|
541
|
+
escalation: result.escalation,
|
|
542
|
+
},
|
|
543
|
+
};
|
|
544
|
+
}
|
|
456
545
|
return {
|
|
457
546
|
content: [{ type: "text", text: `Completed task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
458
547
|
details: {
|
|
@@ -907,6 +996,403 @@ export async function executeSaveGateResult(
|
|
|
907
996
|
}
|
|
908
997
|
}
|
|
909
998
|
|
|
999
|
+
function errorResult(operation: string, message: string, error: string): ToolExecutionResult {
|
|
1000
|
+
return {
|
|
1001
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1002
|
+
details: { operation, error },
|
|
1003
|
+
isError: true,
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
function isNonEmptyString(value: unknown): value is string {
|
|
1008
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
function ensureUatRequiredFields(params: UatResultSaveParams): string | null {
|
|
1012
|
+
if (!isNonEmptyString(params.milestoneId)) return "milestoneId is required";
|
|
1013
|
+
if (!isNonEmptyString(params.sliceId)) return "sliceId is required";
|
|
1014
|
+
if (!isNonEmptyString(params.uatType)) return "uatType is required";
|
|
1015
|
+
if (!["PASS", "FAIL", "PARTIAL"].includes(params.verdict)) return "verdict must be PASS, FAIL, or PARTIAL";
|
|
1016
|
+
if (!Array.isArray(params.checks) || params.checks.length === 0) return "checks must contain at least one UAT check";
|
|
1017
|
+
if (!params.presentation || !Array.isArray(params.presentation.presentedTools)) return "presentation.presentedTools is required";
|
|
1018
|
+
if (!Array.isArray(params.presentation.blockedTools)) return "presentation.blockedTools is required";
|
|
1019
|
+
return null;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
function approvedEvidenceRoots(basePath: string): string[] {
|
|
1023
|
+
const contract = resolveGsdPathContract(basePath);
|
|
1024
|
+
return [contract.worktreeGsd, contract.projectGsd].filter((root): root is string => typeof root === "string");
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
function approvedBrowserArtifactRoots(basePath: string): string[] {
|
|
1028
|
+
const contract = resolveGsdPathContract(basePath);
|
|
1029
|
+
const roots = [contract.workRoot, contract.projectRoot].map((root) => join(root, ".artifacts", "browser"));
|
|
1030
|
+
return [...new Set(roots)];
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
function pathStartsWithin(parent: string, target: string): boolean {
|
|
1034
|
+
const normalizedParent = parent.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1035
|
+
const normalizedTarget = target.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1036
|
+
return normalizedTarget === normalizedParent || normalizedTarget.startsWith(`${normalizedParent}/`);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
function pushUnique(paths: string[], candidate: string): void {
|
|
1040
|
+
if (!paths.includes(candidate)) paths.push(candidate);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
function execMetaPathCandidates(basePath: string, ref: string): string[] {
|
|
1044
|
+
const trimmed = ref.trim();
|
|
1045
|
+
const candidates: string[] = [];
|
|
1046
|
+
const execDirs = approvedEvidenceRoots(basePath).map((root) => join(root, "exec"));
|
|
1047
|
+
const normalizedRef = trimmed.replace(/\\/g, "/");
|
|
1048
|
+
const pathLike = normalizedRef.endsWith(".meta.json") || normalizedRef.includes("/.gsd/exec/");
|
|
1049
|
+
|
|
1050
|
+
if (pathLike) {
|
|
1051
|
+
const rawPath = isAbsolute(trimmed) ? resolve(trimmed) : resolve(basePath, trimmed);
|
|
1052
|
+
pushUnique(candidates, rawPath);
|
|
1053
|
+
|
|
1054
|
+
const relativeExecMarker = ".gsd/exec/";
|
|
1055
|
+
const markerIndex = normalizedRef.indexOf(relativeExecMarker);
|
|
1056
|
+
if (markerIndex >= 0) {
|
|
1057
|
+
const execRelative = normalizedRef.slice(markerIndex + relativeExecMarker.length);
|
|
1058
|
+
for (const execDir of execDirs) {
|
|
1059
|
+
pushUnique(candidates, join(execDir, execRelative));
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
return candidates.filter((candidate) =>
|
|
1064
|
+
execDirs.some((execDir) => pathStartsWithin(execDir, candidate))
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
for (const execDir of execDirs) {
|
|
1069
|
+
pushUnique(candidates, join(execDir, `${trimmed}.meta.json`));
|
|
1070
|
+
}
|
|
1071
|
+
return candidates;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
function resolveExecMetaPath(basePath: string, ref: string): string | null {
|
|
1075
|
+
for (const candidate of execMetaPathCandidates(basePath, ref)) {
|
|
1076
|
+
if (existsSync(candidate)) return candidate;
|
|
1077
|
+
}
|
|
1078
|
+
return null;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
function evidencePathIsApproved(basePath: string, ref: string): boolean {
|
|
1082
|
+
const normalizedRef = ref.replace(/\\/g, "/");
|
|
1083
|
+
if (normalizedRef.startsWith(".gsd/exec/") || normalizedRef.startsWith(".gsd/uat/")) return true;
|
|
1084
|
+
if (normalizedRef.startsWith(".artifacts/browser/")) {
|
|
1085
|
+
const resolvedRef = resolve(basePath, ref);
|
|
1086
|
+
return approvedBrowserArtifactRoots(basePath).some((root) => pathStartsWithin(root, resolvedRef));
|
|
1087
|
+
}
|
|
1088
|
+
const gsdEvidenceApproved = approvedEvidenceRoots(basePath).some((root) => {
|
|
1089
|
+
return pathStartsWithin(join(root, "exec"), ref) || pathStartsWithin(join(root, "uat"), ref);
|
|
1090
|
+
});
|
|
1091
|
+
if (gsdEvidenceApproved) return true;
|
|
1092
|
+
return approvedBrowserArtifactRoots(basePath).some((root) => pathStartsWithin(root, ref));
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
function validateEvidenceRef(basePath: string, evidence: UatEvidenceRef): string | null {
|
|
1096
|
+
if (!isNonEmptyString(evidence.ref)) return "evidence.ref is required";
|
|
1097
|
+
if (evidence.kind === "gsd_uat_exec" || evidence.kind === "gsd_exec") {
|
|
1098
|
+
const path = resolveExecMetaPath(basePath, evidence.ref.trim());
|
|
1099
|
+
if (!path) return `missing gsd_exec metadata for evidence id "${evidence.ref}"`;
|
|
1100
|
+
if (evidence.kind === "gsd_uat_exec") {
|
|
1101
|
+
try {
|
|
1102
|
+
const meta = JSON.parse(readFileSync(path, "utf-8")) as { metadata?: { kind?: unknown } };
|
|
1103
|
+
if (meta.metadata?.kind !== "uat_exec") return `evidence id "${evidence.ref}" is not typed as uat_exec`;
|
|
1104
|
+
} catch {
|
|
1105
|
+
return `invalid gsd_exec metadata JSON for evidence id "${evidence.ref}"`;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
return null;
|
|
1109
|
+
}
|
|
1110
|
+
if (evidence.kind === "url") {
|
|
1111
|
+
try {
|
|
1112
|
+
const parsed = new URL(evidence.ref);
|
|
1113
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:"
|
|
1114
|
+
? null
|
|
1115
|
+
: `invalid URL evidence ref "${evidence.ref}"`;
|
|
1116
|
+
} catch {
|
|
1117
|
+
return `invalid URL evidence ref "${evidence.ref}"`;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
return evidencePathIsApproved(basePath, evidence.ref)
|
|
1121
|
+
? null
|
|
1122
|
+
: `evidence ref "${evidence.ref}" is outside approved evidence locations`;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
function validateUatChecks(basePath: string, params: UatResultSaveParams): string | null {
|
|
1126
|
+
for (const check of params.checks) {
|
|
1127
|
+
if (!isNonEmptyString(check.id)) return "every check must have a non-empty id";
|
|
1128
|
+
if (!isNonEmptyString(check.description)) return `check ${check.id} must have a description`;
|
|
1129
|
+
if (!["artifact", "runtime", "browser", "human-follow-up"].includes(check.mode)) {
|
|
1130
|
+
return `check ${check.id} has invalid mode "${check.mode}"`;
|
|
1131
|
+
}
|
|
1132
|
+
if (!["PASS", "FAIL", "NEEDS-HUMAN"].includes(check.result)) {
|
|
1133
|
+
return `check ${check.id} has invalid result "${check.result}"`;
|
|
1134
|
+
}
|
|
1135
|
+
if (check.result === "PASS" || check.result === "FAIL") {
|
|
1136
|
+
if (!Array.isArray(check.evidence) || check.evidence.length === 0) {
|
|
1137
|
+
return `check ${check.id} is ${check.result} but has no objective evidence`;
|
|
1138
|
+
}
|
|
1139
|
+
for (const evidence of check.evidence) {
|
|
1140
|
+
const error = validateEvidenceRef(basePath, evidence);
|
|
1141
|
+
if (error) return `check ${check.id}: ${error}`;
|
|
1142
|
+
}
|
|
1143
|
+
} else if (!isNonEmptyString(check.notes)) {
|
|
1144
|
+
return `check ${check.id} is NEEDS-HUMAN but has no manual instruction or reason`;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
return null;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
function validateUatMode(params: UatResultSaveParams): string | null {
|
|
1151
|
+
const modes = new Set(params.checks.map((check) => check.mode));
|
|
1152
|
+
const hasHuman = params.checks.some((check) => check.result === "NEEDS-HUMAN");
|
|
1153
|
+
if (params.uatType === "artifact-driven" && hasHuman && params.verdict === "PASS") {
|
|
1154
|
+
return "artifact-driven UAT cannot PASS with human-only checks";
|
|
1155
|
+
}
|
|
1156
|
+
if (
|
|
1157
|
+
hasHuman &&
|
|
1158
|
+
params.verdict === "PASS" &&
|
|
1159
|
+
!["human-experience", "mixed", "live-runtime"].includes(params.uatType) &&
|
|
1160
|
+
!params.checks.every((check) => check.result !== "NEEDS-HUMAN" || check.nonAutomatable === true)
|
|
1161
|
+
) {
|
|
1162
|
+
return "NEEDS-HUMAN checks can only coexist with PASS for human-experience, mixed, live-runtime, or explicitly non-automatable checks";
|
|
1163
|
+
}
|
|
1164
|
+
if (params.uatType === "runtime-executable" && !modes.has("runtime")) {
|
|
1165
|
+
return "runtime-executable UAT requires at least one runtime check";
|
|
1166
|
+
}
|
|
1167
|
+
if (params.uatType === "browser-executable" && !modes.has("browser")) {
|
|
1168
|
+
return "browser-executable UAT requires at least one browser check";
|
|
1169
|
+
}
|
|
1170
|
+
if (params.uatType === "live-runtime" && !modes.has("runtime") && !modes.has("browser")) {
|
|
1171
|
+
return "live-runtime UAT requires runtime or browser evidence";
|
|
1172
|
+
}
|
|
1173
|
+
return null;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
function quoteToolNames(toolNames: readonly string[]): string {
|
|
1177
|
+
return toolNames.map((toolName) => `"${toolName}"`).join(", ");
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
function validateCanonicalPresentation(params: UatResultSaveParams): string | null {
|
|
1181
|
+
const aliasHints: Record<string, string> = {
|
|
1182
|
+
gsd_save_summary: "gsd_summary_save",
|
|
1183
|
+
gsd_complete_task: "gsd_task_complete",
|
|
1184
|
+
gsd_complete_slice: "gsd_slice_complete",
|
|
1185
|
+
gsd_milestone_complete: "gsd_complete_milestone",
|
|
1186
|
+
};
|
|
1187
|
+
const errors: string[] = [];
|
|
1188
|
+
for (const toolName of params.presentation.presentedTools) {
|
|
1189
|
+
const baseName = parseMcpToolName(toolName)?.tool ?? toolName;
|
|
1190
|
+
const canonical = aliasHints[baseName];
|
|
1191
|
+
if (canonical) errors.push(`presentation tool "${toolName}" uses an alias; use canonical "${canonical}"`);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
const presentedCanonical = new Set(
|
|
1195
|
+
params.presentation.presentedTools.map((toolName) =>
|
|
1196
|
+
canonicalWorkflowToolName(parseMcpToolName(toolName)?.tool ?? toolName)
|
|
1197
|
+
),
|
|
1198
|
+
);
|
|
1199
|
+
const missingRequiredTools = RUN_UAT_WORKFLOW_TOOL_NAMES.filter(
|
|
1200
|
+
(requiredTool) => !presentedCanonical.has(requiredTool),
|
|
1201
|
+
);
|
|
1202
|
+
if (missingRequiredTools.length === 1) {
|
|
1203
|
+
errors.push(`presentation is missing required UAT tool "${missingRequiredTools[0]}"`);
|
|
1204
|
+
} else if (missingRequiredTools.length > 1) {
|
|
1205
|
+
errors.push(`presentation is missing required UAT tools ${quoteToolNames(missingRequiredTools)}`);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
const forbiddenCanonical = new Set(
|
|
1209
|
+
RUN_UAT_FORBIDDEN_TOOL_NAMES
|
|
1210
|
+
.filter((toolName) => !toolName.includes("*"))
|
|
1211
|
+
.map((toolName) => canonicalWorkflowToolName(parseMcpToolName(toolName)?.tool ?? toolName)),
|
|
1212
|
+
);
|
|
1213
|
+
const forbiddenPresentedTools: string[] = [];
|
|
1214
|
+
for (const toolName of params.presentation.presentedTools) {
|
|
1215
|
+
const canonical = canonicalWorkflowToolName(parseMcpToolName(toolName)?.tool ?? toolName);
|
|
1216
|
+
if (toolName === "mcp__gsd-workflow__*" || forbiddenCanonical.has(canonical)) {
|
|
1217
|
+
forbiddenPresentedTools.push(toolName);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
if (forbiddenPresentedTools.length === 1) {
|
|
1221
|
+
errors.push(`presentation includes forbidden run-uat tool "${forbiddenPresentedTools[0]}"`);
|
|
1222
|
+
} else if (forbiddenPresentedTools.length > 1) {
|
|
1223
|
+
errors.push(`presentation includes forbidden run-uat tools ${quoteToolNames(forbiddenPresentedTools)}`);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
const blockedCanonical = new Set(
|
|
1227
|
+
params.presentation.blockedTools.map((entry) =>
|
|
1228
|
+
canonicalWorkflowToolName(parseMcpToolName(entry.name)?.tool ?? entry.name)
|
|
1229
|
+
),
|
|
1230
|
+
);
|
|
1231
|
+
const missingBlockedTools = ["gsd_exec", "gsd_summary_save", "gsd_save_gate_result"].filter(
|
|
1232
|
+
(blockedTool) => !blockedCanonical.has(blockedTool),
|
|
1233
|
+
);
|
|
1234
|
+
if (missingBlockedTools.length === 1) {
|
|
1235
|
+
errors.push(`presentation must record "${missingBlockedTools[0]}" as blocked during run-uat`);
|
|
1236
|
+
} else if (missingBlockedTools.length > 1) {
|
|
1237
|
+
errors.push(`presentation must record ${quoteToolNames(missingBlockedTools)} as blocked during run-uat`);
|
|
1238
|
+
}
|
|
1239
|
+
return errors.length > 0 ? errors.join("; ") : null;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
function nextUatAttempt(basePath: string, milestoneId: string, sliceId: string): number {
|
|
1243
|
+
const contract = resolveGsdPathContract(basePath);
|
|
1244
|
+
const dir = join(contract.projectGsd, "uat", milestoneId, sliceId);
|
|
1245
|
+
if (!existsSync(dir)) return 1;
|
|
1246
|
+
let max = 0;
|
|
1247
|
+
for (const entry of readdirSync(dir)) {
|
|
1248
|
+
const match = /^attempt-(\d+)\.json$/.exec(entry);
|
|
1249
|
+
if (match) max = Math.max(max, Number(match[1]));
|
|
1250
|
+
}
|
|
1251
|
+
return max + 1;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
function escapeMarkdownTableCell(value: unknown): string {
|
|
1255
|
+
return String(value ?? "")
|
|
1256
|
+
.replace(/[\\|]/g, (char) => `\\${char}`)
|
|
1257
|
+
.replace(/\r?\n/g, "<br>");
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
function renderUatAssessment(params: UatResultSaveParams, attempt: number, gateVerdict: "pass" | "flag"): string {
|
|
1261
|
+
const lines = [
|
|
1262
|
+
"---",
|
|
1263
|
+
`sliceId: ${params.sliceId}`,
|
|
1264
|
+
`uatType: ${params.uatType}`,
|
|
1265
|
+
`verdict: ${params.verdict}`,
|
|
1266
|
+
`attempt: ${attempt}`,
|
|
1267
|
+
`date: ${new Date().toISOString()}`,
|
|
1268
|
+
"---",
|
|
1269
|
+
"",
|
|
1270
|
+
`# UAT Result - ${params.sliceId}`,
|
|
1271
|
+
"",
|
|
1272
|
+
"## Checks",
|
|
1273
|
+
"",
|
|
1274
|
+
"| Check | Mode | Result | Evidence | Notes |",
|
|
1275
|
+
"|-------|------|--------|----------|-------|",
|
|
1276
|
+
...params.checks.map((check) => {
|
|
1277
|
+
const evidence = (check.evidence ?? []).map((entry) => `${entry.kind}:${entry.ref}`).join("<br>") || "-";
|
|
1278
|
+
return `| ${escapeMarkdownTableCell(check.description)} | ${escapeMarkdownTableCell(check.mode)} | ${escapeMarkdownTableCell(check.result)} | ${escapeMarkdownTableCell(evidence)} | ${escapeMarkdownTableCell(check.notes)} |`;
|
|
1279
|
+
}),
|
|
1280
|
+
"",
|
|
1281
|
+
"## Overall Verdict",
|
|
1282
|
+
"",
|
|
1283
|
+
`${params.verdict} - ${params.notes ?? "UAT result saved."}`,
|
|
1284
|
+
"",
|
|
1285
|
+
"## Tool Presentation",
|
|
1286
|
+
"",
|
|
1287
|
+
"```json",
|
|
1288
|
+
JSON.stringify(params.presentation, null, 2),
|
|
1289
|
+
"```",
|
|
1290
|
+
"",
|
|
1291
|
+
"## Gate",
|
|
1292
|
+
"",
|
|
1293
|
+
`Aggregate UAT gate saved as ${gateVerdict}.`,
|
|
1294
|
+
];
|
|
1295
|
+
return `${lines.join("\n")}\n`;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
async function saveUatAttemptArtifact(basePath: string, params: UatResultSaveParams, attempt: number): Promise<string> {
|
|
1299
|
+
const contract = resolveGsdPathContract(basePath);
|
|
1300
|
+
const relativePath = `uat/${params.milestoneId}/${params.sliceId}/attempt-${attempt}.json`;
|
|
1301
|
+
await saveFile(join(contract.projectGsd, relativePath), `${JSON.stringify({ ...params, attempt }, null, 2)}\n`);
|
|
1302
|
+
return relativePath;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
export async function executeUatResultSave(
|
|
1306
|
+
params: UatResultSaveParams,
|
|
1307
|
+
basePath: string = process.cwd(),
|
|
1308
|
+
): Promise<ToolExecutionResult> {
|
|
1309
|
+
const dbAvailable = await ensureDbOpen(basePath);
|
|
1310
|
+
if (!dbAvailable) return errorResult("save_uat_result", "GSD database is not available.", "db_unavailable");
|
|
1311
|
+
|
|
1312
|
+
const requiredError = ensureUatRequiredFields(params);
|
|
1313
|
+
if (requiredError) return errorResult("save_uat_result", requiredError, "invalid_params");
|
|
1314
|
+
const presentationError = validateCanonicalPresentation(params);
|
|
1315
|
+
if (presentationError) return errorResult("save_uat_result", presentationError, "alias_tool_name");
|
|
1316
|
+
const checkError = validateUatChecks(basePath, params);
|
|
1317
|
+
if (checkError) return errorResult("save_uat_result", checkError, "invalid_evidence");
|
|
1318
|
+
const modeError = validateUatMode(params);
|
|
1319
|
+
if (modeError) return errorResult("save_uat_result", modeError, "uat_mode_mismatch");
|
|
1320
|
+
|
|
1321
|
+
try {
|
|
1322
|
+
const attempt = params.attempt === "auto" || params.attempt === undefined
|
|
1323
|
+
? nextUatAttempt(basePath, params.milestoneId, params.sliceId)
|
|
1324
|
+
: typeof params.attempt === "string"
|
|
1325
|
+
? Number.parseInt(params.attempt, 10)
|
|
1326
|
+
: params.attempt;
|
|
1327
|
+
if (!Number.isInteger(attempt) || attempt < 1) {
|
|
1328
|
+
return errorResult("save_uat_result", "attempt must be a positive integer or auto", "invalid_attempt");
|
|
1329
|
+
}
|
|
1330
|
+
const gateVerdict = params.verdict === "PASS" ? "pass" : "flag";
|
|
1331
|
+
const rationale = params.notes ?? `UAT ${params.verdict} for ${params.sliceId}.`;
|
|
1332
|
+
const assessment = renderUatAssessment(params, attempt, gateVerdict);
|
|
1333
|
+
const summary = await executeSummarySave(
|
|
1334
|
+
{
|
|
1335
|
+
milestone_id: params.milestoneId,
|
|
1336
|
+
slice_id: params.sliceId,
|
|
1337
|
+
artifact_type: "ASSESSMENT",
|
|
1338
|
+
content: assessment,
|
|
1339
|
+
},
|
|
1340
|
+
basePath,
|
|
1341
|
+
);
|
|
1342
|
+
if (summary.isError) return summary;
|
|
1343
|
+
const attemptPath = await saveUatAttemptArtifact(basePath, params, attempt);
|
|
1344
|
+
const evaluatedAt = new Date().toISOString();
|
|
1345
|
+
upsertQualityGate({
|
|
1346
|
+
milestoneId: params.milestoneId,
|
|
1347
|
+
sliceId: params.sliceId,
|
|
1348
|
+
gateId: "UAT",
|
|
1349
|
+
scope: "slice",
|
|
1350
|
+
taskId: "",
|
|
1351
|
+
status: "complete",
|
|
1352
|
+
verdict: gateVerdict,
|
|
1353
|
+
rationale,
|
|
1354
|
+
findings: assessment,
|
|
1355
|
+
evaluatedAt,
|
|
1356
|
+
});
|
|
1357
|
+
insertGateRun({
|
|
1358
|
+
traceId: `uat:${params.milestoneId}:${params.sliceId}`,
|
|
1359
|
+
turnId: `uat:${params.sliceId}:attempt-${attempt}`,
|
|
1360
|
+
gateId: "UAT",
|
|
1361
|
+
gateType: "uat",
|
|
1362
|
+
unitType: "run-uat",
|
|
1363
|
+
unitId: `run-uat:${params.milestoneId}/${params.sliceId}`,
|
|
1364
|
+
milestoneId: params.milestoneId,
|
|
1365
|
+
sliceId: params.sliceId,
|
|
1366
|
+
outcome: params.verdict === "PASS" ? "pass" : "fail",
|
|
1367
|
+
failureClass: params.verdict === "PASS" ? "none" : "verification",
|
|
1368
|
+
rationale,
|
|
1369
|
+
findings: assessment,
|
|
1370
|
+
attempt,
|
|
1371
|
+
maxAttempts: attempt,
|
|
1372
|
+
retryable: params.verdict !== "PASS",
|
|
1373
|
+
evaluatedAt,
|
|
1374
|
+
});
|
|
1375
|
+
invalidateStateCache();
|
|
1376
|
+
return {
|
|
1377
|
+
content: [{ type: "text", text: `UAT result saved for ${params.milestoneId}/${params.sliceId}: ${params.verdict}` }],
|
|
1378
|
+
details: {
|
|
1379
|
+
operation: "save_uat_result",
|
|
1380
|
+
milestoneId: params.milestoneId,
|
|
1381
|
+
sliceId: params.sliceId,
|
|
1382
|
+
verdict: params.verdict,
|
|
1383
|
+
gateVerdict,
|
|
1384
|
+
attempt,
|
|
1385
|
+
attemptPath,
|
|
1386
|
+
recommendedNextUnit: params.verdict === "PASS" ? null : "reactive-execute",
|
|
1387
|
+
},
|
|
1388
|
+
};
|
|
1389
|
+
} catch (err) {
|
|
1390
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1391
|
+
logError("tool", `gsd_uat_result_save failed: ${msg}`, { tool: "gsd_uat_result_save", error: String(err) });
|
|
1392
|
+
return errorResult("save_uat_result", `saving UAT result failed: ${msg}`, msg);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
910
1396
|
export async function executePlanMilestone(
|
|
911
1397
|
params: PlanMilestoneExecutorParams,
|
|
912
1398
|
basePath: string = process.cwd(),
|
|
@@ -270,6 +270,29 @@ export interface GSDActiveUnit {
|
|
|
270
270
|
|
|
271
271
|
// ─── Post-Unit Hook Types ─────────────────────────────────────────────────
|
|
272
272
|
|
|
273
|
+
export type PostUnitHookCriticality = "advisory" | "blocking";
|
|
274
|
+
|
|
275
|
+
export type PostUnitHookOutcomeVerdict =
|
|
276
|
+
| "pass"
|
|
277
|
+
| "advisory"
|
|
278
|
+
| "needs-rework"
|
|
279
|
+
| "needs-remediation"
|
|
280
|
+
| "needs-attention";
|
|
281
|
+
|
|
282
|
+
export type PostUnitHookOnBlockAction =
|
|
283
|
+
| "retry-unit"
|
|
284
|
+
| "retry-task"
|
|
285
|
+
| "queue-task"
|
|
286
|
+
| "queue-slice"
|
|
287
|
+
| "pause";
|
|
288
|
+
|
|
289
|
+
export interface PostUnitHookOnBlockConfig {
|
|
290
|
+
/** Routing action for blocking hook findings. */
|
|
291
|
+
action: PostUnitHookOnBlockAction;
|
|
292
|
+
/** Optional artifact used by compatibility retry routing. */
|
|
293
|
+
artifact?: string;
|
|
294
|
+
}
|
|
295
|
+
|
|
273
296
|
export interface PostUnitHookConfig {
|
|
274
297
|
/** Unique hook identifier — used in idempotency keys and logging. */
|
|
275
298
|
name: string;
|
|
@@ -283,8 +306,12 @@ export interface PostUnitHookConfig {
|
|
|
283
306
|
model?: string;
|
|
284
307
|
/** Expected output file name (relative to task/slice dir). Used for idempotency — skip if exists. */
|
|
285
308
|
artifact?: string;
|
|
309
|
+
/** Whether the hook is advisory or blocks unit advancement. Default advisory. */
|
|
310
|
+
criticality?: PostUnitHookCriticality;
|
|
286
311
|
/** If this file is produced instead of artifact, re-run the trigger unit then re-run hooks. */
|
|
287
312
|
retry_on?: string;
|
|
313
|
+
/** Optional routing for blocking findings. */
|
|
314
|
+
on_block?: PostUnitHookOnBlockConfig;
|
|
288
315
|
/** Agent definition file to use. */
|
|
289
316
|
agent?: string;
|
|
290
317
|
/** Set false to disable without removing config. Default true. */
|
|
@@ -317,6 +344,31 @@ export interface HookDispatchResult {
|
|
|
317
344
|
unitId: string;
|
|
318
345
|
}
|
|
319
346
|
|
|
347
|
+
export interface PostUnitGateBlock {
|
|
348
|
+
/** Blocking hook name. */
|
|
349
|
+
hookName: string;
|
|
350
|
+
/** The unit type that triggered the gate. */
|
|
351
|
+
triggerUnitType: string;
|
|
352
|
+
/** The unit ID that triggered the gate. */
|
|
353
|
+
triggerUnitId: string;
|
|
354
|
+
/** Gate artifact name, when configured. */
|
|
355
|
+
artifact?: string;
|
|
356
|
+
/** Absolute path to the gate artifact, when known. */
|
|
357
|
+
artifactPath?: string;
|
|
358
|
+
/** Parsed blocking verdict, when present. */
|
|
359
|
+
verdict?: PostUnitHookOutcomeVerdict | "failed";
|
|
360
|
+
/** Configured routing action that caused the pause. */
|
|
361
|
+
action: PostUnitHookOnBlockAction;
|
|
362
|
+
/** Human-readable pause reason. */
|
|
363
|
+
reason: string;
|
|
364
|
+
/** Current hook cycle count. */
|
|
365
|
+
cycle: number;
|
|
366
|
+
/** Configured max cycle count. */
|
|
367
|
+
maxCycles: number;
|
|
368
|
+
/** Optional compatibility retry artifact. */
|
|
369
|
+
retryArtifact?: string;
|
|
370
|
+
}
|
|
371
|
+
|
|
320
372
|
// ─── Budget & Notification Types ──────────────────────────────────────────
|
|
321
373
|
|
|
322
374
|
export type BudgetEnforcementMode = "warn" | "pause" | "halt";
|
|
@@ -384,10 +436,10 @@ export interface EscalationArtifact {
|
|
|
384
436
|
/** Why the executor recommends that option (1-2 sentences). */
|
|
385
437
|
recommendationRationale: string;
|
|
386
438
|
/**
|
|
387
|
-
* When true, the
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
439
|
+
* When true, the recommendation is recorded as the default path but the
|
|
440
|
+
* loop still pauses until the user explicitly resolves the escalation.
|
|
441
|
+
* When false, auto-mode also pauses until the user resolves via
|
|
442
|
+
* `/gsd escalate resolve`.
|
|
391
443
|
*/
|
|
392
444
|
continueWithDefault: boolean;
|
|
393
445
|
createdAt: string;
|
|
@@ -452,6 +504,15 @@ export interface PreDispatchResult {
|
|
|
452
504
|
export interface PersistedHookState {
|
|
453
505
|
/** Cycle counts keyed as "hookName/triggerUnitType/triggerUnitId". */
|
|
454
506
|
cycleCounts: Record<string, number>;
|
|
507
|
+
/** In-flight hook, persisted so blocking gates cannot be skipped after resume. */
|
|
508
|
+
activeHook?: HookExecutionState | null;
|
|
509
|
+
/** Remaining hook queue by hook name and trigger unit. */
|
|
510
|
+
hookQueue?: Array<{
|
|
511
|
+
hookName: string;
|
|
512
|
+
triggerUnitType: string;
|
|
513
|
+
triggerUnitId: string;
|
|
514
|
+
forceRun?: boolean;
|
|
515
|
+
}>;
|
|
455
516
|
/** Timestamp of last state save. */
|
|
456
517
|
savedAt: string;
|
|
457
518
|
}
|
|
@@ -465,6 +526,8 @@ export interface HookStatusEntry {
|
|
|
465
526
|
enabled: boolean;
|
|
466
527
|
/** What unit types it targets. */
|
|
467
528
|
targets: string[];
|
|
529
|
+
/** Whether this post-unit hook is advisory or blocking. */
|
|
530
|
+
criticality?: PostUnitHookCriticality;
|
|
468
531
|
/** Current cycle counts for active triggers. */
|
|
469
532
|
activeCycles: Record<string, number>;
|
|
470
533
|
}
|
|
@@ -644,7 +707,8 @@ export interface CompleteSliceParams {
|
|
|
644
707
|
sliceTitle: string;
|
|
645
708
|
oneLiner: string;
|
|
646
709
|
narrative: string;
|
|
647
|
-
verification
|
|
710
|
+
/** @optional — if omitted, verification section is left blank in summary */
|
|
711
|
+
verification?: string;
|
|
648
712
|
uatContent: string;
|
|
649
713
|
/** @optional — defaults to [] when omitted by models with limited tool-calling */
|
|
650
714
|
keyFiles?: string[];
|