@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0
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-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/bg-shell/utilities.js +2 -2
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +142 -15
- package/dist/resources/extensions/gsd/auto/phases.js +34 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +12 -9
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -36
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
- package/dist/resources/extensions/gsd/auto.js +15 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
- package/dist/resources/extensions/gsd/captures.js +5 -13
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +372 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +8 -10
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
- package/dist/resources/extensions/gsd/guided-flow.js +68 -471
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +19 -11
- package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/paths.js +10 -24
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +161 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +12 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +287 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +17 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- 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/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/dist/worktree-status-banner.js +7 -3
- package/package.json +2 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- 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 +3 -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.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +32 -22
- 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/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +295 -98
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +309 -154
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +87 -24
- package/src/resources/extensions/bg-shell/utilities.ts +2 -2
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
- package/src/resources/extensions/gsd/auto/phases.ts +45 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +16 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
- package/src/resources/extensions/gsd/auto-start.ts +25 -34
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
- package/src/resources/extensions/gsd/auto.ts +27 -17
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
- package/src/resources/extensions/gsd/captures.ts +5 -14
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +453 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +8 -11
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
- package/src/resources/extensions/gsd/guided-flow.ts +81 -561
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +17 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/paths.ts +9 -22
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +191 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +14 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +444 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +308 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +17 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/src/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Resolve how workflow units should ask the user for input.
|
|
3
|
+
import { parseMcpToolName, toMcpToolName } from "./mcp-tool-name.js";
|
|
4
|
+
function isWorkflowMcpServerName(serverName) {
|
|
5
|
+
const normalized = serverName.toLowerCase();
|
|
6
|
+
return normalized === "gsd" || normalized.includes("workflow");
|
|
7
|
+
}
|
|
8
|
+
export function usesWorkflowMcpTransport(authMode, baseUrl) {
|
|
9
|
+
return authMode === "externalCli" && typeof baseUrl === "string" && baseUrl.startsWith("local://");
|
|
10
|
+
}
|
|
11
|
+
export function hasAskUserQuestionsTool(activeTools) {
|
|
12
|
+
return activeTools.some((toolName) => {
|
|
13
|
+
if (toolName === "ask_user_questions")
|
|
14
|
+
return true;
|
|
15
|
+
const mcp = parseMcpToolName(toolName);
|
|
16
|
+
if (!mcp)
|
|
17
|
+
return false;
|
|
18
|
+
if (mcp.toolName === "ask_user_questions")
|
|
19
|
+
return true;
|
|
20
|
+
return mcp.toolName === "*" && isWorkflowMcpServerName(mcp.serverName);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function workflowMcpStructuredQuestionsEnabled(env = process.env) {
|
|
24
|
+
const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS?.trim().toLowerCase();
|
|
25
|
+
return value !== "0" && value !== "false" && value !== "off";
|
|
26
|
+
}
|
|
27
|
+
export function resolveQuestionTransport(options) {
|
|
28
|
+
const questionToolAvailable = hasAskUserQuestionsTool(options.activeTools);
|
|
29
|
+
const usesWorkflowMcp = usesWorkflowMcpTransport(options.authMode, options.baseUrl);
|
|
30
|
+
if (!questionToolAvailable) {
|
|
31
|
+
return {
|
|
32
|
+
structuredQuestionsAvailable: "false",
|
|
33
|
+
questionToolAvailable,
|
|
34
|
+
usesWorkflowMcp,
|
|
35
|
+
reason: "question-tool-missing",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (options.authMode === "externalCli" && !workflowMcpStructuredQuestionsEnabled(options.env)) {
|
|
39
|
+
return {
|
|
40
|
+
structuredQuestionsAvailable: "false",
|
|
41
|
+
questionToolAvailable,
|
|
42
|
+
usesWorkflowMcp,
|
|
43
|
+
reason: "workflow-mcp-disabled",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
structuredQuestionsAvailable: "true",
|
|
48
|
+
questionToolAvailable,
|
|
49
|
+
usesWorkflowMcp,
|
|
50
|
+
reason: "question-tool-available",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function supportsStructuredQuestions(activeTools, options = {}) {
|
|
54
|
+
return resolveQuestionTransport({
|
|
55
|
+
...options,
|
|
56
|
+
activeTools,
|
|
57
|
+
}).structuredQuestionsAvailable === "true";
|
|
58
|
+
}
|
|
59
|
+
export function resolveWorkflowQuestionToolSurface(options) {
|
|
60
|
+
const questionToolName = options.workflowServerName && !options.workflowExplicitlyBlocked
|
|
61
|
+
? toMcpToolName(options.workflowServerName, "ask_user_questions")
|
|
62
|
+
: undefined;
|
|
63
|
+
const activeTools = [
|
|
64
|
+
...options.exactWorkflowMcpTools,
|
|
65
|
+
...options.workflowMcpTools,
|
|
66
|
+
...(questionToolName ? [questionToolName] : []),
|
|
67
|
+
];
|
|
68
|
+
const transport = resolveQuestionTransport({
|
|
69
|
+
activeTools,
|
|
70
|
+
authMode: "externalCli",
|
|
71
|
+
baseUrl: "local://claude-code",
|
|
72
|
+
env: options.env,
|
|
73
|
+
});
|
|
74
|
+
const exactQuestionToolAllowed = !!questionToolName && options.exactWorkflowMcpTools.includes(questionToolName);
|
|
75
|
+
const workflowQuestionsEnabled = transport.structuredQuestionsAvailable === "true" &&
|
|
76
|
+
(options.workflowMcpTools.length > 0 || exactQuestionToolAllowed);
|
|
77
|
+
const disallowedTools = options.workflowServerName && transport.questionToolAvailable && !workflowQuestionsEnabled
|
|
78
|
+
? [toMcpToolName(options.workflowServerName, "ask_user_questions")]
|
|
79
|
+
: [];
|
|
80
|
+
return {
|
|
81
|
+
...transport,
|
|
82
|
+
questionToolName,
|
|
83
|
+
workflowQuestionsEnabled,
|
|
84
|
+
disallowedTools,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// File Purpose: ADR-015 Recovery Classification module for runtime failure taxonomy.
|
|
3
3
|
import { classifyError, isTransient } from "./error-classifier.js";
|
|
4
4
|
import { ReconciliationFailedError } from "./state-reconciliation.js";
|
|
5
|
+
import { IllegalPhaseTransitionError } from "./state-transition-matrix.js";
|
|
5
6
|
export function classifyFailure(input) {
|
|
6
7
|
const message = errorMessage(input.error);
|
|
7
8
|
// ADR-017: ReconciliationFailedError is a typed throw from the State
|
|
@@ -9,7 +10,9 @@ export function classifyFailure(input) {
|
|
|
9
10
|
// failureKind so the taxonomy stays consistent.
|
|
10
11
|
const failureKind = input.error instanceof ReconciliationFailedError
|
|
11
12
|
? "reconciliation-drift"
|
|
12
|
-
: input.
|
|
13
|
+
: input.error instanceof IllegalPhaseTransitionError
|
|
14
|
+
? "illegal-transition"
|
|
15
|
+
: input.failureKind ?? inferFailureKind(message);
|
|
13
16
|
switch (failureKind) {
|
|
14
17
|
case "tool-schema":
|
|
15
18
|
return {
|
|
@@ -75,6 +78,14 @@ export function classifyFailure(input) {
|
|
|
75
78
|
exitReason: "reconciliation-drift",
|
|
76
79
|
remediation: "Inspect the persistent or repair-failed drift kinds reported by the State Reconciliation Module before resuming.",
|
|
77
80
|
};
|
|
81
|
+
case "illegal-transition":
|
|
82
|
+
return {
|
|
83
|
+
failureKind,
|
|
84
|
+
action: "escalate",
|
|
85
|
+
reason: `Illegal phase transition${unitSuffix(input)}: ${message}`,
|
|
86
|
+
exitReason: "illegal-transition",
|
|
87
|
+
remediation: "A derived Phase edge rejected by the Phase Transition Invariant survived reconciliation; inspect deriveState and the State Reconciliation Module before resuming.",
|
|
88
|
+
};
|
|
78
89
|
case "provider": {
|
|
79
90
|
const providerClass = classifyError(message, input.retryAfterMs);
|
|
80
91
|
return {
|
|
@@ -191,9 +191,15 @@ export function parseRoadmapSlices(content) {
|
|
|
191
191
|
const riskMatch = rest.match(/`risk:(\w+)`/);
|
|
192
192
|
const risk = (riskMatch ? riskMatch[1] : "low");
|
|
193
193
|
const depsMatch = rest.match(/`depends:\[([^\]]*)\]`/);
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
// Recovery fallback: double-bracket form `[[id]]` from serialized bracket-wrapped IDs
|
|
195
|
+
const fallbackDepsMatch = depsMatch ? null : rest.match(/`depends:\[(\[(?:[^\]]*)\](?:,\[(?:[^\]]*)\])*)\]`/);
|
|
196
|
+
const rawDepContent = (depsMatch ?? fallbackDepsMatch)?.[1] ?? "";
|
|
197
|
+
const SLICE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
|
|
198
|
+
const RANGE_RE = /^[A-Za-z]+\d+(?:-|\.\.)[A-Za-z]+\d+$/;
|
|
199
|
+
const rawDepParts = rawDepContent.trim()
|
|
200
|
+
? rawDepContent.replace(/\[|\]/g, "").split(",").map(s => s.trim()).filter(s => SLICE_ID_RE.test(s) || RANGE_RE.test(s))
|
|
196
201
|
: [];
|
|
202
|
+
const depends = expandDependencies(rawDepParts);
|
|
197
203
|
// ADR-011: the renderer writes a `[sketch]` badge for sketch slices.
|
|
198
204
|
// Parse it back so the is_sketch flag survives a markdown → DB re-import
|
|
199
205
|
// (e.g. /gsd recover); otherwise the flag was silently lost.
|
|
@@ -21,9 +21,10 @@ const EXECUTION_TOOL_NAMES = new Set([
|
|
|
21
21
|
"functions.exec_command",
|
|
22
22
|
"gsd_exec",
|
|
23
23
|
"gsd_exec_search",
|
|
24
|
+
"gsd_uat_exec",
|
|
24
25
|
"powershell",
|
|
25
26
|
]);
|
|
26
|
-
const MCP_EXECUTION_TOOL_RE = /^mcp__.+
|
|
27
|
+
const MCP_EXECUTION_TOOL_RE = /^mcp__.+__gsd_(?:uat_)?exec(?:_search)?$/;
|
|
27
28
|
// ─── Module State ───────────────────────────────────────────────────────────
|
|
28
29
|
let unitEvidence = [];
|
|
29
30
|
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
@@ -146,11 +147,18 @@ export function clearEvidenceFromDisk(basePath, milestoneId, sliceId, taskId) {
|
|
|
146
147
|
* Exit codes and output are filled in by recordToolResult after execution.
|
|
147
148
|
*/
|
|
148
149
|
export function recordToolCall(toolCallId, toolName, input) {
|
|
150
|
+
// Idempotent by toolCallId: native tools reach this via both
|
|
151
|
+
// tool_execution_start and tool_call; external (pre-executed) tools only
|
|
152
|
+
// via tool_execution_start. First recording wins.
|
|
153
|
+
if (unitEvidence.some(e => e.toolCallId === toolCallId))
|
|
154
|
+
return;
|
|
149
155
|
if (isExecutionToolName(toolName)) {
|
|
150
156
|
unitEvidence.push({
|
|
151
157
|
kind: "bash",
|
|
152
158
|
toolCallId,
|
|
153
|
-
|
|
159
|
+
// gsd_exec / gsd_uat_exec carry the script body in `script` (or `code`);
|
|
160
|
+
// bash-style tools use `command`/`cmd`; gsd_exec_search uses `query`.
|
|
161
|
+
command: String(input.command ?? input.script ?? input.cmd ?? input.code ?? input.query ?? ""),
|
|
154
162
|
exitCode: -1,
|
|
155
163
|
outputSnippet: "",
|
|
156
164
|
timestamp: Date.now(),
|
|
@@ -185,9 +193,34 @@ export function recordToolResult(toolCallId, toolName, result, isError) {
|
|
|
185
193
|
if (entry.kind === "bash") {
|
|
186
194
|
const text = extractResultText(result);
|
|
187
195
|
entry.outputSnippet = text.slice(0, 500);
|
|
188
|
-
|
|
189
|
-
|
|
196
|
+
entry.exitCode = resolveExitCode(text, isError);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Resolve the exit code from a tool result's text. Handles the bash tool's
|
|
201
|
+
* prose marker, the gsd_exec / gsd_uat_exec JSON envelope (`"exit_code": N`),
|
|
202
|
+
* and a last-resort read of the run's persisted `.gsd/exec/<id>.meta.json`
|
|
203
|
+
* (covers truncated result text).
|
|
204
|
+
*/
|
|
205
|
+
function resolveExitCode(text, isError) {
|
|
206
|
+
const proseMatch = text.match(/Command exited with code (\d+)/);
|
|
207
|
+
if (proseMatch)
|
|
208
|
+
return Number(proseMatch[1]);
|
|
209
|
+
const jsonMatch = text.match(/"exit_code"\s*:\s*(-?\d+)/);
|
|
210
|
+
if (jsonMatch)
|
|
211
|
+
return Number(jsonMatch[1]);
|
|
212
|
+
const metaMatch = text.match(/"meta_path"\s*:\s*"([^"]+)"/);
|
|
213
|
+
if (metaMatch) {
|
|
214
|
+
try {
|
|
215
|
+
const meta = JSON.parse(readFileSync(metaMatch[1], "utf-8"));
|
|
216
|
+
if (typeof meta.exit_code === "number")
|
|
217
|
+
return meta.exit_code;
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// Fall through to the isError heuristic
|
|
221
|
+
}
|
|
190
222
|
}
|
|
223
|
+
return isError ? 1 : 0;
|
|
191
224
|
}
|
|
192
225
|
// ─── Internals ──────────────────────────────────────────────────────────────
|
|
193
226
|
function extractResultText(result) {
|
|
@@ -80,8 +80,13 @@ function findMatches(claimedCommand, bashCalls) {
|
|
|
80
80
|
const exact = bashCalls.filter(b => b.command.trim() === normalized);
|
|
81
81
|
if (exact.length > 0)
|
|
82
82
|
return exact;
|
|
83
|
-
// Substring match: claimed is contained in actual or actual in claimed
|
|
84
|
-
|
|
83
|
+
// Substring match: claimed is contained in actual or actual in claimed.
|
|
84
|
+
// A claimed verification command typically appears verbatim inside a
|
|
85
|
+
// larger gsd_exec script body (cd prefix, multi-line scripts), so
|
|
86
|
+
// script-containing-claim is the common direction. Blank-command entries
|
|
87
|
+
// must be excluded — `"x".includes("")` is true, so they'd match anything.
|
|
88
|
+
const substring = bashCalls.filter(b => b.command.trim().length > 0 &&
|
|
89
|
+
(b.command.includes(normalized) || normalized.includes(b.command)));
|
|
85
90
|
if (substring.length > 0)
|
|
86
91
|
return substring;
|
|
87
92
|
// Token match: split on whitespace and check significant overlap
|
|
@@ -17,6 +17,16 @@ import { logWarning } from "../workflow-logger.js";
|
|
|
17
17
|
const _require = createRequire(import.meta.url);
|
|
18
18
|
const picomatch = _require("picomatch");
|
|
19
19
|
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Build the effective allowlist for a unit's file-change audit.
|
|
22
|
+
*
|
|
23
|
+
* When GSD manages .gitignore (manage_gitignore unset or true), ensureGitignore()
|
|
24
|
+
* appends baseline patterns at auto-start and the edit rides into the task's
|
|
25
|
+
* auto-commit — so .gitignore changes must not be attributed to the task.
|
|
26
|
+
*/
|
|
27
|
+
export function effectiveFileChangeAllowlist(baseAllowlist, manageGitignore) {
|
|
28
|
+
return manageGitignore === false ? baseAllowlist : [...baseAllowlist, ".gitignore"];
|
|
29
|
+
}
|
|
20
30
|
/**
|
|
21
31
|
* Validate file changes after auto-commit for an execute-task unit.
|
|
22
32
|
* Returns null if task data is unavailable or DB is not loaded.
|
|
@@ -19,7 +19,8 @@ import { isAbsolute, join, dirname, resolve } from "node:path";
|
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
20
|
import { gsdRoot } from "./paths.js";
|
|
21
21
|
import { createWorktree, worktreePath, removeWorktree } from "./worktree-manager.js";
|
|
22
|
-
import { runWorktreePostCreateHook,
|
|
22
|
+
import { runWorktreePostCreateHook, syncGsdStateToWorktreeByScope } from "./auto-worktree.js";
|
|
23
|
+
import { createWorkspace, scopeMilestone } from "./workspace.js";
|
|
23
24
|
import { writeSessionStatus, } from "./session-status-io.js";
|
|
24
25
|
import { hasFileConflict } from "./slice-parallel-conflict.js";
|
|
25
26
|
import { getErrorMessage } from "./error-utils.js";
|
|
@@ -108,7 +109,7 @@ function createSliceWorktree(basePath, milestoneId, sliceId) {
|
|
|
108
109
|
if (hookError) {
|
|
109
110
|
throw new Error(`slice worktree post-create hook failed (${wtName}): ${hookError}`);
|
|
110
111
|
}
|
|
111
|
-
|
|
112
|
+
syncGsdStateToWorktreeByScope(scopeMilestone(createWorkspace(basePath), milestoneId), scopeMilestone(createWorkspace(wtPath), milestoneId));
|
|
112
113
|
if (!existsSync(join(wtPath, ".gsd"))) {
|
|
113
114
|
throw new Error(`slice worktree preflight failed (${wtName}): missing .gsd in worktree`);
|
|
114
115
|
}
|
|
@@ -99,6 +99,44 @@ export const STATE_TRANSITION_MATRIX = [
|
|
|
99
99
|
export function findTransition(from, event) {
|
|
100
100
|
return STATE_TRANSITION_MATRIX.find((entry) => (entry.from === from || entry.from === "*") && entry.event === event);
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Edge-keyed legality check for the Phase Transition Invariant (ADR-030).
|
|
104
|
+
* `advance()` derives the next Phase and asserts the (from → to) edge here.
|
|
105
|
+
*
|
|
106
|
+
* The matrix is an assertion, not a decision-maker — `deriveState` already
|
|
107
|
+
* chose the Phase. A self-edge is trivially legal (no transition to assert). An
|
|
108
|
+
* edge is legal when some matrix entry permits it, honoring the `*` wildcard
|
|
109
|
+
* rows (e.g. any → blocked via manual-block, any → executing via
|
|
110
|
+
* retryable-failure).
|
|
111
|
+
*
|
|
112
|
+
* Note: the matrix is currently a sparse hardening spec, not a complete
|
|
113
|
+
* legal-edge graph, so `advance()` consumes this in advisory mode (telemetry
|
|
114
|
+
* only). It must be expanded to cover every edge `deriveState` emits before
|
|
115
|
+
* enforcement flips on.
|
|
116
|
+
*/
|
|
117
|
+
export function isLegalEdge(from, to) {
|
|
118
|
+
if (from === to)
|
|
119
|
+
return true;
|
|
120
|
+
return STATE_TRANSITION_MATRIX.some((entry) => (entry.from === from || entry.from === "*") && entry.to === to);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Thrown when an illegal derived Phase edge survives reconciliation. Carries
|
|
124
|
+
* both endpoints so Recovery Classification can report them. Recognized by
|
|
125
|
+
* class in `classifyFailure` and mapped to the `illegal-transition` kind.
|
|
126
|
+
*/
|
|
127
|
+
export class IllegalPhaseTransitionError extends Error {
|
|
128
|
+
// Explicit fields, not constructor parameter properties — strip-types
|
|
129
|
+
// consumers (workspace-index subprocess, integration tests) reject the
|
|
130
|
+
// parameter-property syntax with ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX.
|
|
131
|
+
from;
|
|
132
|
+
to;
|
|
133
|
+
constructor(from, to) {
|
|
134
|
+
super(`Illegal phase transition ${from} -> ${to} survived reconciliation`);
|
|
135
|
+
this.name = "IllegalPhaseTransitionError";
|
|
136
|
+
this.from = from;
|
|
137
|
+
this.to = to;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
102
140
|
export function validateTransitionMatrix(requiredEvents) {
|
|
103
141
|
const seen = new Set();
|
|
104
142
|
const duplicateKeys = [];
|
|
@@ -18,8 +18,10 @@ import { logWarning } from './workflow-logger.js';
|
|
|
18
18
|
import { extractVerdict } from './verdict-parser.js';
|
|
19
19
|
import { detectPendingEscalation } from './escalation.js';
|
|
20
20
|
import { isTerminalMilestoneSummaryContent } from './milestone-summary-classifier.js';
|
|
21
|
-
import { isDbAvailable,
|
|
21
|
+
import { isDbAvailable, getAllMilestones, getMilestone, getMilestoneSlices, getSliceTasks, getReplanHistory, getSlice, getRequirementCounts, getLatestAssessmentByScope, getPendingGateCountForTurn, } from './gsd-db.js';
|
|
22
|
+
import { wasWorkflowDatabaseOpenAttempted } from './db-workspace.js';
|
|
22
23
|
import { formatCompletePhaseNextAction, countUnmappedActiveRequirements } from './requirements-backlog.js';
|
|
24
|
+
import { classifyMilestoneReadiness, readinessNeedsDiscussion, } from './milestone-readiness.js';
|
|
23
25
|
function formatNeedsAttentionBlocker(milestoneId) {
|
|
24
26
|
return [
|
|
25
27
|
`Milestone ${milestoneId} is blocked because milestone validation returned needs-attention.`,
|
|
@@ -301,7 +303,7 @@ export async function deriveState(basePath, opts) {
|
|
|
301
303
|
_telemetry.dbDeriveCount++;
|
|
302
304
|
}
|
|
303
305
|
else {
|
|
304
|
-
if (
|
|
306
|
+
if (wasWorkflowDatabaseOpenAttempted()) {
|
|
305
307
|
logWarning("state", "DB unavailable — refusing implicit markdown state derivation");
|
|
306
308
|
}
|
|
307
309
|
result = {
|
|
@@ -396,6 +398,12 @@ async function buildRegistryAndFindActive(basePath, milestones, completeMileston
|
|
|
396
398
|
const title = stripMilestonePrefix(m.title) || m.id;
|
|
397
399
|
const hasContext = !!resolveMilestoneFile(basePath, m.id, "CONTEXT");
|
|
398
400
|
const hasDraftContext = !hasContext && !!resolveMilestoneFile(basePath, m.id, "CONTEXT-DRAFT");
|
|
401
|
+
const readiness = classifyMilestoneReadiness({
|
|
402
|
+
status: m.status,
|
|
403
|
+
hasContext,
|
|
404
|
+
hasDraftContext,
|
|
405
|
+
sliceCount: slices.length,
|
|
406
|
+
});
|
|
399
407
|
if (!activeMilestoneFound) {
|
|
400
408
|
const deps = m.depends_on;
|
|
401
409
|
const depsUnmet = deps.some(dep => !completeMilestoneIds.has(dep));
|
|
@@ -403,9 +411,9 @@ async function buildRegistryAndFindActive(basePath, milestones, completeMileston
|
|
|
403
411
|
registry.push({ id: m.id, title, status: 'pending', dependsOn: deps });
|
|
404
412
|
continue;
|
|
405
413
|
}
|
|
406
|
-
if (
|
|
414
|
+
if (readiness.kind === 'queued-shell') {
|
|
407
415
|
if (!firstDeferredQueuedShell) {
|
|
408
|
-
firstDeferredQueuedShell = { id: m.id, title, deps, hasDraftContext };
|
|
416
|
+
firstDeferredQueuedShell = { id: m.id, title, deps, hasDraftContext: readiness.hasDraftContext };
|
|
409
417
|
}
|
|
410
418
|
registry.push({ id: m.id, title, status: 'pending', ...(deps.length > 0 ? { dependsOn: deps } : {}) });
|
|
411
419
|
continue;
|
|
@@ -417,7 +425,7 @@ async function buildRegistryAndFindActive(basePath, milestones, completeMileston
|
|
|
417
425
|
registry.push({ id: m.id, title, status: 'active', ...(deps.length > 0 ? { dependsOn: deps } : {}) });
|
|
418
426
|
continue;
|
|
419
427
|
}
|
|
420
|
-
if ((
|
|
428
|
+
if (readinessNeedsDiscussion(readiness))
|
|
421
429
|
activeMilestoneHasDraft = true;
|
|
422
430
|
activeMilestone = { id: m.id, title };
|
|
423
431
|
activeMilestoneSlices = slices;
|
|
@@ -1,16 +1,64 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Status predicates for GSD state-machine
|
|
2
|
+
* Status predicates and the canonical status vocabulary for GSD state-machine
|
|
3
|
+
* guards (ADR-030).
|
|
3
4
|
*
|
|
4
|
-
* The DB
|
|
5
|
-
*
|
|
6
|
-
* "closed" (legacy/imported), and
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* The DB column is free-form `string` so legacy/imported rows still load. Three
|
|
6
|
+
* raw values besides canonical "complete"/"skipped" indicate "closed": "done"
|
|
7
|
+
* (legacy alias), "closed" (legacy/imported), and "skipped" (user-directed skip
|
|
8
|
+
* via rethink or backtrack). `RAW_CLOSED_STATUSES` is the single source for both
|
|
9
|
+
* `isClosedStatus()` and the SQL terminal-status fragment
|
|
10
|
+
* (`db/sql-constants.ts` derives `TERMINAL_STATUS_SQL` from it), replacing the
|
|
11
|
+
* prior independent definitions.
|
|
12
|
+
*
|
|
13
|
+
* `toStatus()` is the single seam where a free-form string becomes the canonical
|
|
14
|
+
* `Status` vocabulary; the Status Transition Core writes canonical, so the store
|
|
15
|
+
* converges over time without a forced migration.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Canonical, normalized entity-status vocabulary across milestones, slices, and
|
|
19
|
+
* tasks — the single source for both the `Status` type and the runtime
|
|
20
|
+
* membership set. The in-memory domain speaks `Status`; the DB column stays
|
|
21
|
+
* free-form.
|
|
22
|
+
*/
|
|
23
|
+
export const CANONICAL_STATUSES = [
|
|
24
|
+
"pending", "queued", "active", "parked", "in_progress", "blocked", "complete", "skipped", "deferred",
|
|
25
|
+
];
|
|
26
|
+
const CANONICAL_STATUS_SET = new Set(CANONICAL_STATUSES);
|
|
27
|
+
/**
|
|
28
|
+
* Raw status values that mean a unit is closed — the single source of truth.
|
|
29
|
+
* Includes legacy/imported aliases ("done", "closed") alongside canonical
|
|
30
|
+
* "complete"/"skipped" because the DB column is free-form and older rows /
|
|
31
|
+
* imports still carry them. Order matters: `TERMINAL_STATUS_SQL` is derived
|
|
32
|
+
* from this array verbatim.
|
|
33
|
+
*/
|
|
34
|
+
export const RAW_CLOSED_STATUSES = ["complete", "done", "skipped", "closed"];
|
|
35
|
+
const RAW_CLOSED_SET = new Set(RAW_CLOSED_STATUSES);
|
|
36
|
+
/** Free-form aliases mapped to their canonical Status on read. */
|
|
37
|
+
const ALIAS_TO_CANONICAL = {
|
|
38
|
+
done: "complete",
|
|
39
|
+
closed: "complete",
|
|
40
|
+
planned: "pending",
|
|
41
|
+
"in-progress": "in_progress",
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a free-form DB status string into the canonical `Status`
|
|
45
|
+
* vocabulary. Maps known aliases (done/closed → complete, planned → pending,
|
|
46
|
+
* in-progress → in_progress). An unrecognized/legacy value is **quarantined** —
|
|
47
|
+
* preserved verbatim rather than silently remapped to a wrong canonical state —
|
|
48
|
+
* so reads never fail and reconciliation/telemetry can surface it.
|
|
10
49
|
*/
|
|
50
|
+
export function toStatus(raw) {
|
|
51
|
+
const value = raw.trim();
|
|
52
|
+
if (CANONICAL_STATUS_SET.has(value))
|
|
53
|
+
return value;
|
|
54
|
+
const alias = ALIAS_TO_CANONICAL[value];
|
|
55
|
+
if (alias)
|
|
56
|
+
return alias;
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
11
59
|
/** Returns true when a milestone, slice, or task status indicates closure. */
|
|
12
60
|
export function isClosedStatus(status) {
|
|
13
|
-
return status
|
|
61
|
+
return RAW_CLOSED_SET.has(status);
|
|
14
62
|
}
|
|
15
63
|
/** Returns true when a slice status indicates it was deferred by a decision. */
|
|
16
64
|
export function isDeferredStatus(status) {
|
|
@@ -46,6 +46,13 @@
|
|
|
46
46
|
For simple projects or scripts:
|
|
47
47
|
- Executable verification commands (bash assertions, curl checks, etc.) are sufficient
|
|
48
48
|
|
|
49
|
+
For browser-facing web apps (React, Next, Vue, Vite, static HTML, etc.):
|
|
50
|
+
- Prefer `npx playwright test <spec>` in Verification when `@playwright/test` exists
|
|
51
|
+
- If Playwright is not set up yet, the first UI slice should add `playwright.config.ts`,
|
|
52
|
+
a minimal smoke spec (for example `e2e/smoke.spec.ts`), and a safe verify command
|
|
53
|
+
- Slice closeout UAT must declare `browser-executable` or `runtime-executable` — not
|
|
54
|
+
`artifact-driven` — when checks navigate to localhost or exercise the live UI
|
|
55
|
+
|
|
49
56
|
If the project has no test framework and the work is non-trivial,
|
|
50
57
|
the first task should set one up. A test runner costs 2 minutes
|
|
51
58
|
and pays for itself immediately.
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
- **Complexity:** {{simple | complex}}
|
|
22
22
|
- **Why:** {{one-line rationale citing the signals that decided it}}
|
|
23
|
+
- **Web stack:** {{browser-facing framework or "not a web UI" — e.g. Next.js + Playwright, static HTML, N/A for CLI/API-only}}
|
|
23
24
|
|
|
24
25
|
## Current State
|
|
25
26
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
- Contract verification: {{tests / shell verifiers / fixtures / artifact checks}}
|
|
43
43
|
- Integration verification: {{real subsystem interaction that must be exercised, or none}}
|
|
44
44
|
- Operational verification: {{service lifecycle / restart / reconnect / supervision / deploy-install behavior, or none}}
|
|
45
|
-
- UAT / human verification: {{what needs real human judgment, or none}}
|
|
45
|
+
- UAT / human verification: {{what needs real human judgment, or none — for web apps prefer browser-executable / runtime-executable Playwright checks over deferring UI proof to humans}}
|
|
46
46
|
|
|
47
47
|
## Milestone Definition of Done
|
|
48
48
|
|
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
## UAT Type
|
|
7
7
|
|
|
8
|
-
- UAT mode: {{artifact-driven | live-runtime | human-experience | mixed}}
|
|
8
|
+
- UAT mode: {{artifact-driven | browser-executable | runtime-executable | live-runtime | human-experience | mixed}}
|
|
9
9
|
- Why this mode is sufficient: {{reason}}
|
|
10
10
|
|
|
11
|
+
<!-- Web apps: never use artifact-driven when steps open a browser, navigate to localhost,
|
|
12
|
+
or capture screenshots. Use browser-executable (browser_* tools) or runtime-executable
|
|
13
|
+
(npx playwright test). Name dev-server preconditions below. -->
|
|
14
|
+
|
|
11
15
|
## Preconditions
|
|
12
16
|
|
|
13
17
|
{{whatMustBeTrueBeforeTesting — server running, data seeded, etc.}}
|
|
@@ -4,6 +4,17 @@ import { resolveManifest, } from "./unit-context-manifest.js";
|
|
|
4
4
|
import { getRequiredWorkflowToolsForAutoUnit } from "./workflow-mcp.js";
|
|
5
5
|
import { getUnitToolSurfaceContract } from "./unit-tool-contracts.js";
|
|
6
6
|
import { WHOLE_FILE_OBSERVATION_MAX_BYTES, WHOLE_FILE_OBSERVATION_MAX_LINES, } from "./source-observations.js";
|
|
7
|
+
export function compileUnitContextContract(unitType) {
|
|
8
|
+
const manifest = resolveManifest(unitType);
|
|
9
|
+
if (!manifest) {
|
|
10
|
+
return {
|
|
11
|
+
ok: false,
|
|
12
|
+
reason: "unknown-unit-type",
|
|
13
|
+
detail: `No Unit manifest is registered for ${unitType}`,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return { ok: true, contract: buildPromptContextContract(unitType, manifest) };
|
|
17
|
+
}
|
|
7
18
|
export function compileUnitToolContract(unitType) {
|
|
8
19
|
const manifest = resolveManifest(unitType);
|
|
9
20
|
const surfaceContract = getUnitToolSurfaceContract(unitType);
|
|
@@ -25,6 +36,7 @@ export function compileUnitToolContract(unitType) {
|
|
|
25
36
|
detail: `${unitType} has no closeout workflow tool`,
|
|
26
37
|
};
|
|
27
38
|
}
|
|
39
|
+
const promptContext = buildPromptContextContract(unitType, manifest);
|
|
28
40
|
return {
|
|
29
41
|
ok: true,
|
|
30
42
|
contract: {
|
|
@@ -33,10 +45,8 @@ export function compileUnitToolContract(unitType) {
|
|
|
33
45
|
toolsPolicy: manifest.tools,
|
|
34
46
|
requiredWorkflowTools,
|
|
35
47
|
forbiddenWorkflowTools,
|
|
36
|
-
promptObligations:
|
|
37
|
-
|
|
38
|
-
`tools-policy:${manifest.tools.mode}`,
|
|
39
|
-
],
|
|
48
|
+
promptObligations: promptContext.obligations,
|
|
49
|
+
promptContext,
|
|
40
50
|
validationRules: [
|
|
41
51
|
"unit-manifest-present",
|
|
42
52
|
"workflow-tool-surface-present",
|
|
@@ -44,15 +54,49 @@ export function compileUnitToolContract(unitType) {
|
|
|
44
54
|
...(unitType === "execute-task" ? ["source-observation-contract-present"] : []),
|
|
45
55
|
],
|
|
46
56
|
closeoutTools,
|
|
47
|
-
sourceObservations:
|
|
57
|
+
sourceObservations: promptContext.sourceObservations,
|
|
48
58
|
artifacts: {
|
|
49
|
-
inline:
|
|
50
|
-
excerpt:
|
|
51
|
-
onDemand:
|
|
59
|
+
inline: promptContext.artifacts.inline,
|
|
60
|
+
excerpt: promptContext.artifacts.excerpt,
|
|
61
|
+
onDemand: promptContext.artifacts.onDemand,
|
|
52
62
|
},
|
|
53
63
|
},
|
|
54
64
|
};
|
|
55
65
|
}
|
|
66
|
+
function buildPromptContextContract(unitType, manifest) {
|
|
67
|
+
const sourceObservations = sourceObservationContractForUnit(unitType);
|
|
68
|
+
return {
|
|
69
|
+
unitType,
|
|
70
|
+
contextMode: manifest.contextMode,
|
|
71
|
+
toolsPolicy: manifest.tools,
|
|
72
|
+
obligations: promptContextObligations(manifest, sourceObservations),
|
|
73
|
+
sourceObservations,
|
|
74
|
+
artifacts: {
|
|
75
|
+
inline: manifest.artifacts.inline,
|
|
76
|
+
excerpt: manifest.artifacts.excerpt,
|
|
77
|
+
onDemand: manifest.artifacts.onDemand,
|
|
78
|
+
computed: manifest.artifacts.computed ?? [],
|
|
79
|
+
prepend: manifest.prepend ?? [],
|
|
80
|
+
},
|
|
81
|
+
maxSystemPromptChars: manifest.maxSystemPromptChars,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function promptContextObligations(manifest, sourceObservations) {
|
|
85
|
+
const obligations = [
|
|
86
|
+
`context-mode:${manifest.contextMode}`,
|
|
87
|
+
`tools-policy:${manifest.tools.mode}`,
|
|
88
|
+
artifactObligation("context-inline", manifest.artifacts.inline),
|
|
89
|
+
artifactObligation("context-excerpt", manifest.artifacts.excerpt),
|
|
90
|
+
artifactObligation("context-on-demand", manifest.artifacts.onDemand),
|
|
91
|
+
];
|
|
92
|
+
if (sourceObservations.mode !== "none") {
|
|
93
|
+
obligations.push(`source-observations:${sourceObservations.mode}`);
|
|
94
|
+
}
|
|
95
|
+
return obligations;
|
|
96
|
+
}
|
|
97
|
+
function artifactObligation(label, artifacts) {
|
|
98
|
+
return `${label}:${artifacts.length > 0 ? artifacts.join(",") : "none"}`;
|
|
99
|
+
}
|
|
56
100
|
function sourceObservationContractForUnit(unitType) {
|
|
57
101
|
if (unitType !== "execute-task")
|
|
58
102
|
return { mode: "none" };
|