@opengsd/gsd-pi 1.1.1-dev.a5a2de8 → 1.1.1-dev.b2556262
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/headless-recover.js +56 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +18 -2
- package/dist/resources/extensions/browser-tools/engine/selection.js +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/index.js +68 -24
- package/dist/resources/extensions/browser-tools/state.js +12 -0
- package/dist/resources/extensions/browser-tools/tools/session.js +3 -2
- package/dist/resources/extensions/browser-tools/utils.js +3 -3
- package/dist/resources/extensions/browser-tools/web-app-detect.js +52 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +87 -12
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +81 -13
- package/dist/resources/extensions/gsd/auto-model-selection.js +154 -9
- package/dist/resources/extensions/gsd/auto-post-unit.js +19 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +26 -21
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -2
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +1 -1
- package/dist/resources/extensions/gsd/auto-timers.js +24 -10
- package/dist/resources/extensions/gsd/auto.js +40 -15
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +192 -77
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/closeout-wizard.js +32 -9
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -9
- package/dist/resources/extensions/gsd/commands-maintenance.js +93 -15
- package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +2 -2
- package/dist/resources/extensions/gsd/config-overlay.js +1 -0
- package/dist/resources/extensions/gsd/context-masker.js +129 -5
- package/dist/resources/extensions/gsd/db-writer.js +35 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +50 -1
- package/dist/resources/extensions/gsd/gsd-db.js +480 -172
- package/dist/resources/extensions/gsd/guided-flow.js +4 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +37 -53
- package/dist/resources/extensions/gsd/md-importer.js +38 -3
- package/dist/resources/extensions/gsd/migration-auto-check.js +126 -31
- package/dist/resources/extensions/gsd/parsers-legacy.js +23 -0
- package/dist/resources/extensions/gsd/planner-handoff.js +98 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +22 -4
- package/dist/resources/extensions/gsd/pre-execution-checks.js +10 -2
- package/dist/resources/extensions/gsd/preferences-models.js +111 -43
- package/dist/resources/extensions/gsd/preferences-types.js +13 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +68 -3
- package/dist/resources/extensions/gsd/preferences.js +4 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- 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/run-uat.md +2 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -1
- package/dist/resources/extensions/gsd/safety/content-validator.js +6 -4
- package/dist/resources/extensions/gsd/skill-manifest.js +12 -0
- package/dist/resources/extensions/gsd/source-observations.js +306 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +15 -8
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +33 -5
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +34 -13
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +39 -14
- package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +4 -4
- package/dist/resources/extensions/gsd/state.js +7 -3
- package/dist/resources/extensions/gsd/tool-contract.js +15 -1
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +24 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +28 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +42 -11
- package/dist/resources/extensions/gsd/tools/plan-task.js +7 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +62 -406
- package/dist/resources/extensions/gsd/uat-policy.js +130 -0
- package/dist/resources/extensions/gsd/uat-run.js +414 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +3 -4
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +38 -14
- package/dist/resources/extensions/gsd/verdict-parser.js +3 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +132 -5
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +8 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +26 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +96 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +18 -17
- package/dist/resources/extensions/shared/gsd-browser-cli.js +6 -0
- package/dist/resources/extensions/subagent/agents.js +1 -0
- package/dist/resources/extensions/subagent/index.js +27 -12
- package/dist/resources/extensions/subagent/launch.js +7 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/@gsd/native/dist/native.js +22 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +4 -4
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +21 -23
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +3 -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 +25 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +66 -12
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.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 +18 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-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 +16 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/dist/native.js +22 -0
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +30 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +30 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +174 -29
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +178 -54
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +8 -1
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/utils.d.ts +11 -0
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +119 -6
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/themes.js +1 -1
- package/pkg/dist/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install/handoff.js +16 -3
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +21 -2
- package/src/resources/extensions/browser-tools/engine/selection.ts +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/index.ts +75 -27
- package/src/resources/extensions/browser-tools/state.ts +13 -0
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +2 -2
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +57 -0
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +37 -0
- package/src/resources/extensions/browser-tools/tests/web-app-detect.test.mjs +68 -0
- package/src/resources/extensions/browser-tools/tools/session.ts +4 -2
- package/src/resources/extensions/browser-tools/utils.ts +3 -3
- package/src/resources/extensions/browser-tools/web-app-detect.ts +63 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +89 -15
- package/src/resources/extensions/gsd/auto/session.ts +24 -1
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +117 -12
- package/src/resources/extensions/gsd/auto-model-selection.ts +190 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +20 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +25 -22
- package/src/resources/extensions/gsd/auto-recovery.ts +22 -3
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +1 -1
- package/src/resources/extensions/gsd/auto-timers.ts +25 -9
- package/src/resources/extensions/gsd/auto.ts +41 -14
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +250 -78
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/closeout-wizard.ts +47 -13
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +2 -17
- package/src/resources/extensions/gsd/commands-maintenance.ts +124 -13
- package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +2 -2
- package/src/resources/extensions/gsd/config-overlay.ts +1 -0
- package/src/resources/extensions/gsd/context-masker.ts +152 -5
- package/src/resources/extensions/gsd/db-writer.ts +38 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +50 -1
- package/src/resources/extensions/gsd/gsd-db.ts +564 -186
- package/src/resources/extensions/gsd/guided-flow.ts +4 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +44 -66
- package/src/resources/extensions/gsd/md-importer.ts +49 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +154 -34
- package/src/resources/extensions/gsd/parsers-legacy.ts +20 -0
- package/src/resources/extensions/gsd/planner-handoff.ts +149 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +22 -4
- package/src/resources/extensions/gsd/pre-execution-checks.ts +9 -2
- package/src/resources/extensions/gsd/preferences-models.ts +113 -43
- package/src/resources/extensions/gsd/preferences-types.ts +47 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +76 -2
- package/src/resources/extensions/gsd/preferences.ts +5 -0
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- 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/run-uat.md +2 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +6 -1
- package/src/resources/extensions/gsd/safety/content-validator.ts +8 -5
- package/src/resources/extensions/gsd/skill-manifest.ts +12 -0
- package/src/resources/extensions/gsd/source-observations.ts +402 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +20 -8
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +44 -5
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +39 -11
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +45 -15
- package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +4 -4
- package/src/resources/extensions/gsd/state.ts +7 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +66 -4
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +299 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +75 -3
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -0
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/closeout-wizard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/content-validator.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +17 -2
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +1 -11
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +99 -2
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/planner-handoff.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +162 -18
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/source-observations.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +76 -21
- package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +77 -10
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +260 -5
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +511 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +44 -0
- package/src/resources/extensions/gsd/tool-contract.ts +29 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +41 -6
- package/src/resources/extensions/gsd/tools/complete-slice.ts +29 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +54 -12
- package/src/resources/extensions/gsd/tools/plan-task.ts +8 -1
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +71 -489
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/uat-policy.ts +191 -0
- package/src/resources/extensions/gsd/uat-run.ts +550 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +3 -4
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +38 -14
- package/src/resources/extensions/gsd/verdict-parser.ts +3 -10
- package/src/resources/extensions/gsd/workflow-manifest.ts +193 -7
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +9 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +32 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +103 -0
- package/src/resources/extensions/gsd/worktree-state-projection.ts +22 -22
- package/src/resources/extensions/shared/gsd-browser-cli.ts +6 -0
- package/src/resources/extensions/shared/tests/format-utils.test.ts +8 -3
- package/src/resources/extensions/subagent/agents.ts +4 -0
- package/src/resources/extensions/subagent/index.ts +28 -3
- package/src/resources/extensions/subagent/launch.ts +8 -0
- package/src/resources/extensions/subagent/tests/model-override.test.ts +31 -0
- /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_ssgManifest.js +0 -0
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import { createRequire } from "node:module";
|
|
25
25
|
import { createHash } from "node:crypto";
|
|
26
26
|
import { existsSync, copyFileSync, mkdirSync, realpathSync } from "node:fs";
|
|
27
|
-
import { dirname } from "node:path";
|
|
27
|
+
import { dirname, join } from "node:path";
|
|
28
28
|
import { GSDError, GSD_STALE_STATE } from "./errors.js";
|
|
29
29
|
import { getGateIdsForTurn } from "./gate-registry.js";
|
|
30
30
|
import { logError, logWarning } from "./workflow-logger.js";
|
|
@@ -683,6 +683,29 @@ export function checkpointDatabase() {
|
|
|
683
683
|
logWarning("db", `WAL checkpoint failed: ${e.message}`);
|
|
684
684
|
}
|
|
685
685
|
}
|
|
686
|
+
/**
|
|
687
|
+
* Copy the live database file to `.gsd/backups/<label>-<timestamp>.db` so a
|
|
688
|
+
* destructive operation (e.g. recover, which clears the hierarchy tables) is
|
|
689
|
+
* reversible. Checkpoints the WAL first so the snapshot is complete. Returns
|
|
690
|
+
* the backup path, or null if no DB is open or the copy failed.
|
|
691
|
+
*/
|
|
692
|
+
export function backupDatabaseSnapshot(label) {
|
|
693
|
+
if (!currentPath)
|
|
694
|
+
return null;
|
|
695
|
+
try {
|
|
696
|
+
checkpointDatabase();
|
|
697
|
+
const backupsDir = join(dirname(currentPath), "backups");
|
|
698
|
+
mkdirSync(backupsDir, { recursive: true });
|
|
699
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
700
|
+
const dest = join(backupsDir, `${label}-${stamp}.db`);
|
|
701
|
+
copyFileSync(currentPath, dest);
|
|
702
|
+
return dest;
|
|
703
|
+
}
|
|
704
|
+
catch (e) {
|
|
705
|
+
logWarning("db", `database snapshot failed: ${e.message}`);
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
686
709
|
const _transactionRunner = createDbTransactionRunner();
|
|
687
710
|
function createTransactionControls(db) {
|
|
688
711
|
return {
|
|
@@ -1083,14 +1106,14 @@ export function insertTask(t) {
|
|
|
1083
1106
|
milestone_id, slice_id, id, title, status, one_liner, narrative,
|
|
1084
1107
|
verification_result, duration, completed_at, blocker_discovered,
|
|
1085
1108
|
deviations, known_issues, key_files, key_decisions, full_summary_md,
|
|
1086
|
-
description, estimate, files, verify, inputs, expected_output,
|
|
1087
|
-
, target_repositories
|
|
1109
|
+
description, estimate, files, verify, inputs, expected_output,
|
|
1110
|
+
observability_impact, full_plan_md, target_repositories, sequence
|
|
1088
1111
|
) VALUES (
|
|
1089
1112
|
:milestone_id, :slice_id, :id, :title, :status, :one_liner, :narrative,
|
|
1090
1113
|
:verification_result, :duration, :completed_at, :blocker_discovered,
|
|
1091
1114
|
:deviations, :known_issues, :key_files, :key_decisions, :full_summary_md,
|
|
1092
|
-
:description, :estimate, :files, :verify, :inputs, :expected_output,
|
|
1093
|
-
, :target_repositories
|
|
1115
|
+
:description, :estimate, :files, :verify, :inputs, :expected_output,
|
|
1116
|
+
:observability_impact, :full_plan_md, :target_repositories, :sequence
|
|
1094
1117
|
)
|
|
1095
1118
|
ON CONFLICT(milestone_id, slice_id, id) DO UPDATE SET
|
|
1096
1119
|
title = CASE WHEN NULLIF(:title, '') IS NOT NULL THEN :title ELSE tasks.title END,
|
|
@@ -1113,6 +1136,7 @@ export function insertTask(t) {
|
|
|
1113
1136
|
inputs = CASE WHEN NULLIF(:inputs, '[]') IS NOT NULL THEN :inputs ELSE tasks.inputs END,
|
|
1114
1137
|
expected_output = CASE WHEN NULLIF(:expected_output, '[]') IS NOT NULL THEN :expected_output ELSE tasks.expected_output END,
|
|
1115
1138
|
observability_impact = CASE WHEN NULLIF(:observability_impact, '') IS NOT NULL THEN :observability_impact ELSE tasks.observability_impact END,
|
|
1139
|
+
full_plan_md = CASE WHEN NULLIF(:full_plan_md, '') IS NOT NULL THEN :full_plan_md ELSE tasks.full_plan_md END,
|
|
1116
1140
|
sequence = :sequence,
|
|
1117
1141
|
target_repositories = CASE
|
|
1118
1142
|
WHEN :raw_target_repositories IS NOT NULL THEN :target_repositories
|
|
@@ -1141,6 +1165,7 @@ export function insertTask(t) {
|
|
|
1141
1165
|
":inputs": JSON.stringify(t.planning?.inputs ?? []),
|
|
1142
1166
|
":expected_output": JSON.stringify(t.planning?.expectedOutput ?? []),
|
|
1143
1167
|
":observability_impact": t.planning?.observabilityImpact ?? "",
|
|
1168
|
+
":full_plan_md": t.planning?.fullPlanMd ?? "",
|
|
1144
1169
|
":sequence": t.sequence ?? 0,
|
|
1145
1170
|
":target_repositories": JSON.stringify(t.planning?.targetRepositories ?? []),
|
|
1146
1171
|
":raw_target_repositories": t.planning && "targetRepositories" in t.planning
|
|
@@ -1581,7 +1606,23 @@ export function copyWorktreeDb(srcDbPath, destDbPath) {
|
|
|
1581
1606
|
}
|
|
1582
1607
|
}
|
|
1583
1608
|
export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
1584
|
-
const zero = {
|
|
1609
|
+
const zero = {
|
|
1610
|
+
decisions: 0,
|
|
1611
|
+
requirements: 0,
|
|
1612
|
+
artifacts: 0,
|
|
1613
|
+
milestones: 0,
|
|
1614
|
+
slices: 0,
|
|
1615
|
+
tasks: 0,
|
|
1616
|
+
memories: 0,
|
|
1617
|
+
replan_history: 0,
|
|
1618
|
+
assessments: 0,
|
|
1619
|
+
quality_gates: 0,
|
|
1620
|
+
slice_dependencies: 0,
|
|
1621
|
+
verification_evidence: 0,
|
|
1622
|
+
gate_runs: 0,
|
|
1623
|
+
milestone_commit_attributions: 0,
|
|
1624
|
+
conflicts: [],
|
|
1625
|
+
};
|
|
1585
1626
|
if (!existsSync(worktreeDbPath))
|
|
1586
1627
|
return zero;
|
|
1587
1628
|
// Guard: bail when both paths resolve to the same physical file.
|
|
@@ -1612,204 +1653,362 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
|
|
|
1612
1653
|
try {
|
|
1613
1654
|
adapter.exec(`ATTACH DATABASE '${worktreeDbPath}' AS wt`);
|
|
1614
1655
|
try {
|
|
1615
|
-
|
|
1656
|
+
function countChanges(result) {
|
|
1657
|
+
return typeof result === "object" && result !== null ? (result.changes ?? 0) : 0;
|
|
1658
|
+
}
|
|
1659
|
+
function wtTableInfo(tableName) {
|
|
1660
|
+
return adapter.prepare(`PRAGMA wt.table_info('${tableName}')`).all();
|
|
1661
|
+
}
|
|
1662
|
+
const wtInfo = wtTableInfo("decisions");
|
|
1663
|
+
const hasWtDecisions = wtInfo.length > 0;
|
|
1616
1664
|
const hasMadeBy = wtInfo.some((col) => col["name"] === "made_by");
|
|
1617
1665
|
// ADR-011: worktree may predate schema v16/v17. For missing columns we
|
|
1618
1666
|
// fall through to the main DB's existing value (not a literal default)
|
|
1619
1667
|
// so reconcile never silently clears state the main tree has recorded.
|
|
1620
1668
|
const hasDecisionSource = wtInfo.some((col) => col["name"] === "source");
|
|
1621
|
-
const
|
|
1669
|
+
const wtRequirementInfo = wtTableInfo("requirements");
|
|
1670
|
+
const hasWtRequirements = wtRequirementInfo.length > 0;
|
|
1671
|
+
const wtMilestoneInfo = wtTableInfo("milestones");
|
|
1672
|
+
const hasWtMilestones = wtMilestoneInfo.length > 0;
|
|
1622
1673
|
const hasMilestoneSequence = wtMilestoneInfo.some((col) => col["name"] === "sequence");
|
|
1623
|
-
const wtSliceInfo =
|
|
1674
|
+
const wtSliceInfo = wtTableInfo("slices");
|
|
1675
|
+
const hasWtSlices = wtSliceInfo.length > 0;
|
|
1624
1676
|
const hasIsSketch = wtSliceInfo.some((col) => col["name"] === "is_sketch");
|
|
1625
1677
|
const hasSketchScope = wtSliceInfo.some((col) => col["name"] === "sketch_scope");
|
|
1626
1678
|
const hasSliceTargetRepositories = wtSliceInfo.some((col) => col["name"] === "target_repositories");
|
|
1627
|
-
const wtTaskInfo =
|
|
1679
|
+
const wtTaskInfo = wtTableInfo("tasks");
|
|
1680
|
+
const hasWtTasks = wtTaskInfo.length > 0;
|
|
1628
1681
|
const hasTaskTargetRepositories = wtTaskInfo.some((col) => col["name"] === "target_repositories");
|
|
1629
1682
|
const hasBlockerSource = wtTaskInfo.some((col) => col["name"] === "blocker_source");
|
|
1630
1683
|
const hasEscalationPending = wtTaskInfo.some((col) => col["name"] === "escalation_pending");
|
|
1631
1684
|
const hasEscalationAwaiting = wtTaskInfo.some((col) => col["name"] === "escalation_awaiting_review");
|
|
1632
1685
|
const hasEscalationArtifact = wtTaskInfo.some((col) => col["name"] === "escalation_artifact_path");
|
|
1633
1686
|
const hasEscalationOverride = wtTaskInfo.some((col) => col["name"] === "escalation_override_applied_at");
|
|
1634
|
-
const wtArtifactInfo =
|
|
1635
|
-
const
|
|
1636
|
-
const wtMemoryInfo =
|
|
1687
|
+
const wtArtifactInfo = wtTableInfo("artifacts");
|
|
1688
|
+
const hasWtArtifacts = wtArtifactInfo.length > 0;
|
|
1689
|
+
const wtMemoryInfo = wtTableInfo("memories");
|
|
1690
|
+
const hasWtMemories = wtMemoryInfo.length > 0;
|
|
1637
1691
|
const hasMemoryScope = wtMemoryInfo.some((col) => col["name"] === "scope");
|
|
1638
1692
|
const hasMemoryTags = wtMemoryInfo.some((col) => col["name"] === "tags");
|
|
1639
1693
|
const hasMemoryStructuredFields = wtMemoryInfo.some((col) => col["name"] === "structured_fields");
|
|
1640
1694
|
const hasMemoryLastHitAt = wtMemoryInfo.some((col) => col["name"] === "last_hit_at");
|
|
1641
|
-
const
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
const
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
const
|
|
1648
|
-
|
|
1649
|
-
|
|
1695
|
+
const hasWtReplanHistory = wtTableInfo("replan_history").length > 0;
|
|
1696
|
+
const hasWtAssessments = wtTableInfo("assessments").length > 0;
|
|
1697
|
+
const hasWtQualityGates = wtTableInfo("quality_gates").length > 0;
|
|
1698
|
+
const hasWtSliceDependencies = wtTableInfo("slice_dependencies").length > 0;
|
|
1699
|
+
const hasWtVerificationEvidence = wtTableInfo("verification_evidence").length > 0;
|
|
1700
|
+
const hasWtGateRuns = wtTableInfo("gate_runs").length > 0;
|
|
1701
|
+
const hasWtMilestoneCommitAttributions = wtTableInfo("milestone_commit_attributions").length > 0;
|
|
1702
|
+
if (hasWtDecisions) {
|
|
1703
|
+
const decConf = adapter.prepare(`SELECT m.id FROM decisions m INNER JOIN wt.decisions w ON m.id = w.id WHERE m.decision != w.decision OR m.choice != w.choice OR m.rationale != w.rationale OR ${hasMadeBy ? "m.made_by != w.made_by" : "'agent' != 'agent'"} OR m.superseded_by IS NOT w.superseded_by`).all();
|
|
1704
|
+
for (const row of decConf)
|
|
1705
|
+
conflicts.push(`decision ${row["id"]}: modified in both`);
|
|
1706
|
+
}
|
|
1707
|
+
if (hasWtRequirements) {
|
|
1708
|
+
const reqConf = adapter.prepare(`SELECT m.id FROM requirements m INNER JOIN wt.requirements w ON m.id = w.id WHERE m.description != w.description OR m.status != w.status OR m.notes != w.notes OR m.superseded_by IS NOT w.superseded_by`).all();
|
|
1709
|
+
for (const row of reqConf)
|
|
1710
|
+
conflicts.push(`requirement ${row["id"]}: modified in both`);
|
|
1650
1711
|
}
|
|
1712
|
+
const merged = {
|
|
1713
|
+
decisions: 0,
|
|
1714
|
+
requirements: 0,
|
|
1715
|
+
artifacts: 0,
|
|
1716
|
+
milestones: 0,
|
|
1717
|
+
slices: 0,
|
|
1718
|
+
tasks: 0,
|
|
1719
|
+
memories: 0,
|
|
1720
|
+
replan_history: 0,
|
|
1721
|
+
assessments: 0,
|
|
1722
|
+
quality_gates: 0,
|
|
1723
|
+
slice_dependencies: 0,
|
|
1724
|
+
verification_evidence: 0,
|
|
1725
|
+
gate_runs: 0,
|
|
1726
|
+
milestone_commit_attributions: 0,
|
|
1727
|
+
};
|
|
1728
|
+
const sliceTargetRepositoriesSql = hasSliceTargetRepositories
|
|
1729
|
+
? `CASE
|
|
1730
|
+
WHEN w.target_repositories = '[]' AND COALESCE(m.target_repositories, '[]') <> '[]'
|
|
1731
|
+
THEN m.target_repositories
|
|
1732
|
+
ELSE COALESCE(w.target_repositories, m.target_repositories, '[]')
|
|
1733
|
+
END`
|
|
1734
|
+
: "COALESCE(m.target_repositories, '[]')";
|
|
1735
|
+
const taskTargetRepositoriesSql = hasTaskTargetRepositories
|
|
1736
|
+
? `CASE
|
|
1737
|
+
WHEN w.target_repositories = '[]' AND COALESCE(m.target_repositories, '[]') <> '[]'
|
|
1738
|
+
THEN m.target_repositories
|
|
1739
|
+
ELSE COALESCE(w.target_repositories, m.target_repositories, '[]')
|
|
1740
|
+
END`
|
|
1741
|
+
: "COALESCE(m.target_repositories, '[]')";
|
|
1651
1742
|
adapter.exec("BEGIN");
|
|
1652
1743
|
try {
|
|
1653
1744
|
// Join the target decisions so we can prefer an existing main.source
|
|
1654
1745
|
// when the worktree predates v16 — otherwise a write-through reconcile
|
|
1655
1746
|
// would clobber 'escalation'-sourced decisions with the literal default.
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1747
|
+
if (hasWtDecisions) {
|
|
1748
|
+
merged.decisions = countChanges(adapter.prepare(`
|
|
1749
|
+
INSERT INTO decisions (
|
|
1750
|
+
id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by
|
|
1751
|
+
)
|
|
1752
|
+
SELECT w.id, w.when_context, w.scope, w.decision, w.choice, w.rationale, w.revisable, ${hasMadeBy ? "w.made_by" : "COALESCE(m.made_by, 'agent')"}, ${hasDecisionSource ? "w.source" : "COALESCE(m.source, 'discussion')"}, w.superseded_by
|
|
1753
|
+
FROM wt.decisions w
|
|
1754
|
+
LEFT JOIN decisions m ON m.id = w.id
|
|
1755
|
+
WHERE true
|
|
1756
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
1757
|
+
when_context = excluded.when_context,
|
|
1758
|
+
scope = excluded.scope,
|
|
1759
|
+
decision = excluded.decision,
|
|
1760
|
+
choice = excluded.choice,
|
|
1761
|
+
rationale = excluded.rationale,
|
|
1762
|
+
revisable = excluded.revisable,
|
|
1763
|
+
made_by = excluded.made_by,
|
|
1764
|
+
source = excluded.source,
|
|
1765
|
+
superseded_by = excluded.superseded_by
|
|
1766
|
+
`).run());
|
|
1767
|
+
}
|
|
1768
|
+
if (hasWtRequirements) {
|
|
1769
|
+
merged.requirements = countChanges(adapter.prepare(`
|
|
1770
|
+
INSERT OR REPLACE INTO requirements (
|
|
1771
|
+
id, class, status, description, why, source, primary_owner,
|
|
1772
|
+
supporting_slices, validation, notes, full_content, superseded_by
|
|
1773
|
+
)
|
|
1774
|
+
SELECT id, class, status, description, why, source, primary_owner,
|
|
1775
|
+
supporting_slices, validation, notes, full_content, superseded_by
|
|
1776
|
+
FROM wt.requirements
|
|
1777
|
+
`).run());
|
|
1778
|
+
}
|
|
1779
|
+
// Always recompute artifact hashes from the content being merged. Older
|
|
1780
|
+
// worktree DBs may not have content_hash at all, and migrated old DBs can
|
|
1781
|
+
// carry stale default/null hashes after their content changed.
|
|
1782
|
+
if (hasWtArtifacts) {
|
|
1783
|
+
const artifactRows = adapter.prepare(`
|
|
1784
|
+
SELECT path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at
|
|
1785
|
+
FROM wt.artifacts
|
|
1786
|
+
`).all();
|
|
1787
|
+
const artifactStmt = adapter.prepare(`
|
|
1788
|
+
INSERT OR REPLACE INTO artifacts (
|
|
1789
|
+
path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at, content_hash
|
|
1790
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1791
|
+
`);
|
|
1792
|
+
for (const row of artifactRows) {
|
|
1793
|
+
const fullContent = String(row["full_content"] ?? "");
|
|
1794
|
+
merged.artifacts += countChanges(artifactStmt.run(row["path"], row["artifact_type"], row["milestone_id"] ?? null, row["slice_id"] ?? null, row["task_id"] ?? null, fullContent, row["imported_at"], createHash("sha256").update(fullContent).digest("hex")));
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1685
1797
|
// Merge milestones — worktree may have updated status/planning fields.
|
|
1686
1798
|
// Never downgrade status: complete > active > pre-planning (#4372).
|
|
1687
1799
|
// A stale worktree may carry an older 'active' status for a milestone
|
|
1688
1800
|
// that the main DB has already marked 'complete'; preserve the higher status.
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1801
|
+
if (hasWtMilestones) {
|
|
1802
|
+
merged.milestones = countChanges(adapter.prepare(`
|
|
1803
|
+
INSERT OR REPLACE INTO milestones (
|
|
1804
|
+
id, title, status, depends_on, created_at, completed_at,
|
|
1805
|
+
vision, success_criteria, key_risks, proof_strategy,
|
|
1806
|
+
verification_contract, verification_integration, verification_operational, verification_uat,
|
|
1807
|
+
definition_of_done, requirement_coverage, boundary_map_markdown, sequence
|
|
1808
|
+
)
|
|
1809
|
+
SELECT w.id, w.title,
|
|
1810
|
+
CASE
|
|
1811
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1812
|
+
THEN m.status ELSE w.status
|
|
1813
|
+
END,
|
|
1814
|
+
w.depends_on,
|
|
1815
|
+
CASE
|
|
1816
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1817
|
+
THEN m.created_at ELSE w.created_at
|
|
1818
|
+
END,
|
|
1819
|
+
CASE
|
|
1820
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1821
|
+
THEN m.completed_at ELSE w.completed_at
|
|
1822
|
+
END,
|
|
1823
|
+
w.vision, w.success_criteria, w.key_risks, w.proof_strategy,
|
|
1824
|
+
w.verification_contract, w.verification_integration, w.verification_operational, w.verification_uat,
|
|
1825
|
+
w.definition_of_done, w.requirement_coverage, w.boundary_map_markdown,
|
|
1826
|
+
${hasMilestoneSequence ? "COALESCE(w.sequence, 0)" : "COALESCE(m.sequence, 0)"}
|
|
1827
|
+
FROM wt.milestones w
|
|
1828
|
+
LEFT JOIN milestones m ON m.id = w.id
|
|
1829
|
+
`).run());
|
|
1830
|
+
}
|
|
1717
1831
|
// Merge slices — preserve worktree progress but never downgrade completed status (#2558).
|
|
1718
1832
|
// ADR-011 Phase 1: carry is_sketch + sketch_scope so reconcile doesn't
|
|
1719
1833
|
// silently clear sketch metadata. When the worktree predates v16,
|
|
1720
1834
|
// fall back to the main DB's existing value rather than a literal 0/''.
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1835
|
+
if (hasWtSlices) {
|
|
1836
|
+
merged.slices = countChanges(adapter.prepare(`
|
|
1837
|
+
INSERT OR REPLACE INTO slices (
|
|
1838
|
+
milestone_id, id, title, status, risk, depends, demo, created_at, completed_at,
|
|
1839
|
+
full_summary_md, full_uat_md, goal, success_criteria, proof_level,
|
|
1840
|
+
integration_closure, observability_impact, target_repositories, sequence, replan_triggered_at,
|
|
1841
|
+
is_sketch, sketch_scope
|
|
1842
|
+
)
|
|
1843
|
+
SELECT w.milestone_id, w.id, w.title,
|
|
1844
|
+
CASE
|
|
1845
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1846
|
+
THEN m.status ELSE w.status
|
|
1847
|
+
END,
|
|
1848
|
+
w.risk, w.depends, w.demo, w.created_at,
|
|
1849
|
+
CASE
|
|
1850
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1851
|
+
THEN m.completed_at ELSE w.completed_at
|
|
1852
|
+
END,
|
|
1853
|
+
w.full_summary_md, w.full_uat_md, w.goal, w.success_criteria, w.proof_level,
|
|
1854
|
+
w.integration_closure, w.observability_impact,
|
|
1855
|
+
${sliceTargetRepositoriesSql},
|
|
1856
|
+
w.sequence, w.replan_triggered_at,
|
|
1857
|
+
${hasIsSketch ? "w.is_sketch" : "COALESCE(m.is_sketch, 0)"},
|
|
1858
|
+
${hasSketchScope ? "w.sketch_scope" : "COALESCE(m.sketch_scope, '')"}
|
|
1859
|
+
FROM wt.slices w
|
|
1860
|
+
LEFT JOIN slices m ON m.milestone_id = w.milestone_id AND m.id = w.id
|
|
1861
|
+
`).run());
|
|
1862
|
+
}
|
|
1747
1863
|
// Merge tasks — preserve execution results, never downgrade completed status (#2558).
|
|
1748
1864
|
// ADR-011 P2: carry blocker_source + escalation_* columns so worktree reconcile
|
|
1749
1865
|
// doesn't silently clear escalation state back to defaults.
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1866
|
+
if (hasWtTasks) {
|
|
1867
|
+
merged.tasks = countChanges(adapter.prepare(`
|
|
1868
|
+
INSERT OR REPLACE INTO tasks (
|
|
1869
|
+
milestone_id, slice_id, id, title, status, one_liner, narrative,
|
|
1870
|
+
verification_result, duration, completed_at, blocker_discovered,
|
|
1871
|
+
deviations, known_issues, key_files, key_decisions, full_summary_md,
|
|
1872
|
+
description, estimate, files, verify, inputs, expected_output,
|
|
1873
|
+
observability_impact, full_plan_md, target_repositories, sequence,
|
|
1874
|
+
blocker_source, escalation_pending, escalation_awaiting_review,
|
|
1875
|
+
escalation_artifact_path, escalation_override_applied_at
|
|
1876
|
+
)
|
|
1877
|
+
SELECT w.milestone_id, w.slice_id, w.id, w.title,
|
|
1878
|
+
CASE
|
|
1879
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1880
|
+
THEN m.status ELSE w.status
|
|
1881
|
+
END,
|
|
1882
|
+
w.one_liner, w.narrative,
|
|
1883
|
+
w.verification_result, w.duration,
|
|
1884
|
+
CASE
|
|
1885
|
+
WHEN m.status IN (${TERMINAL_STATUS_SQL}) AND w.status NOT IN (${TERMINAL_STATUS_SQL})
|
|
1886
|
+
THEN m.completed_at ELSE w.completed_at
|
|
1887
|
+
END,
|
|
1888
|
+
w.blocker_discovered,
|
|
1889
|
+
w.deviations, w.known_issues, w.key_files, w.key_decisions, w.full_summary_md,
|
|
1890
|
+
w.description, w.estimate, w.files, w.verify, w.inputs, w.expected_output,
|
|
1891
|
+
w.observability_impact, w.full_plan_md,
|
|
1892
|
+
${taskTargetRepositoriesSql},
|
|
1893
|
+
w.sequence,
|
|
1894
|
+
${hasBlockerSource ? "w.blocker_source" : "COALESCE(m.blocker_source, '')"},
|
|
1895
|
+
${hasEscalationPending ? "w.escalation_pending" : "COALESCE(m.escalation_pending, 0)"},
|
|
1896
|
+
${hasEscalationAwaiting ? "w.escalation_awaiting_review" : "COALESCE(m.escalation_awaiting_review, 0)"},
|
|
1897
|
+
${hasEscalationArtifact ? "w.escalation_artifact_path" : "m.escalation_artifact_path"},
|
|
1898
|
+
${hasEscalationOverride ? "w.escalation_override_applied_at" : "m.escalation_override_applied_at"}
|
|
1899
|
+
FROM wt.tasks w
|
|
1900
|
+
LEFT JOIN tasks m ON m.milestone_id = w.milestone_id AND m.slice_id = w.slice_id AND m.id = w.id
|
|
1901
|
+
`).run());
|
|
1902
|
+
}
|
|
1785
1903
|
// Merge memories — keep worktree-learned insights.
|
|
1786
1904
|
// V18 (scope, tags), V21 (structured_fields), V28 (last_hit_at): for each
|
|
1787
1905
|
// column the wt may not yet have (older worktree DB), fall back to the
|
|
1788
1906
|
// main DB's existing value via LEFT JOIN so reconcile never silently
|
|
1789
1907
|
// resets these fields to defaults on rows that already had them.
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1908
|
+
if (hasWtMemories) {
|
|
1909
|
+
merged.memories = countChanges(adapter.prepare(`
|
|
1910
|
+
INSERT OR REPLACE INTO memories (
|
|
1911
|
+
seq, id, category, content, confidence, source_unit_type, source_unit_id,
|
|
1912
|
+
created_at, updated_at, superseded_by, hit_count,
|
|
1913
|
+
scope, tags, structured_fields, last_hit_at
|
|
1914
|
+
)
|
|
1915
|
+
SELECT w.seq, w.id, w.category, w.content, w.confidence, w.source_unit_type, w.source_unit_id,
|
|
1916
|
+
w.created_at, w.updated_at, w.superseded_by, w.hit_count,
|
|
1917
|
+
${hasMemoryScope ? "w.scope" : "COALESCE(m.scope, 'project')"},
|
|
1918
|
+
${hasMemoryTags ? "w.tags" : "COALESCE(m.tags, '[]')"},
|
|
1919
|
+
${hasMemoryStructuredFields ? "w.structured_fields" : "m.structured_fields"},
|
|
1920
|
+
${hasMemoryLastHitAt ? "w.last_hit_at" : "m.last_hit_at"}
|
|
1921
|
+
FROM wt.memories w
|
|
1922
|
+
LEFT JOIN memories m ON m.id = w.id
|
|
1923
|
+
`).run());
|
|
1924
|
+
}
|
|
1925
|
+
if (hasWtReplanHistory) {
|
|
1926
|
+
merged.replan_history = countChanges(adapter.prepare(`
|
|
1927
|
+
INSERT INTO replan_history (
|
|
1928
|
+
milestone_id, slice_id, task_id, summary, previous_artifact_path, replacement_artifact_path, created_at
|
|
1929
|
+
)
|
|
1930
|
+
SELECT w.milestone_id, w.slice_id, w.task_id, w.summary, w.previous_artifact_path, w.replacement_artifact_path, w.created_at
|
|
1931
|
+
FROM wt.replan_history w
|
|
1932
|
+
WHERE EXISTS (SELECT 1 FROM milestones m WHERE m.id = w.milestone_id)
|
|
1933
|
+
AND NOT EXISTS (
|
|
1934
|
+
SELECT 1 FROM replan_history m
|
|
1935
|
+
WHERE m.milestone_id = w.milestone_id
|
|
1936
|
+
AND m.slice_id IS w.slice_id
|
|
1937
|
+
AND m.task_id IS w.task_id
|
|
1938
|
+
AND m.summary = w.summary
|
|
1939
|
+
AND m.previous_artifact_path IS w.previous_artifact_path
|
|
1940
|
+
AND m.replacement_artifact_path IS w.replacement_artifact_path
|
|
1941
|
+
)
|
|
1942
|
+
`).run());
|
|
1943
|
+
}
|
|
1944
|
+
if (hasWtAssessments) {
|
|
1945
|
+
merged.assessments = countChanges(adapter.prepare(`
|
|
1946
|
+
INSERT OR REPLACE INTO assessments (
|
|
1947
|
+
path, milestone_id, slice_id, task_id, status, scope, full_content, created_at
|
|
1948
|
+
)
|
|
1949
|
+
SELECT w.path, w.milestone_id, w.slice_id, w.task_id, w.status, w.scope, w.full_content, w.created_at
|
|
1950
|
+
FROM wt.assessments w
|
|
1951
|
+
WHERE EXISTS (SELECT 1 FROM milestones m WHERE m.id = w.milestone_id)
|
|
1952
|
+
`).run());
|
|
1953
|
+
}
|
|
1954
|
+
if (hasWtQualityGates) {
|
|
1955
|
+
merged.quality_gates = countChanges(adapter.prepare(`
|
|
1956
|
+
INSERT OR REPLACE INTO quality_gates (
|
|
1957
|
+
milestone_id, slice_id, gate_id, scope, task_id, status, verdict, rationale, findings, evaluated_at
|
|
1958
|
+
)
|
|
1959
|
+
SELECT w.milestone_id, w.slice_id, w.gate_id, w.scope, COALESCE(w.task_id, ''), w.status, w.verdict, w.rationale, w.findings, w.evaluated_at
|
|
1960
|
+
FROM wt.quality_gates w
|
|
1961
|
+
WHERE EXISTS (SELECT 1 FROM slices s WHERE s.milestone_id = w.milestone_id AND s.id = w.slice_id)
|
|
1962
|
+
`).run());
|
|
1963
|
+
}
|
|
1964
|
+
if (hasWtSliceDependencies) {
|
|
1965
|
+
merged.slice_dependencies = countChanges(adapter.prepare(`
|
|
1966
|
+
INSERT OR IGNORE INTO slice_dependencies (milestone_id, slice_id, depends_on_slice_id)
|
|
1967
|
+
SELECT w.milestone_id, w.slice_id, w.depends_on_slice_id
|
|
1968
|
+
FROM wt.slice_dependencies w
|
|
1969
|
+
WHERE EXISTS (SELECT 1 FROM slices s WHERE s.milestone_id = w.milestone_id AND s.id = w.slice_id)
|
|
1970
|
+
AND EXISTS (SELECT 1 FROM slices d WHERE d.milestone_id = w.milestone_id AND d.id = w.depends_on_slice_id)
|
|
1971
|
+
`).run());
|
|
1972
|
+
}
|
|
1805
1973
|
// Merge verification evidence — append-only, use INSERT OR IGNORE to avoid duplicates
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1974
|
+
if (hasWtVerificationEvidence) {
|
|
1975
|
+
merged.verification_evidence = countChanges(adapter.prepare(`
|
|
1976
|
+
INSERT OR IGNORE INTO verification_evidence (
|
|
1977
|
+
task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
|
|
1978
|
+
)
|
|
1979
|
+
SELECT task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
|
|
1980
|
+
FROM wt.verification_evidence
|
|
1981
|
+
`).run());
|
|
1982
|
+
}
|
|
1983
|
+
if (hasWtGateRuns) {
|
|
1984
|
+
merged.gate_runs = countChanges(adapter.prepare(`
|
|
1985
|
+
INSERT INTO gate_runs (
|
|
1986
|
+
trace_id, turn_id, gate_id, gate_type, unit_type, unit_id, milestone_id, slice_id, task_id,
|
|
1987
|
+
outcome, failure_class, rationale, findings, attempt, max_attempts, retryable, evaluated_at
|
|
1988
|
+
)
|
|
1989
|
+
SELECT w.trace_id, w.turn_id, w.gate_id, w.gate_type, w.unit_type, w.unit_id, w.milestone_id, w.slice_id, w.task_id,
|
|
1990
|
+
w.outcome, w.failure_class, w.rationale, w.findings, w.attempt, w.max_attempts, w.retryable, w.evaluated_at
|
|
1991
|
+
FROM wt.gate_runs w
|
|
1992
|
+
WHERE NOT EXISTS (
|
|
1993
|
+
SELECT 1 FROM gate_runs m
|
|
1994
|
+
WHERE m.trace_id = w.trace_id
|
|
1995
|
+
AND m.turn_id = w.turn_id
|
|
1996
|
+
AND m.gate_id = w.gate_id
|
|
1997
|
+
AND m.attempt = w.attempt
|
|
1998
|
+
AND m.evaluated_at = w.evaluated_at
|
|
1999
|
+
)
|
|
2000
|
+
`).run());
|
|
2001
|
+
}
|
|
2002
|
+
if (hasWtMilestoneCommitAttributions) {
|
|
2003
|
+
merged.milestone_commit_attributions = countChanges(adapter.prepare(`
|
|
2004
|
+
INSERT OR REPLACE INTO milestone_commit_attributions (
|
|
2005
|
+
commit_sha, milestone_id, slice_id, task_id, source, confidence, files_json, created_at
|
|
2006
|
+
)
|
|
2007
|
+
SELECT w.commit_sha, w.milestone_id, w.slice_id, w.task_id, w.source, w.confidence, w.files_json, w.created_at
|
|
2008
|
+
FROM wt.milestone_commit_attributions w
|
|
2009
|
+
WHERE EXISTS (SELECT 1 FROM milestones m WHERE m.id = w.milestone_id)
|
|
2010
|
+
`).run());
|
|
2011
|
+
}
|
|
1813
2012
|
adapter.exec("COMMIT");
|
|
1814
2013
|
}
|
|
1815
2014
|
catch (txErr) {
|
|
@@ -1979,11 +2178,12 @@ export function insertGateRow(g) {
|
|
|
1979
2178
|
export function saveGateResult(g) {
|
|
1980
2179
|
if (!currentDb)
|
|
1981
2180
|
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
1982
|
-
|
|
2181
|
+
const evaluatedAt = new Date().toISOString();
|
|
2182
|
+
const result = currentDb.prepare(`UPDATE quality_gates
|
|
1983
2183
|
SET status = 'complete', verdict = :verdict, rationale = :rationale,
|
|
1984
2184
|
findings = :findings, evaluated_at = :evaluated_at
|
|
1985
2185
|
WHERE milestone_id = :mid AND slice_id = :sid AND gate_id = :gid
|
|
1986
|
-
AND task_id = :tid`).run({
|
|
2186
|
+
AND (task_id = :tid OR (:tid = '' AND task_id IS NULL))`).run({
|
|
1987
2187
|
":mid": g.milestoneId,
|
|
1988
2188
|
":sid": g.sliceId,
|
|
1989
2189
|
":gid": g.gateId,
|
|
@@ -1991,8 +2191,11 @@ export function saveGateResult(g) {
|
|
|
1991
2191
|
":verdict": g.verdict,
|
|
1992
2192
|
":rationale": g.rationale,
|
|
1993
2193
|
":findings": g.findings,
|
|
1994
|
-
":evaluated_at":
|
|
2194
|
+
":evaluated_at": evaluatedAt,
|
|
1995
2195
|
});
|
|
2196
|
+
if ((result.changes ?? 0) === 0) {
|
|
2197
|
+
throw new GSDError(GSD_STALE_STATE, `quality gate row not found for ${g.milestoneId}/${g.sliceId}/${g.gateId}${g.taskId ? `/${g.taskId}` : ""}`);
|
|
2198
|
+
}
|
|
1996
2199
|
const outcome = g.verdict === "pass"
|
|
1997
2200
|
? "pass"
|
|
1998
2201
|
: g.verdict === "omitted"
|
|
@@ -2013,7 +2216,7 @@ export function saveGateResult(g) {
|
|
|
2013
2216
|
attempt: 1,
|
|
2014
2217
|
maxAttempts: 1,
|
|
2015
2218
|
retryable: false,
|
|
2016
|
-
evaluatedAt
|
|
2219
|
+
evaluatedAt,
|
|
2017
2220
|
});
|
|
2018
2221
|
}
|
|
2019
2222
|
export function getPendingGates(milestoneId, sliceId, scope) {
|
|
@@ -2048,6 +2251,25 @@ export function markAllGatesOmitted(milestoneId, sliceId) {
|
|
|
2048
2251
|
":now": new Date().toISOString(),
|
|
2049
2252
|
});
|
|
2050
2253
|
}
|
|
2254
|
+
export function markPendingGatesOmittedForTurn(milestoneId, sliceId, turn) {
|
|
2255
|
+
if (!currentDb)
|
|
2256
|
+
return;
|
|
2257
|
+
const gateIds = [...getGateIdsForTurn(turn)];
|
|
2258
|
+
if (gateIds.length === 0)
|
|
2259
|
+
return;
|
|
2260
|
+
const placeholders = gateIds.map((_, i) => `:gid${i}`).join(",");
|
|
2261
|
+
const params = {
|
|
2262
|
+
":mid": milestoneId,
|
|
2263
|
+
":sid": sliceId,
|
|
2264
|
+
":now": new Date().toISOString(),
|
|
2265
|
+
};
|
|
2266
|
+
gateIds.forEach((id, index) => {
|
|
2267
|
+
params[`:gid${index}`] = id;
|
|
2268
|
+
});
|
|
2269
|
+
currentDb.prepare(`UPDATE quality_gates SET status = 'complete', verdict = 'omitted', evaluated_at = :now
|
|
2270
|
+
WHERE milestone_id = :mid AND slice_id = :sid AND status = 'pending'
|
|
2271
|
+
AND gate_id IN (${placeholders})`).run(params);
|
|
2272
|
+
}
|
|
2051
2273
|
export function getPendingSliceGateCount(milestoneId, sliceId) {
|
|
2052
2274
|
if (!currentDb)
|
|
2053
2275
|
return 0;
|
|
@@ -2358,21 +2580,64 @@ export function upsertQualityGate(g) {
|
|
|
2358
2580
|
}
|
|
2359
2581
|
/**
|
|
2360
2582
|
* Atomically replace all workflow state from a manifest. Lifted verbatim from
|
|
2361
|
-
* workflow-manifest.ts so the single-writer invariant holds.
|
|
2362
|
-
*
|
|
2583
|
+
* workflow-manifest.ts so the single-writer invariant holds. Restores
|
|
2584
|
+
* correctness-bearing workflow tables; runtime soft state and append-only audit
|
|
2585
|
+
* streams stay outside this recovery path.
|
|
2363
2586
|
*/
|
|
2364
2587
|
export function restoreManifest(manifest) {
|
|
2365
2588
|
if (!currentDb)
|
|
2366
2589
|
throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
|
|
2367
2590
|
const db = currentDb;
|
|
2368
2591
|
transaction(() => {
|
|
2369
|
-
|
|
2592
|
+
const restoredMilestoneIds = new Set(manifest.milestones.map((m) => m.id));
|
|
2593
|
+
const restoredSliceKeys = new Set(manifest.slices.map((s) => JSON.stringify([s.milestone_id, s.id])));
|
|
2594
|
+
const preservedReplanHistory = manifest.replan_history === undefined
|
|
2595
|
+
? db.prepare("SELECT * FROM replan_history ORDER BY id").all()
|
|
2596
|
+
: [];
|
|
2597
|
+
const preservedAssessments = manifest.assessments === undefined
|
|
2598
|
+
? db.prepare("SELECT * FROM assessments ORDER BY path").all()
|
|
2599
|
+
: [];
|
|
2600
|
+
const preservedQualityGates = manifest.quality_gates === undefined
|
|
2601
|
+
? db.prepare("SELECT * FROM quality_gates ORDER BY milestone_id, slice_id, gate_id, task_id").all()
|
|
2602
|
+
: [];
|
|
2603
|
+
const preservedCommitAttributions = manifest.milestone_commit_attributions === undefined
|
|
2604
|
+
? db.prepare("SELECT * FROM milestone_commit_attributions ORDER BY milestone_id, commit_sha").all()
|
|
2605
|
+
: [];
|
|
2606
|
+
// Clear workflow tables in dependency order.
|
|
2370
2607
|
db.exec("DELETE FROM verification_evidence");
|
|
2608
|
+
db.exec("DELETE FROM quality_gates");
|
|
2609
|
+
db.exec("DELETE FROM slice_dependencies");
|
|
2610
|
+
db.exec("DELETE FROM assessments");
|
|
2611
|
+
db.exec("DELETE FROM replan_history");
|
|
2612
|
+
db.exec("DELETE FROM milestone_commit_attributions");
|
|
2371
2613
|
db.exec("DELETE FROM tasks");
|
|
2372
2614
|
db.exec("DELETE FROM slices");
|
|
2373
2615
|
db.exec("DELETE FROM milestone_leases");
|
|
2374
2616
|
db.exec("DELETE FROM milestones");
|
|
2375
2617
|
db.exec("DELETE FROM decisions WHERE 1=1");
|
|
2618
|
+
db.exec(`DELETE FROM memories WHERE category = 'architecture' AND structured_fields LIKE '%"sourceDecisionId":"%'`);
|
|
2619
|
+
if (manifest.artifacts !== undefined)
|
|
2620
|
+
db.exec("DELETE FROM artifacts");
|
|
2621
|
+
if (manifest.requirements !== undefined)
|
|
2622
|
+
db.exec("DELETE FROM requirements");
|
|
2623
|
+
if (manifest.requirements !== undefined) {
|
|
2624
|
+
const reqStmt = db.prepare(`INSERT INTO requirements (
|
|
2625
|
+
id, class, status, description, why, source, primary_owner,
|
|
2626
|
+
supporting_slices, validation, notes, full_content, superseded_by
|
|
2627
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2628
|
+
for (const r of manifest.requirements) {
|
|
2629
|
+
reqStmt.run(r.id, r.class, r.status, r.description, r.why, r.source, r.primary_owner, r.supporting_slices, r.validation, r.notes, r.full_content, r.superseded_by);
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
if (manifest.artifacts !== undefined) {
|
|
2633
|
+
const artStmt = db.prepare(`INSERT INTO artifacts (
|
|
2634
|
+
path, artifact_type, milestone_id, slice_id, task_id, full_content, imported_at, content_hash
|
|
2635
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2636
|
+
for (const a of manifest.artifacts) {
|
|
2637
|
+
const fullContent = a.full_content ?? "";
|
|
2638
|
+
artStmt.run(a.path, a.artifact_type, a.milestone_id, a.slice_id, a.task_id, fullContent, a.imported_at, a.content_hash ?? createHash("sha256").update(fullContent).digest("hex"));
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2376
2641
|
// Restore milestones
|
|
2377
2642
|
const msStmt = db.prepare(`INSERT INTO milestones (id, title, status, depends_on, created_at, completed_at,
|
|
2378
2643
|
vision, success_criteria, key_risks, proof_strategy,
|
|
@@ -2391,17 +2656,23 @@ export function restoreManifest(manifest) {
|
|
|
2391
2656
|
for (const s of manifest.slices) {
|
|
2392
2657
|
slStmt.run(s.milestone_id, s.id, s.title, s.status, s.risk, JSON.stringify(s.depends), s.demo, s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md, s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact, JSON.stringify(s.target_repositories ?? []), s.sequence, s.replan_triggered_at, s.is_sketch ?? 0, s.sketch_scope ?? "");
|
|
2393
2658
|
}
|
|
2659
|
+
const depStmt = db.prepare("INSERT OR IGNORE INTO slice_dependencies (milestone_id, slice_id, depends_on_slice_id) VALUES (?, ?, ?)");
|
|
2660
|
+
for (const s of manifest.slices) {
|
|
2661
|
+
for (const dep of s.depends ?? []) {
|
|
2662
|
+
depStmt.run(s.milestone_id, s.id, dep);
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2394
2665
|
// Restore tasks (ADR-011 P2: includes blocker_source + escalation_* columns)
|
|
2395
2666
|
const tkStmt = db.prepare(`INSERT INTO tasks (milestone_id, slice_id, id, title, status,
|
|
2396
2667
|
one_liner, narrative, verification_result, duration, completed_at,
|
|
2397
2668
|
blocker_discovered, deviations, known_issues, key_files, key_decisions,
|
|
2398
2669
|
full_summary_md, description, estimate, files, verify,
|
|
2399
|
-
inputs, expected_output, observability_impact, target_repositories, sequence,
|
|
2670
|
+
inputs, expected_output, observability_impact, full_plan_md, target_repositories, sequence,
|
|
2400
2671
|
blocker_source, escalation_pending, escalation_awaiting_review,
|
|
2401
2672
|
escalation_artifact_path, escalation_override_applied_at)
|
|
2402
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2673
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2403
2674
|
for (const t of manifest.tasks) {
|
|
2404
|
-
tkStmt.run(t.milestone_id, t.slice_id, t.id, t.title, t.status, t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at, t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues, JSON.stringify(t.key_files), JSON.stringify(t.key_decisions), t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify, JSON.stringify(t.inputs), JSON.stringify(t.expected_output), t.observability_impact, JSON.stringify(t.target_repositories ?? []), t.sequence, t.blocker_source ?? "", t.escalation_pending ?? 0, t.escalation_awaiting_review ?? 0, t.escalation_artifact_path ?? null, t.escalation_override_applied_at ?? null);
|
|
2675
|
+
tkStmt.run(t.milestone_id, t.slice_id, t.id, t.title, t.status, t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at, t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues, JSON.stringify(t.key_files), JSON.stringify(t.key_decisions), t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify, JSON.stringify(t.inputs), JSON.stringify(t.expected_output), t.observability_impact, t.full_plan_md ?? "", JSON.stringify(t.target_repositories ?? []), t.sequence, t.blocker_source ?? "", t.escalation_pending ?? 0, t.escalation_awaiting_review ?? 0, t.escalation_artifact_path ?? null, t.escalation_override_applied_at ?? null);
|
|
2405
2676
|
}
|
|
2406
2677
|
// Restore decisions (ADR-011 P2: include source so escalation decisions survive)
|
|
2407
2678
|
const dcStmt = db.prepare(`INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, source, superseded_by)
|
|
@@ -2409,6 +2680,43 @@ export function restoreManifest(manifest) {
|
|
|
2409
2680
|
for (const d of manifest.decisions) {
|
|
2410
2681
|
dcStmt.run(d.seq, d.id, d.when_context, d.scope, d.decision, d.choice, d.rationale, d.revisable, d.made_by, d.source ?? "discussion", d.superseded_by);
|
|
2411
2682
|
}
|
|
2683
|
+
const replanHistoryRows = manifest.replan_history ?? preservedReplanHistory.filter((r) => restoredMilestoneIds.has(r.milestone_id));
|
|
2684
|
+
if (replanHistoryRows.length > 0) {
|
|
2685
|
+
const replStmt = db.prepare(`INSERT INTO replan_history (
|
|
2686
|
+
id, milestone_id, slice_id, task_id, summary, previous_artifact_path, replacement_artifact_path, created_at
|
|
2687
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2688
|
+
for (const r of replanHistoryRows) {
|
|
2689
|
+
replStmt.run(r.id, r.milestone_id, r.slice_id, r.task_id, r.summary, r.previous_artifact_path, r.replacement_artifact_path, r.created_at);
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
const assessmentRows = manifest.assessments ?? preservedAssessments.filter((a) => restoredMilestoneIds.has(a.milestone_id));
|
|
2693
|
+
if (assessmentRows.length > 0) {
|
|
2694
|
+
const assessStmt = db.prepare(`INSERT INTO assessments (
|
|
2695
|
+
path, milestone_id, slice_id, task_id, status, scope, full_content, created_at
|
|
2696
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2697
|
+
for (const a of assessmentRows) {
|
|
2698
|
+
assessStmt.run(a.path, a.milestone_id, a.slice_id, a.task_id, a.status, a.scope, a.full_content, a.created_at);
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
const qualityGateRows = manifest.quality_gates ?? preservedQualityGates.filter((g) => (restoredSliceKeys.has(JSON.stringify([g.milestone_id, g.slice_id]))));
|
|
2702
|
+
if (qualityGateRows.length > 0) {
|
|
2703
|
+
const gateStmt = db.prepare(`INSERT INTO quality_gates (
|
|
2704
|
+
milestone_id, slice_id, gate_id, scope, task_id, status, verdict, rationale, findings, evaluated_at
|
|
2705
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2706
|
+
for (const g of qualityGateRows) {
|
|
2707
|
+
gateStmt.run(g.milestone_id, g.slice_id, g.gate_id, g.scope, g.task_id, g.status, g.verdict ?? "", g.rationale, g.findings, g.evaluated_at);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
const commitAttributionRows = manifest.milestone_commit_attributions ??
|
|
2711
|
+
preservedCommitAttributions.filter((a) => restoredMilestoneIds.has(a.milestone_id));
|
|
2712
|
+
if (commitAttributionRows.length > 0) {
|
|
2713
|
+
const attrStmt = db.prepare(`INSERT OR REPLACE INTO milestone_commit_attributions (
|
|
2714
|
+
commit_sha, milestone_id, slice_id, task_id, source, confidence, files_json, created_at
|
|
2715
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
2716
|
+
for (const a of commitAttributionRows) {
|
|
2717
|
+
attrStmt.run(a.commit_sha, a.milestone_id, a.slice_id, a.task_id, a.source, a.confidence, a.files_json, a.created_at);
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2412
2720
|
// Restore verification evidence
|
|
2413
2721
|
const evStmt = db.prepare(`INSERT INTO verification_evidence (task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at)
|
|
2414
2722
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
|