@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
|
@@ -14,13 +14,14 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
14
14
|
|
|
15
15
|
import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus, AutoTerminalOutcome } from "./contracts.js";
|
|
16
16
|
import type { AutoSession, PendingOrchestrationDispatch } from "./session.js";
|
|
17
|
-
import type { GSDState } from "../types.js";
|
|
17
|
+
import type { GSDState, Phase } from "../types.js";
|
|
18
18
|
import type { MinimalModelRegistry } from "../context-budget.js";
|
|
19
19
|
|
|
20
20
|
type BlockedAdvanceResult = Extract<AutoAdvanceResult, { kind: "blocked" }>;
|
|
21
21
|
|
|
22
|
-
import { debugCount, debugTime } from "../debug-logger.js";
|
|
22
|
+
import { debugCount, debugLog, debugTime } from "../debug-logger.js";
|
|
23
23
|
import { reconcileBeforeDispatch } from "../state-reconciliation.js";
|
|
24
|
+
import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
|
|
24
25
|
import { resolveDispatch } from "../auto-dispatch.js";
|
|
25
26
|
import { classifyFailure } from "../recovery-classification.js";
|
|
26
27
|
import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
|
|
@@ -37,7 +38,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
|
|
|
37
38
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
38
39
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
39
40
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
40
|
-
import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
|
|
41
|
+
import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
41
42
|
import {
|
|
42
43
|
detectWorktreeName,
|
|
43
44
|
getMainBranch,
|
|
@@ -63,6 +64,13 @@ import {
|
|
|
63
64
|
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
64
65
|
import { getErrorMessage } from "../error-utils.js";
|
|
65
66
|
import { logWarning } from "../workflow-logger.js";
|
|
67
|
+
import { normalizeRealPath } from "../paths.js";
|
|
68
|
+
import {
|
|
69
|
+
buildDispatchKey,
|
|
70
|
+
createDispatchHistory,
|
|
71
|
+
STUCK_WINDOW_SIZE,
|
|
72
|
+
type DispatchHistory,
|
|
73
|
+
} from "./dispatch-history.js";
|
|
66
74
|
import { existsSync, readFileSync } from "node:fs";
|
|
67
75
|
import { join } from "node:path";
|
|
68
76
|
import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
|
|
@@ -71,16 +79,6 @@ function now(): number {
|
|
|
71
79
|
return Date.now();
|
|
72
80
|
}
|
|
73
81
|
|
|
74
|
-
/**
|
|
75
|
-
* Size of the dispatch-decision ring buffer used by the Auto Orchestration
|
|
76
|
-
* module's stuck-loop detector. When the same `${unitType}:${unitId}` key
|
|
77
|
-
* fills the window, advance() blocks with `action: "stop"`.
|
|
78
|
-
*
|
|
79
|
-
* Mirrors the legacy `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is
|
|
80
|
-
* preserved across the eventual cutover (issue #5791).
|
|
81
|
-
*/
|
|
82
|
-
export const STUCK_WINDOW_SIZE = 6;
|
|
83
|
-
|
|
84
82
|
function noRemainingUnitsOutcome(stateSnapshot: GSDState): AutoTerminalOutcome {
|
|
85
83
|
if (stateSnapshot.phase === "complete") {
|
|
86
84
|
return {
|
|
@@ -329,7 +327,13 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
329
327
|
private seq = 0;
|
|
330
328
|
private lastAdvanceKey: string | null = null;
|
|
331
329
|
private lastFinalizedUnitKey: string | null = null;
|
|
332
|
-
|
|
330
|
+
// Dispatch History module (#482): the dispatch-decision window with
|
|
331
|
+
// cross-session DB rehydration and full detect-stuck rules.
|
|
332
|
+
private readonly dispatchHistory: DispatchHistory;
|
|
333
|
+
// ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
|
|
334
|
+
// the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
|
|
335
|
+
// so the first advance of a session has no edge to assert.
|
|
336
|
+
private lastDerivedPhase: Phase | null = null;
|
|
333
337
|
// #442: the unit key we last attempted graduated stuck-recovery for. Bounds
|
|
334
338
|
// recovery to one attempt per stuck episode per run (reset on start/resume/
|
|
335
339
|
// stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
|
|
@@ -342,6 +346,16 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
342
346
|
this.runtimeBasePath = context.runtimeBasePath;
|
|
343
347
|
this.s = context.session;
|
|
344
348
|
this.flowId = `auto-orchestrator-${Date.now()}`;
|
|
349
|
+
this.dispatchHistory = createDispatchHistory({
|
|
350
|
+
windowSize: STUCK_WINDOW_SIZE,
|
|
351
|
+
// Same stable scope the auto-loop uses for stuck-state persistence so
|
|
352
|
+
// rehydration reads the rows the dispatch ledger wrote for this project.
|
|
353
|
+
resolveScopeId: () =>
|
|
354
|
+
normalizeRealPath(
|
|
355
|
+
this.s.scope?.workspace.projectRoot ??
|
|
356
|
+
(this.s.originalBasePath || this.s.basePath || this.runtimeBasePath),
|
|
357
|
+
) || null,
|
|
358
|
+
});
|
|
345
359
|
}
|
|
346
360
|
|
|
347
361
|
// ── Live base-path resolution (was the wiring factory's getLiveDispatchBasePath) ──
|
|
@@ -612,8 +626,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
612
626
|
// ── WorktreeAdapter (folded) ─────────────────────────────────────────────
|
|
613
627
|
|
|
614
628
|
private getEffectiveUnitIsolationMode(basePath: string): ReturnType<typeof getIsolationMode> {
|
|
615
|
-
|
|
616
|
-
|
|
629
|
+
return resolveEffectiveUnitIsolationMode(
|
|
630
|
+
getIsolationMode(basePath),
|
|
631
|
+
this.s.isolationDegraded,
|
|
632
|
+
this.s.strandedRecoveryIsolationMode,
|
|
633
|
+
);
|
|
617
634
|
}
|
|
618
635
|
|
|
619
636
|
private buildLifecycle(): WorktreeLifecycle {
|
|
@@ -724,6 +741,21 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
724
741
|
return { action: recovery.action, reason: recovery.reason };
|
|
725
742
|
}
|
|
726
743
|
|
|
744
|
+
/**
|
|
745
|
+
* ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
|
|
746
|
+
* assertion, not a decision-maker — deriveState already chose the phase; we
|
|
747
|
+
* only observe illegal *derived* edges that survived reconciliation. The
|
|
748
|
+
* matrix is still a sparse hardening spec, so this is telemetry-only (no
|
|
749
|
+
* block) until it is expanded into a validated legal-edge graph. To enforce:
|
|
750
|
+
* `throw violation;` instead of logging — recovery-classification maps
|
|
751
|
+
* IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
|
|
752
|
+
*/
|
|
753
|
+
private observePhaseTransition(from: Phase, to: Phase): void {
|
|
754
|
+
if (isLegalEdge(from, to)) return;
|
|
755
|
+
const violation = new IllegalPhaseTransitionError(from, to);
|
|
756
|
+
debugLog("phase-transition-advisory", { from, to, message: violation.message });
|
|
757
|
+
}
|
|
758
|
+
|
|
727
759
|
// ── Lifecycle verbs ──────────────────────────────────────────────────────
|
|
728
760
|
|
|
729
761
|
/**
|
|
@@ -742,7 +774,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
742
774
|
* skipped result) instead of stopping.
|
|
743
775
|
*/
|
|
744
776
|
private tryStuckArtifactRecovery(unitType: string, unitId: string): boolean {
|
|
745
|
-
const key =
|
|
777
|
+
const key = buildDispatchKey(unitType, unitId);
|
|
746
778
|
if (this.lastStuckRecoveryKey === key) return false; // already tried this episode
|
|
747
779
|
const basePath = this.getLiveDispatchBasePath();
|
|
748
780
|
if (!verifyExpectedArtifact(unitType, unitId, basePath)) return false;
|
|
@@ -754,7 +786,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
754
786
|
if (!refreshed.ok && refreshed.fatal) return false;
|
|
755
787
|
this.lastStuckRecoveryKey = key;
|
|
756
788
|
invalidateAllCaches();
|
|
757
|
-
this.
|
|
789
|
+
this.dispatchHistory.clearOnRecovery();
|
|
758
790
|
this.lastAdvanceKey = null;
|
|
759
791
|
this.lastFinalizedUnitKey = null;
|
|
760
792
|
return true;
|
|
@@ -785,8 +817,14 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
785
817
|
public async start(_sessionContext: AutoSessionContext): Promise<AutoAdvanceResult> {
|
|
786
818
|
this.lastAdvanceKey = null;
|
|
787
819
|
this.lastFinalizedUnitKey = null;
|
|
788
|
-
|
|
820
|
+
// #482: the DB dispatch ledger is the source of truth across sessions.
|
|
821
|
+
// Discard any in-memory window and rebuild it from the ledger so a unit
|
|
822
|
+
// that was re-dispatched in previous sessions is detected as stuck here
|
|
823
|
+
// instead of silently re-dispatching forever.
|
|
824
|
+
this.dispatchHistory.clearOnRecovery();
|
|
825
|
+
this.dispatchHistory.rehydrate();
|
|
789
826
|
this.lastStuckRecoveryKey = null;
|
|
827
|
+
this.lastDerivedPhase = null;
|
|
790
828
|
this.status.phase = "running";
|
|
791
829
|
this.bumpTransition();
|
|
792
830
|
this.journalTransition({ name: "start" });
|
|
@@ -876,6 +914,12 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
876
914
|
return blocked;
|
|
877
915
|
}
|
|
878
916
|
|
|
917
|
+
const reconciledPhase = reconciliation.stateSnapshot.phase;
|
|
918
|
+
if (this.lastDerivedPhase !== null) {
|
|
919
|
+
this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
|
|
920
|
+
}
|
|
921
|
+
this.lastDerivedPhase = reconciledPhase;
|
|
922
|
+
|
|
879
923
|
const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
|
|
880
924
|
if (!decision) {
|
|
881
925
|
const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
|
|
@@ -883,7 +927,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
883
927
|
this.status.phase = "paused";
|
|
884
928
|
this.status.activeUnit = undefined;
|
|
885
929
|
this.lastAdvanceKey = null;
|
|
886
|
-
this.
|
|
930
|
+
this.dispatchHistory.clearOnRecovery();
|
|
887
931
|
this.bumpTransition();
|
|
888
932
|
this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
|
|
889
933
|
this.postAdvanceRecord(settlementBlock);
|
|
@@ -899,7 +943,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
899
943
|
this.status.phase = "stopped";
|
|
900
944
|
this.status.activeUnit = undefined;
|
|
901
945
|
this.lastAdvanceKey = null;
|
|
902
|
-
this.
|
|
946
|
+
this.dispatchHistory.clearOnRecovery();
|
|
903
947
|
this.bumpTransition();
|
|
904
948
|
this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
|
|
905
949
|
this.postAdvanceRecord(stopped);
|
|
@@ -949,18 +993,13 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
949
993
|
return blocked;
|
|
950
994
|
}
|
|
951
995
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
// Record every dispatch decision in the ring buffer before pre-flight
|
|
996
|
+
// Record every dispatch decision in the history window before pre-flight
|
|
955
997
|
// checks so the stuck-loop detector observes the full decision history
|
|
956
998
|
// (including decisions that idempotency would otherwise short-circuit).
|
|
957
|
-
// The
|
|
958
|
-
this.
|
|
959
|
-
if (this.dispatchKeyWindow.length > STUCK_WINDOW_SIZE) {
|
|
960
|
-
this.dispatchKeyWindow.shift();
|
|
961
|
-
}
|
|
999
|
+
// The window is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
|
|
1000
|
+
const nextKey = this.dispatchHistory.recordDispatch(decision.unitType, decision.unitId);
|
|
962
1001
|
|
|
963
|
-
const matchingCount = this.
|
|
1002
|
+
const matchingCount = this.dispatchHistory.countMatching(nextKey);
|
|
964
1003
|
if (this.lastFinalizedUnitKey === nextKey) {
|
|
965
1004
|
// #442: the unit re-dispatched immediately after finalizing may have
|
|
966
1005
|
// actually completed on disk with a stale DB. Verify + recover before
|
|
@@ -993,23 +1032,32 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
993
1032
|
// checks coexist: idempotency for the common immediate-repeat case,
|
|
994
1033
|
// stuck-loop for the saturated-window case.
|
|
995
1034
|
if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
|
|
1035
|
+
// Unit already active — benign no-op. Return skipped so the loop re-polls
|
|
1036
|
+
// without cancelling the in-flight unit (blocked+pause would force-cancel it).
|
|
996
1037
|
this.clearPendingDispatch();
|
|
997
|
-
const
|
|
1038
|
+
const skipped: AutoAdvanceResult = { kind: "skipped", reason: "idempotent advance: unit already active" };
|
|
998
1039
|
this.journalTransition({
|
|
999
|
-
name: "advance-
|
|
1000
|
-
reason:
|
|
1040
|
+
name: "advance-skipped",
|
|
1041
|
+
reason: skipped.reason,
|
|
1001
1042
|
unitType: decision.unitType,
|
|
1002
1043
|
unitId: decision.unitId,
|
|
1003
1044
|
});
|
|
1004
|
-
this.postAdvanceRecord(
|
|
1005
|
-
return
|
|
1045
|
+
this.postAdvanceRecord(skipped);
|
|
1046
|
+
return skipped;
|
|
1006
1047
|
}
|
|
1007
1048
|
|
|
1008
|
-
// Stuck-loop detection: when the
|
|
1009
|
-
// `nextKey` (count >= STUCK_WINDOW_SIZE), the
|
|
1010
|
-
//
|
|
1011
|
-
//
|
|
1012
|
-
|
|
1049
|
+
// Stuck-loop detection: when the window is saturated with copies of
|
|
1050
|
+
// `nextKey` (count >= STUCK_WINDOW_SIZE), consult the Dispatch History
|
|
1051
|
+
// module's full detect-stuck rule set for the verdict instead of the old
|
|
1052
|
+
// bare saturation count. This keeps the saturation threshold (the window
|
|
1053
|
+
// deliberately records benign idempotent repeats, so earlier-firing
|
|
1054
|
+
// rules would false-positive on pause/resume re-advances) while gaining
|
|
1055
|
+
// retry-budget suppression and diagnosable rule reasons. A saturated
|
|
1056
|
+
// window with no verdict means the dispatch ledger says we are inside
|
|
1057
|
+
// the unit's retry-backoff budget — let the retry proceed.
|
|
1058
|
+
const stuckVerdict =
|
|
1059
|
+
matchingCount >= STUCK_WINDOW_SIZE ? this.dispatchHistory.detectStuck() : null;
|
|
1060
|
+
if (stuckVerdict) {
|
|
1013
1061
|
// #442: before declaring a stuck loop, verify the unit didn't actually
|
|
1014
1062
|
// complete on disk (stale DB) and recover if so — legacy graduated
|
|
1015
1063
|
// stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
|
|
@@ -1020,7 +1068,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1020
1068
|
this.clearPendingDispatch();
|
|
1021
1069
|
const blocked: AutoAdvanceResult = {
|
|
1022
1070
|
kind: "blocked",
|
|
1023
|
-
reason: `stuck-loop: ${
|
|
1071
|
+
reason: `stuck-loop: ${stuckVerdict.reason}`,
|
|
1024
1072
|
action: "stop",
|
|
1025
1073
|
};
|
|
1026
1074
|
this.journalTransition({
|
|
@@ -1114,7 +1162,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1114
1162
|
if (result.kind === "stopped") {
|
|
1115
1163
|
this.lastAdvanceKey = null;
|
|
1116
1164
|
this.lastFinalizedUnitKey = null;
|
|
1117
|
-
this.
|
|
1165
|
+
this.dispatchHistory.clearOnRecovery();
|
|
1118
1166
|
this.status.activeUnit = undefined;
|
|
1119
1167
|
}
|
|
1120
1168
|
this.bumpTransition();
|
|
@@ -1143,9 +1191,18 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1143
1191
|
public async resume(): Promise<AutoAdvanceResult> {
|
|
1144
1192
|
this.lastAdvanceKey = null;
|
|
1145
1193
|
this.lastFinalizedUnitKey = null;
|
|
1146
|
-
// Preserve
|
|
1147
|
-
// accumulates across pause/resume cycles rather than
|
|
1194
|
+
// Preserve the dispatch-history window across an in-process resume so
|
|
1195
|
+
// stuck-loop detection accumulates across pause/resume cycles rather than
|
|
1196
|
+
// resetting each time (#572 regression). When the window is empty (fresh
|
|
1197
|
+
// orchestrator resuming a prior session), rehydrate it from the DB
|
|
1198
|
+
// dispatch ledger so cross-session re-dispatch loops are detected (#482).
|
|
1199
|
+
if (this.dispatchHistory.getRecentWindow().length === 0) {
|
|
1200
|
+
this.dispatchHistory.rehydrate();
|
|
1201
|
+
}
|
|
1148
1202
|
this.lastStuckRecoveryKey = null;
|
|
1203
|
+
// ADR-030: drop the prior "from" — the first advance after resume has no
|
|
1204
|
+
// edge to assert (avoids a false illegal-edge across the pause boundary).
|
|
1205
|
+
this.lastDerivedPhase = null;
|
|
1149
1206
|
this.status.phase = "running";
|
|
1150
1207
|
this.bumpTransition();
|
|
1151
1208
|
this.journalTransition({ name: "resume" });
|
|
@@ -1162,10 +1219,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1162
1219
|
this.status.activeUnit = undefined;
|
|
1163
1220
|
this.lastAdvanceKey = null;
|
|
1164
1221
|
this.lastFinalizedUnitKey = null;
|
|
1165
|
-
|
|
1166
|
-
//
|
|
1222
|
+
this.lastDerivedPhase = null;
|
|
1223
|
+
// Preserve the dispatch-history window on pause so stuck-loop detection
|
|
1224
|
+
// accumulates across pause/resume cycles. Only clear on a hard stop.
|
|
1167
1225
|
if (reason !== "pause") {
|
|
1168
|
-
this.
|
|
1226
|
+
this.dispatchHistory.clearOnRecovery();
|
|
1169
1227
|
}
|
|
1170
1228
|
this.lastStuckRecoveryKey = null;
|
|
1171
1229
|
this.bumpTransition();
|
|
@@ -1179,9 +1237,9 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1179
1237
|
}
|
|
1180
1238
|
|
|
1181
1239
|
public async completeActiveUnit(unit: { unitType: string; unitId: string }): Promise<void> {
|
|
1182
|
-
const unitKey =
|
|
1240
|
+
const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
|
|
1183
1241
|
const activeUnitKey = this.status.activeUnit
|
|
1184
|
-
?
|
|
1242
|
+
? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
|
|
1185
1243
|
: null;
|
|
1186
1244
|
if (activeUnitKey !== unitKey) return;
|
|
1187
1245
|
|
|
@@ -1199,9 +1257,9 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1199
1257
|
}
|
|
1200
1258
|
|
|
1201
1259
|
public async retryActiveUnit(unit: { unitType: string; unitId: string }): Promise<void> {
|
|
1202
|
-
const unitKey =
|
|
1260
|
+
const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
|
|
1203
1261
|
const activeUnitKey = this.status.activeUnit
|
|
1204
|
-
?
|
|
1262
|
+
? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
|
|
1205
1263
|
: null;
|
|
1206
1264
|
if (activeUnitKey !== unitKey && this.lastFinalizedUnitKey !== unitKey) return;
|
|
1207
1265
|
|
|
@@ -19,7 +19,8 @@ import {
|
|
|
19
19
|
type PostUnitContext,
|
|
20
20
|
type PreVerificationOpts,
|
|
21
21
|
} from "../auto-post-unit.js";
|
|
22
|
-
import { lastAssistantText } from "../
|
|
22
|
+
import { lastAssistantText } from "../consent-question.js";
|
|
23
|
+
import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
23
24
|
import type { Phase } from "../types.js";
|
|
24
25
|
import {
|
|
25
26
|
MAX_RECOVERY_CHARS,
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
type IterationData,
|
|
33
34
|
} from "./types.js";
|
|
34
35
|
import { detectStuck } from "./detect-stuck.js";
|
|
36
|
+
import { STUCK_WINDOW_SIZE } from "./dispatch-history.js";
|
|
35
37
|
import { runUnit } from "./run-unit.js";
|
|
36
38
|
import { debugLog } from "../debug-logger.js";
|
|
37
39
|
import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
|
|
@@ -106,7 +108,6 @@ import {
|
|
|
106
108
|
} from "../root-write-leak-guard.js";
|
|
107
109
|
import { classifyError, isTransient } from "../error-classifier.js";
|
|
108
110
|
|
|
109
|
-
export const STUCK_WINDOW_SIZE = 6;
|
|
110
111
|
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
111
112
|
const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE =
|
|
112
113
|
/^(?: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;
|
|
@@ -362,7 +363,15 @@ async function validateSourceWriteWorktreeSafety(
|
|
|
362
363
|
if (!writesSource) return null;
|
|
363
364
|
|
|
364
365
|
const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
365
|
-
|
|
366
|
+
// A degraded session already fell back to the milestone branch in the
|
|
367
|
+
// project root — validating against the canonical worktree root there
|
|
368
|
+
// would fail every dispatch with a false invalid-root. The same applies
|
|
369
|
+
// to a stranded-recovery session that adopted the milestone branch.
|
|
370
|
+
const isolationMode = resolveEffectiveUnitIsolationMode(
|
|
371
|
+
deps.getIsolationMode(projectRoot),
|
|
372
|
+
s.isolationDegraded,
|
|
373
|
+
s.strandedRecoveryIsolationMode,
|
|
374
|
+
);
|
|
366
375
|
if (isolationMode !== "worktree") return null;
|
|
367
376
|
|
|
368
377
|
const safety = createWorktreeSafetyModule();
|
|
@@ -10,10 +10,9 @@ import type {
|
|
|
10
10
|
|
|
11
11
|
import { deriveState } from "./state.js";
|
|
12
12
|
import { loadFile } from "./files.js";
|
|
13
|
-
import { isDbAvailable,
|
|
14
|
-
import { parseRoadmap } from "./parsers-legacy.js";
|
|
13
|
+
import { isDbAvailable, getClosedSliceIds } from "./gsd-db.js";
|
|
15
14
|
import {
|
|
16
|
-
|
|
15
|
+
resolveSliceFile, relSliceFile,
|
|
17
16
|
} from "./paths.js";
|
|
18
17
|
import {
|
|
19
18
|
buildResearchSlicePrompt,
|
|
@@ -182,21 +181,9 @@ export async function dispatchDirectPhase(
|
|
|
182
181
|
|
|
183
182
|
case "reassess":
|
|
184
183
|
case "reassess-roadmap": {
|
|
185
|
-
// DB
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
completedSliceIds = getMilestoneSlices(mid).filter(s => s.status === "complete").map(s => s.id);
|
|
189
|
-
}
|
|
190
|
-
if (completedSliceIds.length === 0) {
|
|
191
|
-
// File-based fallback: parse roadmap checkboxes
|
|
192
|
-
const roadmapPath = resolveMilestoneFile(dispatchBase, mid, "ROADMAP");
|
|
193
|
-
if (roadmapPath) {
|
|
194
|
-
const roadmapContent = await loadFile(roadmapPath);
|
|
195
|
-
if (roadmapContent) {
|
|
196
|
-
completedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
184
|
+
// DB-authoritative read (ADR-017) — markdown projections are never
|
|
185
|
+
// consulted for dispatch decisions. No DB rows means no completed slices.
|
|
186
|
+
const completedSliceIds = isDbAvailable() ? getClosedSliceIds(mid) : [];
|
|
200
187
|
if (completedSliceIds.length === 0) {
|
|
201
188
|
ctx.ui.notify("Cannot dispatch reassess-roadmap: no completed slices.", "warning");
|
|
202
189
|
return;
|
|
@@ -222,20 +209,9 @@ export async function dispatchDirectPhase(
|
|
|
222
209
|
// incomplete) slice. After slice completion, state.activeSlice advances
|
|
223
210
|
// to the next incomplete slice, so we find the last done slice from the
|
|
224
211
|
// roadmap instead (#1693).
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
if (uatCompletedSliceIds.length === 0) {
|
|
230
|
-
// File-based fallback: parse roadmap checkboxes
|
|
231
|
-
const roadmapPath = resolveMilestoneFile(dispatchBase, mid, "ROADMAP");
|
|
232
|
-
if (roadmapPath) {
|
|
233
|
-
const roadmapContent = await loadFile(roadmapPath);
|
|
234
|
-
if (roadmapContent) {
|
|
235
|
-
uatCompletedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
212
|
+
// DB-authoritative read (ADR-017) — no markdown fallback for dispatch
|
|
213
|
+
// decisions.
|
|
214
|
+
const uatCompletedSliceIds = isDbAvailable() ? getClosedSliceIds(mid) : [];
|
|
239
215
|
if (uatCompletedSliceIds.length === 0) {
|
|
240
216
|
ctx.ui.notify("Cannot dispatch run-uat: no completed slices.", "warning");
|
|
241
217
|
return;
|
|
@@ -20,6 +20,8 @@ import { getUatBrowserToolSupportError, type UatType } from "./uat-policy.js";
|
|
|
20
20
|
import {
|
|
21
21
|
isDbAvailable,
|
|
22
22
|
getMilestoneSlices,
|
|
23
|
+
getMilestoneSliceSummaries,
|
|
24
|
+
getClosedSliceIds,
|
|
23
25
|
getPendingGatesForTurn,
|
|
24
26
|
markPendingGatesOmittedForTurn,
|
|
25
27
|
getMilestone,
|
|
@@ -47,7 +49,6 @@ import {
|
|
|
47
49
|
buildTaskFileName,
|
|
48
50
|
gsdProjectionRoot,
|
|
49
51
|
} from "./paths.js";
|
|
50
|
-
import { parseRoadmap } from "./parsers-legacy.js";
|
|
51
52
|
import { validateArtifact } from "./schemas/validate.js";
|
|
52
53
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from "node:fs";
|
|
53
54
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
@@ -84,13 +85,18 @@ import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
|
84
85
|
import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js";
|
|
85
86
|
import { EXECUTION_ENTRY_PHASES, hasFinalizedMilestoneContext } from "./uok/plan-v2.js";
|
|
86
87
|
import { isAutoActive } from "./auto.js";
|
|
87
|
-
|
|
88
|
+
// Host adapter explicitly: auto-dispatch runs in the extension host, and the
|
|
89
|
+
// ambient write-gate exports env-sniff the adapter per call (they are reserved
|
|
90
|
+
// for the workflow MCP child's dynamic-import surface).
|
|
91
|
+
import { hostWriteGateAdapter } from "./bootstrap/write-gate.js";
|
|
88
92
|
import { ensureWorkflowPreferencesCaptured } from "./planning-depth.js";
|
|
89
93
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
90
94
|
import {
|
|
91
95
|
getWorkflowTransportSupportError,
|
|
92
96
|
getRequiredWorkflowToolsForAutoUnit,
|
|
97
|
+
resolveWorkflowMcpProjectRoot,
|
|
93
98
|
} from "./workflow-mcp.js";
|
|
99
|
+
import { prepareBrowserDaemonForUat } from "./browser-daemon-auto-prep.js";
|
|
94
100
|
import {
|
|
95
101
|
PROJECT_RESEARCH_INFLIGHT_MARKER,
|
|
96
102
|
} from "./project-research-policy.js";
|
|
@@ -490,27 +496,12 @@ function persistSliceAssessmentBackfill(
|
|
|
490
496
|
}
|
|
491
497
|
|
|
492
498
|
function backfillMissingAssessmentsFromSummaries(basePath: string, mid: string): void {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
}
|
|
500
|
-
} else {
|
|
501
|
-
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
502
|
-
if (!roadmapFile) return;
|
|
503
|
-
try {
|
|
504
|
-
const roadmap = parseRoadmap(readFileSync(roadmapFile, "utf-8"));
|
|
505
|
-
for (const slice of roadmap.slices) {
|
|
506
|
-
if (slice.done) completedSliceIds.add(slice.id);
|
|
507
|
-
}
|
|
508
|
-
} catch {
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
for (const sliceId of completedSliceIds) {
|
|
499
|
+
// DB-authoritative (ADR-017): no markdown fallback. Without DB rows there
|
|
500
|
+
// is nothing to backfill.
|
|
501
|
+
if (!isDbAvailable()) return;
|
|
502
|
+
// Canonical closed vocabulary (complete/done/skipped/closed) — a skipped or
|
|
503
|
+
// closed slice with a SUMMARY gets the same assessment backfill treatment.
|
|
504
|
+
for (const sliceId of getClosedSliceIds(mid)) {
|
|
514
505
|
const summaryPath = resolveSliceFile(basePath, mid, sliceId, "SUMMARY");
|
|
515
506
|
if (!summaryPath || !existsSync(summaryPath)) continue;
|
|
516
507
|
|
|
@@ -696,7 +687,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
696
687
|
// deadlock. Deep planning is still user-driven even inside auto-mode,
|
|
697
688
|
// so it must wait for explicit approval instead of taking this bypass.
|
|
698
689
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
699
|
-
markDepthVerified(mid, basePath);
|
|
690
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
700
691
|
}
|
|
701
692
|
return {
|
|
702
693
|
action: "dispatch",
|
|
@@ -772,6 +763,16 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
772
763
|
if (browserToolError) {
|
|
773
764
|
return { action: "stop" as const, reason: browserToolError, level: "warning" as const };
|
|
774
765
|
}
|
|
766
|
+
const browserDaemonError = prepareBrowserDaemonForUat({
|
|
767
|
+
uatType,
|
|
768
|
+
sessionProvider,
|
|
769
|
+
sessionAuthMode,
|
|
770
|
+
sessionBaseUrl,
|
|
771
|
+
projectRoot: resolveWorkflowMcpProjectRoot(basePath),
|
|
772
|
+
});
|
|
773
|
+
if (browserDaemonError) {
|
|
774
|
+
return { action: "stop" as const, reason: browserDaemonError, level: "warning" as const };
|
|
775
|
+
}
|
|
775
776
|
|
|
776
777
|
// Cap run-uat dispatch attempts to prevent infinite replay (#3624).
|
|
777
778
|
// Check before incrementing so an exhausted counter cannot create a
|
|
@@ -808,23 +809,10 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
808
809
|
// Only applies when UAT dispatch is enabled
|
|
809
810
|
if (!prefs?.uat_dispatch) return null;
|
|
810
811
|
|
|
811
|
-
// DB-
|
|
812
|
-
|
|
813
|
-
if (isDbAvailable())
|
|
814
|
-
|
|
815
|
-
.filter(s => isClosedStatus(s.status))
|
|
816
|
-
.map(s => s.id);
|
|
817
|
-
} else {
|
|
818
|
-
// Filesystem fallback for degraded / unmigrated projects.
|
|
819
|
-
// `slice.done` in the parsed ROADMAP is the disk-level closed signal.
|
|
820
|
-
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
|
821
|
-
const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
|
|
822
|
-
if (!roadmapContent) return null;
|
|
823
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
824
|
-
closedSliceIds = roadmap.slices.filter(s => s.done).map(s => s.id);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
for (const sliceId of closedSliceIds) {
|
|
812
|
+
// DB-authoritative (ADR-017): closed slices come from the DB only; the
|
|
813
|
+
// ROADMAP projection is never parsed for gate decisions.
|
|
814
|
+
if (!isDbAvailable()) return null;
|
|
815
|
+
for (const sliceId of getClosedSliceIds(mid)) {
|
|
828
816
|
const result = await readUatGateVerdict(basePath, mid, sliceId);
|
|
829
817
|
if (!result) continue;
|
|
830
818
|
const { verdict, uatType } = result;
|
|
@@ -879,7 +867,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
879
867
|
// H6 fix (#4973): keep the non-deep auto-mode bypass, but do not
|
|
880
868
|
// pre-verify deep planning's user-facing milestone approval gate.
|
|
881
869
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
882
|
-
markDepthVerified(mid, basePath);
|
|
870
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
883
871
|
}
|
|
884
872
|
return {
|
|
885
873
|
action: "dispatch",
|
|
@@ -1050,7 +1038,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1050
1038
|
// H6 fix (#4973): keep the non-deep auto-mode bypass, but do not
|
|
1051
1039
|
// pre-verify deep planning's user-facing milestone approval gate.
|
|
1052
1040
|
if (shouldBypassMilestoneDepthGateInAuto(prefs)) {
|
|
1053
|
-
markDepthVerified(mid, basePath);
|
|
1041
|
+
hostWriteGateAdapter.markDepthVerified(mid, basePath);
|
|
1054
1042
|
}
|
|
1055
1043
|
return {
|
|
1056
1044
|
action: "dispatch",
|
|
@@ -1128,13 +1116,11 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1128
1116
|
// behavior.
|
|
1129
1117
|
if (await getMilestonePipelineVariant(mid) === "trivial") return null;
|
|
1130
1118
|
|
|
1131
|
-
//
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if (!roadmapContent) return null;
|
|
1137
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
1119
|
+
// DB-authoritative slice list (ADR-017): the ROADMAP projection is
|
|
1120
|
+
// never parsed for dispatch decisions. No DB / no rows → skip this rule.
|
|
1121
|
+
if (!isDbAvailable()) return null;
|
|
1122
|
+
const dbSlices = getMilestoneSliceSummaries(mid);
|
|
1123
|
+
if (dbSlices.length === 0) return null;
|
|
1138
1124
|
|
|
1139
1125
|
// Find slices that need research (no RESEARCH file, dependencies done)
|
|
1140
1126
|
const milestoneResearchFile =
|
|
@@ -1142,14 +1128,14 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1142
1128
|
resolveMilestoneFile(basePath, mid, "RESEARCH");
|
|
1143
1129
|
const researchReadySlices: Array<{ id: string; title: string }> = [];
|
|
1144
1130
|
|
|
1145
|
-
for (const slice of
|
|
1131
|
+
for (const slice of dbSlices) {
|
|
1146
1132
|
if (slice.done) continue;
|
|
1147
1133
|
// Skip S01 when milestone research exists
|
|
1148
1134
|
if (milestoneResearchFile && slice.id === "S01") continue;
|
|
1149
1135
|
// Skip if already has research
|
|
1150
1136
|
if (resolveExistingExpectedArtifact("research-slice", `${mid}/${slice.id}`, basePath)) continue;
|
|
1151
1137
|
// Skip if dependencies aren't done (check for SUMMARY files)
|
|
1152
|
-
const depsComplete =
|
|
1138
|
+
const depsComplete = slice.depends.every((depId) =>
|
|
1153
1139
|
!!resolveExistingExpectedArtifact("complete-slice", `${mid}/${depId}`, basePath),
|
|
1154
1140
|
);
|
|
1155
1141
|
if (!depsComplete) continue;
|
|
@@ -1041,16 +1041,36 @@ export function resolveModelId<T extends { id: string; provider: string }>(
|
|
|
1041
1041
|
if (providerMatch) return providerMatch;
|
|
1042
1042
|
}
|
|
1043
1043
|
|
|
1044
|
-
//
|
|
1045
|
-
//
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1044
|
+
// Subscription/OAuth routes beat pay-per-token API when the same model ID
|
|
1045
|
+
// exists on multiple providers. Order matters — first match wins.
|
|
1046
|
+
for (const provider of BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE) {
|
|
1047
|
+
const match = candidates.find(m => m.provider === provider);
|
|
1048
|
+
if (match) return match;
|
|
1049
|
+
}
|
|
1049
1050
|
|
|
1050
1051
|
// Fall back to first non-extension candidate, or any candidate
|
|
1051
1052
|
return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
|
|
1052
1053
|
}
|
|
1053
1054
|
|
|
1055
|
+
/**
|
|
1056
|
+
* When a bare model ID exists on multiple providers, prefer subscription/OAuth
|
|
1057
|
+
* routes over pay-per-token API keys. Matches PROVIDER_ROUTES in doctor-providers
|
|
1058
|
+
* but applies when *both* sides are authenticated.
|
|
1059
|
+
*
|
|
1060
|
+
* Order rationale:
|
|
1061
|
+
* - openai-codex before github-copilot: ChatGPT-native for shared GPT IDs
|
|
1062
|
+
* - google-gemini-cli before github-copilot: first-party Gemini CLI
|
|
1063
|
+
* - anthropic before github-copilot: first-party Claude API/OAuth over Copilot
|
|
1064
|
+
* - github-copilot before openai/google: Copilot OAuth over platform API keys
|
|
1065
|
+
*/
|
|
1066
|
+
export const BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE = [
|
|
1067
|
+
"openai-codex",
|
|
1068
|
+
"google-gemini-cli",
|
|
1069
|
+
"anthropic",
|
|
1070
|
+
"github-copilot",
|
|
1071
|
+
"google-antigravity",
|
|
1072
|
+
] as const;
|
|
1073
|
+
|
|
1054
1074
|
/**
|
|
1055
1075
|
* Flat-rate providers charge the same per request regardless of model.
|
|
1056
1076
|
* Dynamic routing provides no cost benefit — it only degrades quality (#3453).
|