@opengsd/gsd-pi 1.2.0-dev.b1abb545 → 1.2.0-dev.d6c5343c
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-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.js +2 -14
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +5 -2
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +94 -48
- package/dist/resources/extensions/gsd/auto/phases.js +8 -3
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +40 -57
- package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +31 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +24 -26
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +9 -28
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
- package/dist/resources/extensions/gsd/auto.js +8 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +5 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/consent-question.js +337 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +398 -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/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- 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 +171 -2048
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +51 -5
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
- package/dist/resources/extensions/gsd/milestone-closeout.js +13 -23
- 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/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +37 -24
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/preferences.js +14 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- 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/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +6 -20
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +44 -53
- package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- 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/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
- 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 +28 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/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/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/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 +8 -8
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- 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/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -11
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- 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/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- 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 +8 -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 +7 -0
- 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 +8 -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-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +6 -3
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +46 -21
- 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/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/models.generated.d.ts +192 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +166 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +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/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.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/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +5 -2
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +109 -51
- package/src/resources/extensions/gsd/auto/phases.ts +12 -3
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -32
- package/src/resources/extensions/gsd/auto-dispatch.ts +38 -52
- package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +37 -13
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +24 -29
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +8 -26
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
- package/src/resources/extensions/gsd/auto.ts +20 -24
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +5 -16
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/consent-question.ts +416 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +490 -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/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- 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 +173 -2373
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +50 -5
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
- package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
- package/src/resources/extensions/gsd/milestone-closeout.ts +13 -23
- 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/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +42 -22
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/preferences.ts +18 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- 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/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +9 -21
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +101 -26
- 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-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/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +336 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -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 +248 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -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 +43 -6
- 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/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- 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/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +43 -68
- package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- 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/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
- 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 +29 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/gsd-browser/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → jmTLg6xZmAuq_LIqKOxrH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → jmTLg6xZmAuq_LIqKOxrH}/_ssgManifest.js +0 -0
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
// the real collaborators (state-reconciliation, doctor-proactive,
|
|
10
10
|
// auto-dispatch, recovery-classification, tool-contract, worktree-safety,
|
|
11
11
|
// uok/gate-runner, journal, session-lock, ctx.ui.notify) directly.
|
|
12
|
-
import { debugCount, debugTime } from "../debug-logger.js";
|
|
12
|
+
import { debugCount, debugLog, debugTime } from "../debug-logger.js";
|
|
13
13
|
import { reconcileBeforeDispatch } from "../state-reconciliation.js";
|
|
14
|
+
import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
|
|
14
15
|
import { resolveDispatch } from "../auto-dispatch.js";
|
|
15
16
|
import { classifyFailure } from "../recovery-classification.js";
|
|
16
17
|
import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
|
|
@@ -24,7 +25,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
|
|
|
24
25
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
25
26
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
26
27
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
27
|
-
import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
|
|
28
|
+
import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
28
29
|
import { detectWorktreeName, getMainBranch, resolveProjectRoot, resolveWorktreeProjectRoot, } from "../worktree.js";
|
|
29
30
|
import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
|
|
30
31
|
import { GitServiceImpl } from "../git-service.js";
|
|
@@ -41,21 +42,14 @@ import { isDbAvailable, getSlice, getTask, } from "../gsd-db.js";
|
|
|
41
42
|
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
42
43
|
import { getErrorMessage } from "../error-utils.js";
|
|
43
44
|
import { logWarning } from "../workflow-logger.js";
|
|
45
|
+
import { normalizeRealPath } from "../paths.js";
|
|
46
|
+
import { buildDispatchKey, createDispatchHistory, STUCK_WINDOW_SIZE, } from "./dispatch-history.js";
|
|
44
47
|
import { existsSync, readFileSync } from "node:fs";
|
|
45
48
|
import { join } from "node:path";
|
|
46
49
|
import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
|
|
47
50
|
function now() {
|
|
48
51
|
return Date.now();
|
|
49
52
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Size of the dispatch-decision ring buffer used by the Auto Orchestration
|
|
52
|
-
* module's stuck-loop detector. When the same `${unitType}:${unitId}` key
|
|
53
|
-
* fills the window, advance() blocks with `action: "stop"`.
|
|
54
|
-
*
|
|
55
|
-
* Mirrors the legacy `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is
|
|
56
|
-
* preserved across the eventual cutover (issue #5791).
|
|
57
|
-
*/
|
|
58
|
-
export const STUCK_WINDOW_SIZE = 6;
|
|
59
53
|
function noRemainingUnitsOutcome(stateSnapshot) {
|
|
60
54
|
if (stateSnapshot.phase === "complete") {
|
|
61
55
|
return {
|
|
@@ -243,7 +237,13 @@ export class AutoOrchestrator {
|
|
|
243
237
|
seq = 0;
|
|
244
238
|
lastAdvanceKey = null;
|
|
245
239
|
lastFinalizedUnitKey = null;
|
|
246
|
-
|
|
240
|
+
// Dispatch History module (#482): the dispatch-decision window with
|
|
241
|
+
// cross-session DB rehydration and full detect-stuck rules.
|
|
242
|
+
dispatchHistory;
|
|
243
|
+
// ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
|
|
244
|
+
// the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
|
|
245
|
+
// so the first advance of a session has no edge to assert.
|
|
246
|
+
lastDerivedPhase = null;
|
|
247
247
|
// #442: the unit key we last attempted graduated stuck-recovery for. Bounds
|
|
248
248
|
// recovery to one attempt per stuck episode per run (reset on start/resume/
|
|
249
249
|
// stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
|
|
@@ -255,6 +255,13 @@ export class AutoOrchestrator {
|
|
|
255
255
|
this.runtimeBasePath = context.runtimeBasePath;
|
|
256
256
|
this.s = context.session;
|
|
257
257
|
this.flowId = `auto-orchestrator-${Date.now()}`;
|
|
258
|
+
this.dispatchHistory = createDispatchHistory({
|
|
259
|
+
windowSize: STUCK_WINDOW_SIZE,
|
|
260
|
+
// Same stable scope the auto-loop uses for stuck-state persistence so
|
|
261
|
+
// rehydration reads the rows the dispatch ledger wrote for this project.
|
|
262
|
+
resolveScopeId: () => normalizeRealPath(this.s.scope?.workspace.projectRoot ??
|
|
263
|
+
(this.s.originalBasePath || this.s.basePath || this.runtimeBasePath)) || null,
|
|
264
|
+
});
|
|
258
265
|
}
|
|
259
266
|
// ── Live base-path resolution (was the wiring factory's getLiveDispatchBasePath) ──
|
|
260
267
|
getLiveDispatchBasePath() {
|
|
@@ -476,8 +483,7 @@ export class AutoOrchestrator {
|
|
|
476
483
|
}
|
|
477
484
|
// ── WorktreeAdapter (folded) ─────────────────────────────────────────────
|
|
478
485
|
getEffectiveUnitIsolationMode(basePath) {
|
|
479
|
-
|
|
480
|
-
return configuredMode === "worktree" && this.s.isolationDegraded ? "branch" : configuredMode;
|
|
486
|
+
return resolveEffectiveUnitIsolationMode(getIsolationMode(basePath), this.s.isolationDegraded, this.s.strandedRecoveryIsolationMode);
|
|
481
487
|
}
|
|
482
488
|
buildLifecycle() {
|
|
483
489
|
return new WorktreeLifecycle(this.s, {
|
|
@@ -576,6 +582,21 @@ export class AutoOrchestrator {
|
|
|
576
582
|
const recovery = classifyFailure(input);
|
|
577
583
|
return { action: recovery.action, reason: recovery.reason };
|
|
578
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
|
|
587
|
+
* assertion, not a decision-maker — deriveState already chose the phase; we
|
|
588
|
+
* only observe illegal *derived* edges that survived reconciliation. The
|
|
589
|
+
* matrix is still a sparse hardening spec, so this is telemetry-only (no
|
|
590
|
+
* block) until it is expanded into a validated legal-edge graph. To enforce:
|
|
591
|
+
* `throw violation;` instead of logging — recovery-classification maps
|
|
592
|
+
* IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
|
|
593
|
+
*/
|
|
594
|
+
observePhaseTransition(from, to) {
|
|
595
|
+
if (isLegalEdge(from, to))
|
|
596
|
+
return;
|
|
597
|
+
const violation = new IllegalPhaseTransitionError(from, to);
|
|
598
|
+
debugLog("phase-transition-advisory", { from, to, message: violation.message });
|
|
599
|
+
}
|
|
579
600
|
// ── Lifecycle verbs ──────────────────────────────────────────────────────
|
|
580
601
|
/**
|
|
581
602
|
* #442: graduated stuck recovery, ported from the legacy
|
|
@@ -593,7 +614,7 @@ export class AutoOrchestrator {
|
|
|
593
614
|
* skipped result) instead of stopping.
|
|
594
615
|
*/
|
|
595
616
|
tryStuckArtifactRecovery(unitType, unitId) {
|
|
596
|
-
const key =
|
|
617
|
+
const key = buildDispatchKey(unitType, unitId);
|
|
597
618
|
if (this.lastStuckRecoveryKey === key)
|
|
598
619
|
return false; // already tried this episode
|
|
599
620
|
const basePath = this.getLiveDispatchBasePath();
|
|
@@ -608,7 +629,7 @@ export class AutoOrchestrator {
|
|
|
608
629
|
return false;
|
|
609
630
|
this.lastStuckRecoveryKey = key;
|
|
610
631
|
invalidateAllCaches();
|
|
611
|
-
this.
|
|
632
|
+
this.dispatchHistory.clearOnRecovery();
|
|
612
633
|
this.lastAdvanceKey = null;
|
|
613
634
|
this.lastFinalizedUnitKey = null;
|
|
614
635
|
return true;
|
|
@@ -634,8 +655,14 @@ export class AutoOrchestrator {
|
|
|
634
655
|
async start(_sessionContext) {
|
|
635
656
|
this.lastAdvanceKey = null;
|
|
636
657
|
this.lastFinalizedUnitKey = null;
|
|
637
|
-
|
|
658
|
+
// #482: the DB dispatch ledger is the source of truth across sessions.
|
|
659
|
+
// Discard any in-memory window and rebuild it from the ledger so a unit
|
|
660
|
+
// that was re-dispatched in previous sessions is detected as stuck here
|
|
661
|
+
// instead of silently re-dispatching forever.
|
|
662
|
+
this.dispatchHistory.clearOnRecovery();
|
|
663
|
+
this.dispatchHistory.rehydrate();
|
|
638
664
|
this.lastStuckRecoveryKey = null;
|
|
665
|
+
this.lastDerivedPhase = null;
|
|
639
666
|
this.status.phase = "running";
|
|
640
667
|
this.bumpTransition();
|
|
641
668
|
this.journalTransition({ name: "start" });
|
|
@@ -721,6 +748,11 @@ export class AutoOrchestrator {
|
|
|
721
748
|
this.postAdvanceRecord(blocked);
|
|
722
749
|
return blocked;
|
|
723
750
|
}
|
|
751
|
+
const reconciledPhase = reconciliation.stateSnapshot.phase;
|
|
752
|
+
if (this.lastDerivedPhase !== null) {
|
|
753
|
+
this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
|
|
754
|
+
}
|
|
755
|
+
this.lastDerivedPhase = reconciledPhase;
|
|
724
756
|
const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
|
|
725
757
|
if (!decision) {
|
|
726
758
|
const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
|
|
@@ -728,7 +760,7 @@ export class AutoOrchestrator {
|
|
|
728
760
|
this.status.phase = "paused";
|
|
729
761
|
this.status.activeUnit = undefined;
|
|
730
762
|
this.lastAdvanceKey = null;
|
|
731
|
-
this.
|
|
763
|
+
this.dispatchHistory.clearOnRecovery();
|
|
732
764
|
this.bumpTransition();
|
|
733
765
|
this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
|
|
734
766
|
this.postAdvanceRecord(settlementBlock);
|
|
@@ -744,7 +776,7 @@ export class AutoOrchestrator {
|
|
|
744
776
|
this.status.phase = "stopped";
|
|
745
777
|
this.status.activeUnit = undefined;
|
|
746
778
|
this.lastAdvanceKey = null;
|
|
747
|
-
this.
|
|
779
|
+
this.dispatchHistory.clearOnRecovery();
|
|
748
780
|
this.bumpTransition();
|
|
749
781
|
this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
|
|
750
782
|
this.postAdvanceRecord(stopped);
|
|
@@ -792,16 +824,12 @@ export class AutoOrchestrator {
|
|
|
792
824
|
this.postAdvanceRecord(blocked);
|
|
793
825
|
return blocked;
|
|
794
826
|
}
|
|
795
|
-
|
|
796
|
-
// Record every dispatch decision in the ring buffer before pre-flight
|
|
827
|
+
// Record every dispatch decision in the history window before pre-flight
|
|
797
828
|
// checks so the stuck-loop detector observes the full decision history
|
|
798
829
|
// (including decisions that idempotency would otherwise short-circuit).
|
|
799
|
-
// The
|
|
800
|
-
this.
|
|
801
|
-
|
|
802
|
-
this.dispatchKeyWindow.shift();
|
|
803
|
-
}
|
|
804
|
-
const matchingCount = this.dispatchKeyWindow.filter((k) => k === nextKey).length;
|
|
830
|
+
// The window is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
|
|
831
|
+
const nextKey = this.dispatchHistory.recordDispatch(decision.unitType, decision.unitId);
|
|
832
|
+
const matchingCount = this.dispatchHistory.countMatching(nextKey);
|
|
805
833
|
if (this.lastFinalizedUnitKey === nextKey) {
|
|
806
834
|
// #442: the unit re-dispatched immediately after finalizing may have
|
|
807
835
|
// actually completed on disk with a stale DB. Verify + recover before
|
|
@@ -833,22 +861,30 @@ export class AutoOrchestrator {
|
|
|
833
861
|
// checks coexist: idempotency for the common immediate-repeat case,
|
|
834
862
|
// stuck-loop for the saturated-window case.
|
|
835
863
|
if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
|
|
864
|
+
// Unit already active — benign no-op. Return skipped so the loop re-polls
|
|
865
|
+
// without cancelling the in-flight unit (blocked+pause would force-cancel it).
|
|
836
866
|
this.clearPendingDispatch();
|
|
837
|
-
const
|
|
867
|
+
const skipped = { kind: "skipped", reason: "idempotent advance: unit already active" };
|
|
838
868
|
this.journalTransition({
|
|
839
|
-
name: "advance-
|
|
840
|
-
reason:
|
|
869
|
+
name: "advance-skipped",
|
|
870
|
+
reason: skipped.reason,
|
|
841
871
|
unitType: decision.unitType,
|
|
842
872
|
unitId: decision.unitId,
|
|
843
873
|
});
|
|
844
|
-
this.postAdvanceRecord(
|
|
845
|
-
return
|
|
874
|
+
this.postAdvanceRecord(skipped);
|
|
875
|
+
return skipped;
|
|
846
876
|
}
|
|
847
|
-
// Stuck-loop detection: when the
|
|
848
|
-
// `nextKey` (count >= STUCK_WINDOW_SIZE), the
|
|
849
|
-
//
|
|
850
|
-
//
|
|
851
|
-
|
|
877
|
+
// Stuck-loop detection: when the window is saturated with copies of
|
|
878
|
+
// `nextKey` (count >= STUCK_WINDOW_SIZE), consult the Dispatch History
|
|
879
|
+
// module's full detect-stuck rule set for the verdict instead of the old
|
|
880
|
+
// bare saturation count. This keeps the saturation threshold (the window
|
|
881
|
+
// deliberately records benign idempotent repeats, so earlier-firing
|
|
882
|
+
// rules would false-positive on pause/resume re-advances) while gaining
|
|
883
|
+
// retry-budget suppression and diagnosable rule reasons. A saturated
|
|
884
|
+
// window with no verdict means the dispatch ledger says we are inside
|
|
885
|
+
// the unit's retry-backoff budget — let the retry proceed.
|
|
886
|
+
const stuckVerdict = matchingCount >= STUCK_WINDOW_SIZE ? this.dispatchHistory.detectStuck() : null;
|
|
887
|
+
if (stuckVerdict) {
|
|
852
888
|
// #442: before declaring a stuck loop, verify the unit didn't actually
|
|
853
889
|
// complete on disk (stale DB) and recover if so — legacy graduated
|
|
854
890
|
// stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
|
|
@@ -859,7 +895,7 @@ export class AutoOrchestrator {
|
|
|
859
895
|
this.clearPendingDispatch();
|
|
860
896
|
const blocked = {
|
|
861
897
|
kind: "blocked",
|
|
862
|
-
reason: `stuck-loop: ${
|
|
898
|
+
reason: `stuck-loop: ${stuckVerdict.reason}`,
|
|
863
899
|
action: "stop",
|
|
864
900
|
};
|
|
865
901
|
this.journalTransition({
|
|
@@ -949,7 +985,7 @@ export class AutoOrchestrator {
|
|
|
949
985
|
if (result.kind === "stopped") {
|
|
950
986
|
this.lastAdvanceKey = null;
|
|
951
987
|
this.lastFinalizedUnitKey = null;
|
|
952
|
-
this.
|
|
988
|
+
this.dispatchHistory.clearOnRecovery();
|
|
953
989
|
this.status.activeUnit = undefined;
|
|
954
990
|
}
|
|
955
991
|
this.bumpTransition();
|
|
@@ -978,9 +1014,18 @@ export class AutoOrchestrator {
|
|
|
978
1014
|
async resume() {
|
|
979
1015
|
this.lastAdvanceKey = null;
|
|
980
1016
|
this.lastFinalizedUnitKey = null;
|
|
981
|
-
// Preserve
|
|
982
|
-
// accumulates across pause/resume cycles rather than
|
|
1017
|
+
// Preserve the dispatch-history window across an in-process resume so
|
|
1018
|
+
// stuck-loop detection accumulates across pause/resume cycles rather than
|
|
1019
|
+
// resetting each time (#572 regression). When the window is empty (fresh
|
|
1020
|
+
// orchestrator resuming a prior session), rehydrate it from the DB
|
|
1021
|
+
// dispatch ledger so cross-session re-dispatch loops are detected (#482).
|
|
1022
|
+
if (this.dispatchHistory.getRecentWindow().length === 0) {
|
|
1023
|
+
this.dispatchHistory.rehydrate();
|
|
1024
|
+
}
|
|
983
1025
|
this.lastStuckRecoveryKey = null;
|
|
1026
|
+
// ADR-030: drop the prior "from" — the first advance after resume has no
|
|
1027
|
+
// edge to assert (avoids a false illegal-edge across the pause boundary).
|
|
1028
|
+
this.lastDerivedPhase = null;
|
|
984
1029
|
this.status.phase = "running";
|
|
985
1030
|
this.bumpTransition();
|
|
986
1031
|
this.journalTransition({ name: "resume" });
|
|
@@ -996,10 +1041,11 @@ export class AutoOrchestrator {
|
|
|
996
1041
|
this.status.activeUnit = undefined;
|
|
997
1042
|
this.lastAdvanceKey = null;
|
|
998
1043
|
this.lastFinalizedUnitKey = null;
|
|
999
|
-
|
|
1000
|
-
//
|
|
1044
|
+
this.lastDerivedPhase = null;
|
|
1045
|
+
// Preserve the dispatch-history window on pause so stuck-loop detection
|
|
1046
|
+
// accumulates across pause/resume cycles. Only clear on a hard stop.
|
|
1001
1047
|
if (reason !== "pause") {
|
|
1002
|
-
this.
|
|
1048
|
+
this.dispatchHistory.clearOnRecovery();
|
|
1003
1049
|
}
|
|
1004
1050
|
this.lastStuckRecoveryKey = null;
|
|
1005
1051
|
this.bumpTransition();
|
|
@@ -1011,9 +1057,9 @@ export class AutoOrchestrator {
|
|
|
1011
1057
|
return { ...this.status, activeUnit: this.status.activeUnit ? { ...this.status.activeUnit } : undefined };
|
|
1012
1058
|
}
|
|
1013
1059
|
async completeActiveUnit(unit) {
|
|
1014
|
-
const unitKey =
|
|
1060
|
+
const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
|
|
1015
1061
|
const activeUnitKey = this.status.activeUnit
|
|
1016
|
-
?
|
|
1062
|
+
? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
|
|
1017
1063
|
: null;
|
|
1018
1064
|
if (activeUnitKey !== unitKey)
|
|
1019
1065
|
return;
|
|
@@ -1030,9 +1076,9 @@ export class AutoOrchestrator {
|
|
|
1030
1076
|
});
|
|
1031
1077
|
}
|
|
1032
1078
|
async retryActiveUnit(unit) {
|
|
1033
|
-
const unitKey =
|
|
1079
|
+
const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
|
|
1034
1080
|
const activeUnitKey = this.status.activeUnit
|
|
1035
|
-
?
|
|
1081
|
+
? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
|
|
1036
1082
|
: null;
|
|
1037
1083
|
if (activeUnitKey !== unitKey && this.lastFinalizedUnitKey !== unitKey)
|
|
1038
1084
|
return;
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { importExtensionModule } from "@gsd/pi-coding-agent";
|
|
12
12
|
import { USER_DRIVEN_DEEP_UNITS, isAwaitingUserInput, } from "../auto-post-unit.js";
|
|
13
|
-
import { lastAssistantText } from "../
|
|
13
|
+
import { lastAssistantText } from "../consent-question.js";
|
|
14
|
+
import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
14
15
|
import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, MAX_FINALIZE_TIMEOUTS, } from "./types.js";
|
|
15
16
|
import { detectStuck } from "./detect-stuck.js";
|
|
17
|
+
import { STUCK_WINDOW_SIZE } from "./dispatch-history.js";
|
|
16
18
|
import { runUnit } from "./run-unit.js";
|
|
17
19
|
import { debugLog } from "../debug-logger.js";
|
|
18
20
|
import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
|
|
@@ -59,7 +61,6 @@ import { buildPhaseHandoffOutcome, setAutoActiveStatus, setAutoOutcomeWidget } f
|
|
|
59
61
|
import { getConsecutiveDispatchBlocker } from "../dispatch-guard.js";
|
|
60
62
|
import { captureRootDirtySnapshot, detectRootWriteLeak, formatRootWriteLeakMessage, } from "../root-write-leak-guard.js";
|
|
61
63
|
import { classifyError, isTransient } from "../error-classifier.js";
|
|
62
|
-
export const STUCK_WINDOW_SIZE = 6;
|
|
63
64
|
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
64
65
|
const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE = /^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) (?:hit|reached) your (?:\w+ )?limit\b|.*\b(?:usage|session|weekly|daily|monthly|quota) limit\b|limit\b.{0,40}\bresets?\b|out of extra usage\b|service.?unavailable\b|internal(?: server)? error(?::|$)|internal(?:[_-]server)?[_-]error\b|server[_-]error\b|(?:provider|server|api|model|codex|claude|openai|anthropic|gemini)\b.{0,80}\boverloaded\b|overloaded\b.{0,80}\b(?:provider|server|api|model)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
65
66
|
const ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE = /(?:\b(?:http|status(?: code)?|code|error:)\s*(?:429|500|502|503)\b|\b(?:api|provider) error\s*[:(]?\s*(?:429|500|502|503)\b|\b(?:typeerror|error):\s*(?:fetch failed\b|socket hang up\b|terminated(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|(?:network|connection|server) error(?::|$)|stream idle timeout\b|partial response received\b|unexpected eof\b)|\b(?:server_error|api_error|stream_exhausted(?:_without_result)?)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
@@ -265,7 +266,11 @@ async function validateSourceWriteWorktreeSafety(ic, unitType, unitId, milestone
|
|
|
265
266
|
if (!writesSource)
|
|
266
267
|
return null;
|
|
267
268
|
const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
268
|
-
|
|
269
|
+
// A degraded session already fell back to the milestone branch in the
|
|
270
|
+
// project root — validating against the canonical worktree root there
|
|
271
|
+
// would fail every dispatch with a false invalid-root. The same applies
|
|
272
|
+
// to a stranded-recovery session that adopted the milestone branch.
|
|
273
|
+
const isolationMode = resolveEffectiveUnitIsolationMode(deps.getIsolationMode(projectRoot), s.isolationDegraded, s.strandedRecoveryIsolationMode);
|
|
269
274
|
if (isolationMode !== "worktree")
|
|
270
275
|
return null;
|
|
271
276
|
const safety = createWorktreeSafetyModule();
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { deriveState } from "./state.js";
|
|
6
6
|
import { loadFile } from "./files.js";
|
|
7
|
-
import { isDbAvailable,
|
|
8
|
-
import {
|
|
9
|
-
import { resolveMilestoneFile, resolveSliceFile, relSliceFile, } from "./paths.js";
|
|
7
|
+
import { isDbAvailable, getClosedSliceIds } from "./gsd-db.js";
|
|
8
|
+
import { resolveSliceFile, relSliceFile, } from "./paths.js";
|
|
10
9
|
import { buildResearchSlicePrompt, buildResearchMilestonePrompt, buildPlanSlicePrompt, buildPlanMilestonePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReassessRoadmapPrompt, buildRunUatPrompt, buildReplanSlicePrompt, } from "./auto-prompts.js";
|
|
11
10
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
12
11
|
import { pauseAuto } from "./auto.js";
|
|
@@ -135,21 +134,9 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
|
|
|
135
134
|
}
|
|
136
135
|
case "reassess":
|
|
137
136
|
case "reassess-roadmap": {
|
|
138
|
-
// DB
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
completedSliceIds = getMilestoneSlices(mid).filter(s => s.status === "complete").map(s => s.id);
|
|
142
|
-
}
|
|
143
|
-
if (completedSliceIds.length === 0) {
|
|
144
|
-
// File-based fallback: parse roadmap checkboxes
|
|
145
|
-
const roadmapPath = resolveMilestoneFile(dispatchBase, mid, "ROADMAP");
|
|
146
|
-
if (roadmapPath) {
|
|
147
|
-
const roadmapContent = await loadFile(roadmapPath);
|
|
148
|
-
if (roadmapContent) {
|
|
149
|
-
completedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
137
|
+
// DB-authoritative read (ADR-017) — markdown projections are never
|
|
138
|
+
// consulted for dispatch decisions. No DB rows means no completed slices.
|
|
139
|
+
const completedSliceIds = isDbAvailable() ? getClosedSliceIds(mid) : [];
|
|
153
140
|
if (completedSliceIds.length === 0) {
|
|
154
141
|
ctx.ui.notify("Cannot dispatch reassess-roadmap: no completed slices.", "warning");
|
|
155
142
|
return;
|
|
@@ -173,20 +160,9 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
|
|
|
173
160
|
// incomplete) slice. After slice completion, state.activeSlice advances
|
|
174
161
|
// to the next incomplete slice, so we find the last done slice from the
|
|
175
162
|
// roadmap instead (#1693).
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
if (uatCompletedSliceIds.length === 0) {
|
|
181
|
-
// File-based fallback: parse roadmap checkboxes
|
|
182
|
-
const roadmapPath = resolveMilestoneFile(dispatchBase, mid, "ROADMAP");
|
|
183
|
-
if (roadmapPath) {
|
|
184
|
-
const roadmapContent = await loadFile(roadmapPath);
|
|
185
|
-
if (roadmapContent) {
|
|
186
|
-
uatCompletedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
163
|
+
// DB-authoritative read (ADR-017) — no markdown fallback for dispatch
|
|
164
|
+
// decisions.
|
|
165
|
+
const uatCompletedSliceIds = isDbAvailable() ? getClosedSliceIds(mid) : [];
|
|
190
166
|
if (uatCompletedSliceIds.length === 0) {
|
|
191
167
|
ctx.ui.notify("Cannot dispatch run-uat: no completed slices.", "warning");
|
|
192
168
|
return;
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// File Purpose: Declarative auto-mode dispatch rules and dispatch resolver.
|
|
3
3
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
4
4
|
import { getUatBrowserToolSupportError } from "./uat-policy.js";
|
|
5
|
-
import { isDbAvailable, getMilestoneSlices, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, } from "./gsd-db.js";
|
|
5
|
+
import { isDbAvailable, getMilestoneSlices, getMilestoneSliceSummaries, getClosedSliceIds, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, } from "./gsd-db.js";
|
|
6
6
|
import { isClosedStatus } from "./status-guards.js";
|
|
7
7
|
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
8
8
|
import { gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveMilestonePath, resolveSliceFile, resolveSlicePath, resolveTaskFile, relTaskFile, relSliceFile, buildMilestoneFileName, buildSliceFileName, buildTaskFileName, gsdProjectionRoot, } from "./paths.js";
|
|
9
|
-
import { parseRoadmap } from "./parsers-legacy.js";
|
|
10
9
|
import { validateArtifact } from "./schemas/validate.js";
|
|
11
10
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from "node:fs";
|
|
12
11
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -19,10 +18,14 @@ import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
|
19
18
|
import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js";
|
|
20
19
|
import { EXECUTION_ENTRY_PHASES, hasFinalizedMilestoneContext } from "./uok/plan-v2.js";
|
|
21
20
|
import { isAutoActive } from "./auto.js";
|
|
22
|
-
|
|
21
|
+
// Host adapter explicitly: auto-dispatch runs in the extension host, and the
|
|
22
|
+
// ambient write-gate exports env-sniff the adapter per call (they are reserved
|
|
23
|
+
// for the workflow MCP child's dynamic-import surface).
|
|
24
|
+
import { hostWriteGateAdapter } from "./bootstrap/write-gate.js";
|
|
23
25
|
import { ensureWorkflowPreferencesCaptured } from "./planning-depth.js";
|
|
24
26
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
25
|
-
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, } from "./workflow-mcp.js";
|
|
27
|
+
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, resolveWorkflowMcpProjectRoot, } from "./workflow-mcp.js";
|
|
28
|
+
import { prepareBrowserDaemonForUat } from "./browser-daemon-auto-prep.js";
|
|
26
29
|
import { PROJECT_RESEARCH_INFLIGHT_MARKER, } from "./project-research-policy.js";
|
|
27
30
|
import { isWorkflowPrefsCaptured, resolveDeepProjectSetupState, } from "./deep-project-setup-policy.js";
|
|
28
31
|
import { annotateBackgroundable } from "./delegation-policy.js";
|
|
@@ -289,30 +292,13 @@ function persistSliceAssessmentBackfill(assessmentRelPath, mid, sliceId, content
|
|
|
289
292
|
});
|
|
290
293
|
}
|
|
291
294
|
function backfillMissingAssessmentsFromSummaries(basePath, mid) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
302
|
-
if (!roadmapFile)
|
|
303
|
-
return;
|
|
304
|
-
try {
|
|
305
|
-
const roadmap = parseRoadmap(readFileSync(roadmapFile, "utf-8"));
|
|
306
|
-
for (const slice of roadmap.slices) {
|
|
307
|
-
if (slice.done)
|
|
308
|
-
completedSliceIds.add(slice.id);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
catch {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
for (const sliceId of completedSliceIds) {
|
|
295
|
+
// DB-authoritative (ADR-017): no markdown fallback. Without DB rows there
|
|
296
|
+
// is nothing to backfill.
|
|
297
|
+
if (!isDbAvailable())
|
|
298
|
+
return;
|
|
299
|
+
// Canonical closed vocabulary (complete/done/skipped/closed) — a skipped or
|
|
300
|
+
// closed slice with a SUMMARY gets the same assessment backfill treatment.
|
|
301
|
+
for (const sliceId of getClosedSliceIds(mid)) {
|
|
316
302
|
const summaryPath = resolveSliceFile(basePath, mid, sliceId, "SUMMARY");
|
|
317
303
|
if (!summaryPath || !existsSync(summaryPath))
|
|
318
304
|
continue;
|
|
@@ -488,7 +474,7 @@ export const DISPATCH_RULES = [
|
|
|
488
474
|
// deadlock. Deep planning is still user-driven even inside auto-mode,
|
|
489
475
|
// so it must wait for explicit approval instead of taking this bypass.
|
|
490
476
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
491
|
-
markDepthVerified(mid, basePath);
|
|
477
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
492
478
|
}
|
|
493
479
|
return {
|
|
494
480
|
action: "dispatch",
|
|
@@ -540,6 +526,16 @@ export const DISPATCH_RULES = [
|
|
|
540
526
|
if (browserToolError) {
|
|
541
527
|
return { action: "stop", reason: browserToolError, level: "warning" };
|
|
542
528
|
}
|
|
529
|
+
const browserDaemonError = prepareBrowserDaemonForUat({
|
|
530
|
+
uatType,
|
|
531
|
+
sessionProvider,
|
|
532
|
+
sessionAuthMode,
|
|
533
|
+
sessionBaseUrl,
|
|
534
|
+
projectRoot: resolveWorkflowMcpProjectRoot(basePath),
|
|
535
|
+
});
|
|
536
|
+
if (browserDaemonError) {
|
|
537
|
+
return { action: "stop", reason: browserDaemonError, level: "warning" };
|
|
538
|
+
}
|
|
543
539
|
// Cap run-uat dispatch attempts to prevent infinite replay (#3624).
|
|
544
540
|
// Check before incrementing so an exhausted counter cannot create a
|
|
545
541
|
// no-progress skip loop that starves later dispatch rules.
|
|
@@ -569,24 +565,11 @@ export const DISPATCH_RULES = [
|
|
|
569
565
|
// Only applies when UAT dispatch is enabled
|
|
570
566
|
if (!prefs?.uat_dispatch)
|
|
571
567
|
return null;
|
|
572
|
-
// DB-
|
|
573
|
-
|
|
574
|
-
if (isDbAvailable())
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
.map(s => s.id);
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
// Filesystem fallback for degraded / unmigrated projects.
|
|
581
|
-
// `slice.done` in the parsed ROADMAP is the disk-level closed signal.
|
|
582
|
-
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
583
|
-
const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
|
|
584
|
-
if (!roadmapContent)
|
|
585
|
-
return null;
|
|
586
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
587
|
-
closedSliceIds = roadmap.slices.filter(s => s.done).map(s => s.id);
|
|
588
|
-
}
|
|
589
|
-
for (const sliceId of closedSliceIds) {
|
|
568
|
+
// DB-authoritative (ADR-017): closed slices come from the DB only; the
|
|
569
|
+
// ROADMAP projection is never parsed for gate decisions.
|
|
570
|
+
if (!isDbAvailable())
|
|
571
|
+
return null;
|
|
572
|
+
for (const sliceId of getClosedSliceIds(mid)) {
|
|
590
573
|
const result = await readUatGateVerdict(basePath, mid, sliceId);
|
|
591
574
|
if (!result)
|
|
592
575
|
continue;
|
|
@@ -641,7 +624,7 @@ export const DISPATCH_RULES = [
|
|
|
641
624
|
// H6 fix (#4973): keep the non-deep auto-mode bypass, but do not
|
|
642
625
|
// pre-verify deep planning's user-facing milestone approval gate.
|
|
643
626
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
644
|
-
markDepthVerified(mid, basePath);
|
|
627
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
645
628
|
}
|
|
646
629
|
return {
|
|
647
630
|
action: "dispatch",
|
|
@@ -823,7 +806,7 @@ export const DISPATCH_RULES = [
|
|
|
823
806
|
// H6 fix (#4973): keep the non-deep auto-mode bypass, but do not
|
|
824
807
|
// pre-verify deep planning's user-facing milestone approval gate.
|
|
825
808
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
826
|
-
markDepthVerified(mid, basePath);
|
|
809
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
827
810
|
}
|
|
828
811
|
return {
|
|
829
812
|
action: "dispatch",
|
|
@@ -905,18 +888,18 @@ export const DISPATCH_RULES = [
|
|
|
905
888
|
// behavior.
|
|
906
889
|
if (await getMilestonePipelineVariant(mid) === "trivial")
|
|
907
890
|
return null;
|
|
908
|
-
//
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
891
|
+
// DB-authoritative slice list (ADR-017): the ROADMAP projection is
|
|
892
|
+
// never parsed for dispatch decisions. No DB / no rows → skip this rule.
|
|
893
|
+
if (!isDbAvailable())
|
|
894
|
+
return null;
|
|
895
|
+
const dbSlices = getMilestoneSliceSummaries(mid);
|
|
896
|
+
if (dbSlices.length === 0)
|
|
913
897
|
return null;
|
|
914
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
915
898
|
// Find slices that need research (no RESEARCH file, dependencies done)
|
|
916
899
|
const milestoneResearchFile = resolveExistingExpectedArtifact("research-milestone", mid, basePath) ??
|
|
917
900
|
resolveMilestoneFile(basePath, mid, "RESEARCH");
|
|
918
901
|
const researchReadySlices = [];
|
|
919
|
-
for (const slice of
|
|
902
|
+
for (const slice of dbSlices) {
|
|
920
903
|
if (slice.done)
|
|
921
904
|
continue;
|
|
922
905
|
// Skip S01 when milestone research exists
|
|
@@ -926,7 +909,7 @@ export const DISPATCH_RULES = [
|
|
|
926
909
|
if (resolveExistingExpectedArtifact("research-slice", `${mid}/${slice.id}`, basePath))
|
|
927
910
|
continue;
|
|
928
911
|
// Skip if dependencies aren't done (check for SUMMARY files)
|
|
929
|
-
const depsComplete =
|
|
912
|
+
const depsComplete = slice.depends.every((depId) => !!resolveExistingExpectedArtifact("complete-slice", `${mid}/${depId}`, basePath));
|
|
930
913
|
if (!depsComplete)
|
|
931
914
|
continue;
|
|
932
915
|
researchReadySlices.push({ id: slice.id, title: slice.title });
|
|
@@ -839,15 +839,34 @@ export function resolveModelId(modelId, availableModels, currentProvider) {
|
|
|
839
839
|
if (providerMatch)
|
|
840
840
|
return providerMatch;
|
|
841
841
|
}
|
|
842
|
-
//
|
|
843
|
-
//
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
842
|
+
// Subscription/OAuth routes beat pay-per-token API when the same model ID
|
|
843
|
+
// exists on multiple providers. Order matters — first match wins.
|
|
844
|
+
for (const provider of BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE) {
|
|
845
|
+
const match = candidates.find(m => m.provider === provider);
|
|
846
|
+
if (match)
|
|
847
|
+
return match;
|
|
848
|
+
}
|
|
848
849
|
// Fall back to first non-extension candidate, or any candidate
|
|
849
850
|
return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
|
|
850
851
|
}
|
|
852
|
+
/**
|
|
853
|
+
* When a bare model ID exists on multiple providers, prefer subscription/OAuth
|
|
854
|
+
* routes over pay-per-token API keys. Matches PROVIDER_ROUTES in doctor-providers
|
|
855
|
+
* but applies when *both* sides are authenticated.
|
|
856
|
+
*
|
|
857
|
+
* Order rationale:
|
|
858
|
+
* - openai-codex before github-copilot: ChatGPT-native for shared GPT IDs
|
|
859
|
+
* - google-gemini-cli before github-copilot: first-party Gemini CLI
|
|
860
|
+
* - anthropic before github-copilot: first-party Claude API/OAuth over Copilot
|
|
861
|
+
* - github-copilot before openai/google: Copilot OAuth over platform API keys
|
|
862
|
+
*/
|
|
863
|
+
export const BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE = [
|
|
864
|
+
"openai-codex",
|
|
865
|
+
"google-gemini-cli",
|
|
866
|
+
"anthropic",
|
|
867
|
+
"github-copilot",
|
|
868
|
+
"google-antigravity",
|
|
869
|
+
];
|
|
851
870
|
/**
|
|
852
871
|
* Flat-rate providers charge the same per request regardless of model.
|
|
853
872
|
* Dynamic routing provides no cost benefit — it only degrades quality (#3453).
|