@orion-agents/orion-code 0.1.9 → 0.2.2
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/CHANGELOG.md +85 -0
- package/README.md +142 -323
- package/README.zh-CN.md +118 -578
- package/dist/cli.js +65 -84
- package/dist/cli.js.map +1 -1
- package/dist/commands/context-commands.d.ts.map +1 -1
- package/dist/commands/context-commands.js +14 -7
- package/dist/commands/context-commands.js.map +1 -1
- package/dist/commands/context-tool-command-handlers.d.ts +4 -5
- package/dist/commands/context-tool-command-handlers.d.ts.map +1 -1
- package/dist/commands/context-tool-command-handlers.js +132 -208
- package/dist/commands/context-tool-command-handlers.js.map +1 -1
- package/dist/commands/core-command-handlers.d.ts +3 -6
- package/dist/commands/core-command-handlers.d.ts.map +1 -1
- package/dist/commands/core-command-handlers.js +66 -664
- package/dist/commands/core-command-handlers.js.map +1 -1
- package/dist/commands/diagnostic-command-handlers.d.ts +1 -2
- package/dist/commands/diagnostic-command-handlers.d.ts.map +1 -1
- package/dist/commands/diagnostic-command-handlers.js +3 -17
- package/dist/commands/diagnostic-command-handlers.js.map +1 -1
- package/dist/commands/diagnostic-commands.d.ts.map +1 -1
- package/dist/commands/diagnostic-commands.js +0 -45
- package/dist/commands/diagnostic-commands.js.map +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -7
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/model-command-handlers.d.ts +1 -1
- package/dist/commands/model-command-handlers.js +2 -2
- package/dist/commands/model-command-handlers.js.map +1 -1
- package/dist/commands/model-commands.d.ts.map +1 -1
- package/dist/commands/model-commands.js +0 -11
- package/dist/commands/model-commands.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +1 -139
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/session-command-handlers.d.ts +1 -1
- package/dist/commands/session-command-handlers.d.ts.map +1 -1
- package/dist/commands/session-command-handlers.js +52 -214
- package/dist/commands/session-command-handlers.js.map +1 -1
- package/dist/commands/session-commands.d.ts.map +1 -1
- package/dist/commands/session-commands.js +0 -48
- package/dist/commands/session-commands.js.map +1 -1
- package/dist/commands/target-command.d.ts +9 -15
- package/dist/commands/target-command.d.ts.map +1 -1
- package/dist/commands/target-command.js +16 -130
- package/dist/commands/target-command.js.map +1 -1
- package/dist/commands/tool-commands.d.ts.map +1 -1
- package/dist/commands/tool-commands.js +0 -10
- package/dist/commands/tool-commands.js.map +1 -1
- package/dist/commands/types.d.ts +10 -14
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/workflow-command-handlers.d.ts.map +1 -1
- package/dist/commands/workflow-command-handlers.js +1 -3
- package/dist/commands/workflow-command-handlers.js.map +1 -1
- package/dist/commands/workflow-commands.d.ts.map +1 -1
- package/dist/commands/workflow-commands.js +2 -24
- package/dist/commands/workflow-commands.js.map +1 -1
- package/dist/framework/agent-mode.d.ts +2 -3
- package/dist/framework/agent-mode.d.ts.map +1 -1
- package/dist/framework/agent-mode.js +8 -31
- package/dist/framework/agent-mode.js.map +1 -1
- package/dist/framework/index.d.ts +3 -3
- package/dist/framework/index.d.ts.map +1 -1
- package/dist/framework/index.js +6 -9
- package/dist/framework/index.js.map +1 -1
- package/dist/framework/loop-budget-contract.d.ts +20 -0
- package/dist/framework/loop-budget-contract.d.ts.map +1 -0
- package/dist/framework/loop-budget-contract.js +13 -0
- package/dist/framework/loop-budget-contract.js.map +1 -0
- package/dist/framework/prompt.d.ts.map +1 -1
- package/dist/framework/prompt.js +5 -4
- package/dist/framework/prompt.js.map +1 -1
- package/dist/framework/query.d.ts +45 -22
- package/dist/framework/query.d.ts.map +1 -1
- package/dist/framework/query.js +64 -52
- package/dist/framework/query.js.map +1 -1
- package/dist/framework/store.d.ts +4 -2
- package/dist/framework/store.d.ts.map +1 -1
- package/dist/framework/store.js +1 -0
- package/dist/framework/store.js.map +1 -1
- package/dist/framework/tool-call-orchestrator.d.ts +80 -0
- package/dist/framework/tool-call-orchestrator.d.ts.map +1 -0
- package/dist/framework/tool-call-orchestrator.js +192 -0
- package/dist/framework/tool-call-orchestrator.js.map +1 -0
- package/dist/framework/tool-state.d.ts +12 -11
- package/dist/framework/tool-state.d.ts.map +1 -1
- package/dist/framework/tool-state.js +36 -28
- package/dist/framework/tool-state.js.map +1 -1
- package/dist/framework/tool.d.ts +0 -9
- package/dist/framework/tool.d.ts.map +1 -1
- package/dist/framework/tool.js.map +1 -1
- package/dist/index.d.ts +70 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -65
- package/dist/index.js.map +1 -1
- package/dist/print-ui/launch.d.ts.map +1 -1
- package/dist/print-ui/launch.js +9 -2
- package/dist/print-ui/launch.js.map +1 -1
- package/dist/product/paths.d.ts +7 -0
- package/dist/product/paths.d.ts.map +1 -1
- package/dist/product/paths.js +19 -0
- package/dist/product/paths.js.map +1 -1
- package/dist/runtime/agent-loop.d.ts +80 -0
- package/dist/runtime/agent-loop.d.ts.map +1 -0
- package/dist/runtime/agent-loop.js +419 -0
- package/dist/runtime/agent-loop.js.map +1 -0
- package/dist/runtime/agent-runtime-controller.d.ts +10 -57
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +270 -1216
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-protocol.d.ts +4 -5
- package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-protocol.js.map +1 -1
- package/dist/runtime/agent-runtime-runner.d.ts +36 -0
- package/dist/runtime/agent-runtime-runner.d.ts.map +1 -0
- package/dist/runtime/agent-runtime-runner.js +3 -0
- package/dist/runtime/agent-runtime-runner.js.map +1 -0
- package/dist/runtime/batch-read-service.d.ts +29 -0
- package/dist/runtime/batch-read-service.d.ts.map +1 -0
- package/dist/runtime/batch-read-service.js +212 -0
- package/dist/runtime/batch-read-service.js.map +1 -0
- package/dist/runtime/builtin-tool-provider.d.ts +30 -0
- package/dist/runtime/builtin-tool-provider.d.ts.map +1 -0
- package/dist/runtime/builtin-tool-provider.js +233 -0
- package/dist/runtime/builtin-tool-provider.js.map +1 -0
- package/dist/runtime/capabilities/compiler.d.ts +11 -0
- package/dist/runtime/capabilities/compiler.d.ts.map +1 -0
- package/dist/runtime/capabilities/compiler.js +719 -0
- package/dist/runtime/capabilities/compiler.js.map +1 -0
- package/dist/runtime/capabilities/index.d.ts +3 -0
- package/dist/runtime/capabilities/index.d.ts.map +1 -0
- package/dist/runtime/capabilities/index.js +9 -0
- package/dist/runtime/capabilities/index.js.map +1 -0
- package/dist/runtime/capabilities/types.d.ts +175 -0
- package/dist/runtime/capabilities/types.d.ts.map +1 -0
- package/dist/runtime/capabilities/types.js +3 -0
- package/dist/runtime/capabilities/types.js.map +1 -0
- package/dist/runtime/capability-receipt-journal.d.ts +29 -0
- package/dist/runtime/capability-receipt-journal.d.ts.map +1 -0
- package/dist/runtime/capability-receipt-journal.js +264 -0
- package/dist/runtime/capability-receipt-journal.js.map +1 -0
- package/dist/runtime/capability-step-factory.d.ts +73 -0
- package/dist/runtime/capability-step-factory.d.ts.map +1 -0
- package/dist/runtime/capability-step-factory.js +302 -0
- package/dist/runtime/capability-step-factory.js.map +1 -0
- package/dist/runtime/compact-transaction.d.ts +225 -0
- package/dist/runtime/compact-transaction.d.ts.map +1 -0
- package/dist/runtime/compact-transaction.js +622 -0
- package/dist/runtime/compact-transaction.js.map +1 -0
- package/dist/runtime/composer/buffer.d.ts +3 -4
- package/dist/runtime/composer/buffer.d.ts.map +1 -1
- package/dist/runtime/composer/buffer.js +3 -4
- package/dist/runtime/composer/buffer.js.map +1 -1
- package/dist/runtime/composer/grapheme.d.ts +2 -4
- package/dist/runtime/composer/grapheme.d.ts.map +1 -1
- package/dist/runtime/composer/grapheme.js +2 -4
- package/dist/runtime/composer/grapheme.js.map +1 -1
- package/dist/runtime/composer/layout.d.ts +1 -3
- package/dist/runtime/composer/layout.d.ts.map +1 -1
- package/dist/runtime/composer/layout.js +1 -3
- package/dist/runtime/composer/layout.js.map +1 -1
- package/dist/runtime/core-tools/descriptors.d.ts +17 -0
- package/dist/runtime/core-tools/descriptors.d.ts.map +1 -0
- package/dist/runtime/core-tools/descriptors.js +185 -0
- package/dist/runtime/core-tools/descriptors.js.map +1 -0
- package/dist/runtime/first-party-core-provider.d.ts +55 -0
- package/dist/runtime/first-party-core-provider.d.ts.map +1 -0
- package/dist/runtime/first-party-core-provider.js +197 -0
- package/dist/runtime/first-party-core-provider.js.map +1 -0
- package/dist/runtime/first-party-long-tail-provider.d.ts +57 -0
- package/dist/runtime/first-party-long-tail-provider.d.ts.map +1 -0
- package/dist/runtime/first-party-long-tail-provider.js +238 -0
- package/dist/runtime/first-party-long-tail-provider.js.map +1 -0
- package/dist/runtime/first-party-tool-services.d.ts +43 -0
- package/dist/runtime/first-party-tool-services.d.ts.map +1 -0
- package/dist/runtime/first-party-tool-services.js +200 -0
- package/dist/runtime/first-party-tool-services.js.map +1 -0
- package/dist/runtime/first-party-tool-universe.d.ts +14 -0
- package/dist/runtime/first-party-tool-universe.d.ts.map +1 -0
- package/dist/runtime/first-party-tool-universe.js +20 -0
- package/dist/runtime/first-party-tool-universe.js.map +1 -0
- package/dist/runtime/goal-lifecycle-v2.d.ts +63 -0
- package/dist/runtime/goal-lifecycle-v2.d.ts.map +1 -0
- package/dist/runtime/goal-lifecycle-v2.js +253 -0
- package/dist/runtime/goal-lifecycle-v2.js.map +1 -0
- package/dist/runtime/goal-runtime-coordinator.d.ts +111 -0
- package/dist/runtime/goal-runtime-coordinator.d.ts.map +1 -0
- package/dist/runtime/goal-runtime-coordinator.js +511 -0
- package/dist/runtime/goal-runtime-coordinator.js.map +1 -0
- package/dist/runtime/harness-confluence.d.ts +165 -0
- package/dist/runtime/harness-confluence.d.ts.map +1 -0
- package/dist/runtime/harness-confluence.js +807 -0
- package/dist/runtime/harness-confluence.js.map +1 -0
- package/dist/runtime/harness-eval.d.ts +96 -0
- package/dist/runtime/harness-eval.d.ts.map +1 -0
- package/dist/runtime/harness-eval.js +181 -0
- package/dist/runtime/harness-eval.js.map +1 -0
- package/dist/runtime/harness-metrics.d.ts +202 -0
- package/dist/runtime/harness-metrics.d.ts.map +1 -0
- package/dist/runtime/harness-metrics.js +415 -0
- package/dist/runtime/harness-metrics.js.map +1 -0
- package/dist/runtime/legacy-session-importer.d.ts +99 -0
- package/dist/runtime/legacy-session-importer.d.ts.map +1 -0
- package/dist/runtime/legacy-session-importer.js +455 -0
- package/dist/runtime/legacy-session-importer.js.map +1 -0
- package/dist/runtime/legacy-thread-materializer.d.ts +72 -0
- package/dist/runtime/legacy-thread-materializer.d.ts.map +1 -0
- package/dist/runtime/legacy-thread-materializer.js +553 -0
- package/dist/runtime/legacy-thread-materializer.js.map +1 -0
- package/dist/runtime/long-tail-tools/descriptors.d.ts +23 -0
- package/dist/runtime/long-tail-tools/descriptors.d.ts.map +1 -0
- package/dist/runtime/long-tail-tools/descriptors.js +423 -0
- package/dist/runtime/long-tail-tools/descriptors.js.map +1 -0
- package/dist/runtime/loop-budget.d.ts +1 -1
- package/dist/runtime/loop-budget.d.ts.map +1 -1
- package/dist/runtime/loop-budget.js +2 -2
- package/dist/runtime/loop-budget.js.map +1 -1
- package/dist/runtime/mcp/first-party-mcp-adapter.d.ts +75 -0
- package/dist/runtime/mcp/first-party-mcp-adapter.d.ts.map +1 -0
- package/dist/runtime/mcp/first-party-mcp-adapter.js +484 -0
- package/dist/runtime/mcp/first-party-mcp-adapter.js.map +1 -0
- package/dist/runtime/mcp/first-party-mcp-config.d.ts +13 -0
- package/dist/runtime/mcp/first-party-mcp-config.d.ts.map +1 -0
- package/dist/runtime/mcp/first-party-mcp-config.js +139 -0
- package/dist/runtime/mcp/first-party-mcp-config.js.map +1 -0
- package/dist/runtime/mcp/index.d.ts +5 -0
- package/dist/runtime/mcp/index.d.ts.map +1 -0
- package/dist/{skills → runtime/mcp}/index.js +3 -9
- package/dist/runtime/mcp/index.js.map +1 -0
- package/dist/runtime/mcp/lazy-mcp-runtime.d.ts +95 -0
- package/dist/runtime/mcp/lazy-mcp-runtime.d.ts.map +1 -0
- package/dist/runtime/mcp/lazy-mcp-runtime.js +854 -0
- package/dist/runtime/mcp/lazy-mcp-runtime.js.map +1 -0
- package/dist/runtime/mcp/types.d.ts +128 -0
- package/dist/runtime/mcp/types.d.ts.map +1 -0
- package/dist/runtime/mcp/types.js +5 -0
- package/dist/runtime/mcp/types.js.map +1 -0
- package/dist/runtime/orion-runtime-v1.d.ts +322 -0
- package/dist/runtime/orion-runtime-v1.d.ts.map +1 -0
- package/dist/runtime/orion-runtime-v1.js +959 -0
- package/dist/runtime/orion-runtime-v1.js.map +1 -0
- package/dist/runtime/orion-session-runner.d.ts +38 -0
- package/dist/runtime/orion-session-runner.d.ts.map +1 -0
- package/dist/runtime/orion-session-runner.js +168 -0
- package/dist/runtime/orion-session-runner.js.map +1 -0
- package/dist/runtime/product-orion-runtime.d.ts +35 -0
- package/dist/runtime/product-orion-runtime.d.ts.map +1 -0
- package/dist/runtime/product-orion-runtime.js +1047 -0
- package/dist/runtime/product-orion-runtime.js.map +1 -0
- package/dist/runtime/prompts/index.d.ts +3 -0
- package/dist/runtime/prompts/index.d.ts.map +1 -0
- package/dist/{ink-ui/types.js → runtime/prompts/index.js} +3 -2
- package/dist/runtime/prompts/index.js.map +1 -0
- package/dist/runtime/prompts/prompt-registry.d.ts +22 -0
- package/dist/runtime/prompts/prompt-registry.d.ts.map +1 -0
- package/dist/runtime/prompts/prompt-registry.js +356 -0
- package/dist/runtime/prompts/prompt-registry.js.map +1 -0
- package/dist/runtime/prompts/types.d.ts +111 -0
- package/dist/runtime/prompts/types.d.ts.map +1 -0
- package/dist/runtime/prompts/types.js +5 -0
- package/dist/runtime/prompts/types.js.map +1 -0
- package/dist/runtime/protocol/canonical.d.ts +3 -0
- package/dist/runtime/protocol/canonical.d.ts.map +1 -0
- package/dist/runtime/protocol/canonical.js +21 -0
- package/dist/runtime/protocol/canonical.js.map +1 -0
- package/dist/runtime/protocol/index.d.ts +4 -0
- package/dist/runtime/protocol/index.d.ts.map +1 -0
- package/dist/runtime/protocol/index.js +16 -0
- package/dist/runtime/protocol/index.js.map +1 -0
- package/dist/runtime/protocol/runtime-protocol-v1.d.ts +671 -0
- package/dist/runtime/protocol/runtime-protocol-v1.d.ts.map +1 -0
- package/dist/runtime/protocol/runtime-protocol-v1.js +557 -0
- package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -0
- package/dist/runtime/release-receipts.d.ts +110 -0
- package/dist/runtime/release-receipts.d.ts.map +1 -0
- package/dist/runtime/release-receipts.js +305 -0
- package/dist/runtime/release-receipts.js.map +1 -0
- package/dist/runtime/resource-scope.d.ts +123 -0
- package/dist/runtime/resource-scope.d.ts.map +1 -0
- package/dist/runtime/resource-scope.js +363 -0
- package/dist/runtime/resource-scope.js.map +1 -0
- package/dist/runtime/runtime-event-buffer.d.ts +78 -0
- package/dist/runtime/runtime-event-buffer.d.ts.map +1 -0
- package/dist/runtime/runtime-event-buffer.js +237 -0
- package/dist/runtime/runtime-event-buffer.js.map +1 -0
- package/dist/runtime/runtime-services.d.ts +87 -0
- package/dist/runtime/runtime-services.d.ts.map +1 -0
- package/dist/runtime/runtime-services.js +180 -0
- package/dist/runtime/runtime-services.js.map +1 -0
- package/dist/runtime/session-history-recovery.d.ts +19 -0
- package/dist/runtime/session-history-recovery.d.ts.map +1 -0
- package/dist/runtime/session-history-recovery.js +45 -0
- package/dist/runtime/session-history-recovery.js.map +1 -0
- package/dist/runtime/skills/bounded-lru-cache.d.ts +34 -0
- package/dist/runtime/skills/bounded-lru-cache.d.ts.map +1 -0
- package/dist/runtime/skills/bounded-lru-cache.js +100 -0
- package/dist/runtime/skills/bounded-lru-cache.js.map +1 -0
- package/dist/runtime/skills/filesystem-skill-provider.d.ts +96 -0
- package/dist/runtime/skills/filesystem-skill-provider.d.ts.map +1 -0
- package/dist/runtime/skills/filesystem-skill-provider.js +829 -0
- package/dist/runtime/skills/filesystem-skill-provider.js.map +1 -0
- package/dist/runtime/skills/index.d.ts +5 -0
- package/dist/runtime/skills/index.d.ts.map +1 -0
- package/dist/{ink-ui/controllers/chat-controller.js → runtime/skills/index.js} +5 -2
- package/dist/runtime/skills/index.js.map +1 -0
- package/dist/runtime/skills/lazy-skill-runtime.d.ts +77 -0
- package/dist/runtime/skills/lazy-skill-runtime.d.ts.map +1 -0
- package/dist/runtime/skills/lazy-skill-runtime.js +673 -0
- package/dist/runtime/skills/lazy-skill-runtime.js.map +1 -0
- package/dist/runtime/skills/types.d.ts +137 -0
- package/dist/runtime/skills/types.d.ts.map +1 -0
- package/dist/runtime/skills/types.js +13 -0
- package/dist/runtime/skills/types.js.map +1 -0
- package/dist/runtime/step-snapshot.d.ts +183 -0
- package/dist/runtime/step-snapshot.d.ts.map +1 -0
- package/dist/runtime/step-snapshot.js +286 -0
- package/dist/runtime/step-snapshot.js.map +1 -0
- package/dist/runtime/subagent-thread-runtime.d.ts +239 -0
- package/dist/runtime/subagent-thread-runtime.d.ts.map +1 -0
- package/dist/runtime/subagent-thread-runtime.js +876 -0
- package/dist/runtime/subagent-thread-runtime.js.map +1 -0
- package/dist/runtime/subagents/index.d.ts +4 -1
- package/dist/runtime/subagents/index.d.ts.map +1 -1
- package/dist/runtime/subagents/index.js +10 -2
- package/dist/runtime/subagents/index.js.map +1 -1
- package/dist/runtime/subagents/parent-step-fork.d.ts +36 -0
- package/dist/runtime/subagents/parent-step-fork.d.ts.map +1 -0
- package/dist/runtime/subagents/parent-step-fork.js +83 -0
- package/dist/runtime/subagents/parent-step-fork.js.map +1 -0
- package/dist/runtime/subagents/production.d.ts +65 -46
- package/dist/runtime/subagents/production.d.ts.map +1 -1
- package/dist/runtime/subagents/production.js +494 -170
- package/dist/runtime/subagents/production.js.map +1 -1
- package/dist/runtime/subagents/receipt-journal.d.ts +20 -0
- package/dist/runtime/subagents/receipt-journal.d.ts.map +1 -0
- package/dist/runtime/subagents/receipt-journal.js +74 -0
- package/dist/runtime/subagents/receipt-journal.js.map +1 -0
- package/dist/runtime/subagents/runtime-contract.d.ts +29 -0
- package/dist/runtime/subagents/runtime-contract.d.ts.map +1 -0
- package/dist/runtime/subagents/runtime-contract.js +3 -0
- package/dist/runtime/subagents/runtime-contract.js.map +1 -0
- package/dist/runtime/subagents/runtime-integration.d.ts +41 -56
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
- package/dist/runtime/subagents/runtime-integration.js +34 -198
- package/dist/runtime/subagents/runtime-integration.js.map +1 -1
- package/dist/runtime/subagents/supervisor.d.ts +19 -7
- package/dist/runtime/subagents/supervisor.d.ts.map +1 -1
- package/dist/runtime/subagents/supervisor.js +83 -40
- package/dist/runtime/subagents/supervisor.js.map +1 -1
- package/dist/runtime/subagents/types.d.ts +1 -1
- package/dist/runtime/subagents/types.js +1 -1
- package/dist/runtime/task-context-service.d.ts +91 -0
- package/dist/runtime/task-context-service.d.ts.map +1 -0
- package/dist/runtime/task-context-service.js +122 -0
- package/dist/runtime/task-context-service.js.map +1 -0
- package/dist/runtime/thread-admission.d.ts +130 -0
- package/dist/runtime/thread-admission.d.ts.map +1 -0
- package/dist/runtime/thread-admission.js +276 -0
- package/dist/runtime/thread-admission.js.map +1 -0
- package/dist/runtime/thread-compact-persistence.d.ts +50 -0
- package/dist/runtime/thread-compact-persistence.d.ts.map +1 -0
- package/dist/runtime/thread-compact-persistence.js +176 -0
- package/dist/runtime/thread-compact-persistence.js.map +1 -0
- package/dist/runtime/thread-event-store.d.ts +98 -0
- package/dist/runtime/thread-event-store.d.ts.map +1 -0
- package/dist/runtime/thread-event-store.js +737 -0
- package/dist/runtime/thread-event-store.js.map +1 -0
- package/dist/runtime/thread-projection.d.ts +91 -0
- package/dist/runtime/thread-projection.d.ts.map +1 -0
- package/dist/runtime/thread-projection.js +407 -0
- package/dist/runtime/thread-projection.js.map +1 -0
- package/dist/runtime/thread-runtime.d.ts +165 -0
- package/dist/runtime/thread-runtime.d.ts.map +1 -0
- package/dist/runtime/thread-runtime.js +704 -0
- package/dist/runtime/thread-runtime.js.map +1 -0
- package/dist/runtime/thread-session-view.d.ts +45 -0
- package/dist/runtime/thread-session-view.d.ts.map +1 -0
- package/dist/runtime/thread-session-view.js +264 -0
- package/dist/runtime/thread-session-view.js.map +1 -0
- package/dist/runtime/thread-tool-journal.d.ts +11 -0
- package/dist/runtime/thread-tool-journal.d.ts.map +1 -0
- package/dist/runtime/thread-tool-journal.js +131 -0
- package/dist/runtime/thread-tool-journal.js.map +1 -0
- package/dist/runtime/thread-ui-adapter.d.ts +87 -0
- package/dist/runtime/thread-ui-adapter.d.ts.map +1 -0
- package/dist/runtime/thread-ui-adapter.js +580 -0
- package/dist/runtime/thread-ui-adapter.js.map +1 -0
- package/dist/runtime/tool-gateway.d.ts +159 -0
- package/dist/runtime/tool-gateway.d.ts.map +1 -0
- package/dist/runtime/tool-gateway.js +311 -0
- package/dist/runtime/tool-gateway.js.map +1 -0
- package/dist/runtime/turn-commit.d.ts +103 -0
- package/dist/runtime/turn-commit.d.ts.map +1 -0
- package/dist/runtime/turn-commit.js +321 -0
- package/dist/runtime/turn-commit.js.map +1 -0
- package/dist/runtime/ui-events.d.ts +15 -5
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js +0 -1
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/runtime/ui-view-model.d.ts +2 -1
- package/dist/runtime/ui-view-model.d.ts.map +1 -1
- package/dist/runtime/ui-view-model.js +6 -5
- package/dist/runtime/ui-view-model.js.map +1 -1
- package/dist/services/config-dir.d.ts +1 -1
- package/dist/services/config-dir.d.ts.map +1 -1
- package/dist/services/config-dir.js +2 -1
- package/dist/services/config-dir.js.map +1 -1
- package/dist/services/config.d.ts +2 -16
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +2 -29
- package/dist/services/config.js.map +1 -1
- package/dist/services/doctor.d.ts +0 -2
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +39 -64
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/file-lock.d.ts.map +1 -1
- package/dist/services/file-lock.js +42 -17
- package/dist/services/file-lock.js.map +1 -1
- package/dist/services/global-config.d.ts +2 -2
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/session-storage.d.ts +8 -0
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +76 -12
- package/dist/services/session-storage.js.map +1 -1
- package/dist/skills/builtin/code-review/SKILL.md +51 -0
- package/dist/skills/builtin/security-check/SKILL.md +54 -0
- package/dist/skills/builtin/test-gen/SKILL.md +49 -0
- package/dist/terminal-ui/launch.d.ts +3 -1
- package/dist/terminal-ui/launch.d.ts.map +1 -1
- package/dist/terminal-ui/launch.js +21 -3
- package/dist/terminal-ui/launch.js.map +1 -1
- package/dist/tools/core/common.d.ts +34 -0
- package/dist/tools/core/common.d.ts.map +1 -0
- package/dist/tools/core/common.js +164 -0
- package/dist/tools/core/common.js.map +1 -0
- package/dist/tools/core/edit-file.d.ts +10 -0
- package/dist/tools/core/edit-file.d.ts.map +1 -0
- package/dist/tools/core/edit-file.js +301 -0
- package/dist/tools/core/edit-file.js.map +1 -0
- package/dist/tools/core/exec-command.d.ts +2 -0
- package/dist/tools/core/exec-command.d.ts.map +1 -0
- package/dist/tools/core/exec-command.js +347 -0
- package/dist/tools/core/exec-command.js.map +1 -0
- package/dist/tools/core/glob.d.ts +2 -0
- package/dist/tools/core/glob.d.ts.map +1 -0
- package/dist/tools/core/glob.js +133 -0
- package/dist/tools/core/glob.js.map +1 -0
- package/dist/tools/core/grep.d.ts +12 -0
- package/dist/tools/core/grep.d.ts.map +1 -0
- package/dist/tools/core/grep.js +223 -0
- package/dist/tools/core/grep.js.map +1 -0
- package/dist/tools/core/index.d.ts +15 -0
- package/dist/tools/core/index.d.ts.map +1 -0
- package/dist/tools/core/index.js +31 -0
- package/dist/tools/core/index.js.map +1 -0
- package/dist/tools/core/list-files.d.ts +2 -0
- package/dist/tools/core/list-files.d.ts.map +1 -0
- package/dist/tools/core/list-files.js +87 -0
- package/dist/tools/core/list-files.js.map +1 -0
- package/dist/tools/core/read-file.d.ts +2 -0
- package/dist/tools/core/read-file.d.ts.map +1 -0
- package/dist/tools/core/read-file.js +129 -0
- package/dist/tools/core/read-file.js.map +1 -0
- package/dist/tools/core/write-file.d.ts +2 -0
- package/dist/tools/core/write-file.d.ts.map +1 -0
- package/dist/tools/core/write-file.js +65 -0
- package/dist/tools/core/write-file.js.map +1 -0
- package/dist/tools/todo.d.ts +3 -4
- package/dist/tools/todo.d.ts.map +1 -1
- package/dist/tools/todo.js +80 -79
- package/dist/tools/todo.js.map +1 -1
- package/dist/tools/web.js +1 -1
- package/dist/tools/web.js.map +1 -1
- package/dist/tui-ui/chrome-view-model.d.ts.map +1 -1
- package/dist/tui-ui/chrome-view-model.js +22 -8
- package/dist/tui-ui/chrome-view-model.js.map +1 -1
- package/dist/tui-ui/launch.d.ts.map +1 -1
- package/dist/tui-ui/launch.js +13 -0
- package/dist/tui-ui/launch.js.map +1 -1
- package/dist/tui-ui/layout.js +1 -1
- package/dist/tui-ui/layout.js.map +1 -1
- package/dist/tui-ui/state.d.ts.map +1 -1
- package/dist/tui-ui/state.js +2 -0
- package/dist/tui-ui/state.js.map +1 -1
- package/docs/migration/v0.1.9-to-v0.2.0.md +98 -0
- package/docs/orion.example.json +79 -0
- package/docs/plan/v0.2.0-dsh-harness-redesign-plan.md +1234 -0
- package/docs/plan/v0.2.0-release-checklist.md +91 -0
- package/docs/readme.md +8 -8
- package/npm-shrinkwrap.json +45 -450
- package/package.json +17 -13
- package/dist/agents/coder.d.ts +0 -12
- package/dist/agents/coder.d.ts.map +0 -1
- package/dist/agents/coder.js +0 -48
- package/dist/agents/coder.js.map +0 -1
- package/dist/agents/coordinator.d.ts +0 -86
- package/dist/agents/coordinator.d.ts.map +0 -1
- package/dist/agents/coordinator.js +0 -291
- package/dist/agents/coordinator.js.map +0 -1
- package/dist/agents/fork.d.ts +0 -73
- package/dist/agents/fork.d.ts.map +0 -1
- package/dist/agents/fork.js +0 -163
- package/dist/agents/fork.js.map +0 -1
- package/dist/agents/leader.d.ts +0 -12
- package/dist/agents/leader.d.ts.map +0 -1
- package/dist/agents/leader.js +0 -49
- package/dist/agents/leader.js.map +0 -1
- package/dist/agents/router.d.ts +0 -59
- package/dist/agents/router.d.ts.map +0 -1
- package/dist/agents/router.js +0 -193
- package/dist/agents/router.js.map +0 -1
- package/dist/agents/worker-pool.d.ts +0 -72
- package/dist/agents/worker-pool.d.ts.map +0 -1
- package/dist/agents/worker-pool.js +0 -229
- package/dist/agents/worker-pool.js.map +0 -1
- package/dist/commands/legacy-commands.d.ts +0 -4
- package/dist/commands/legacy-commands.d.ts.map +0 -1
- package/dist/commands/legacy-commands.js +0 -44
- package/dist/commands/legacy-commands.js.map +0 -1
- package/dist/core/agent.d.ts +0 -84
- package/dist/core/agent.d.ts.map +0 -1
- package/dist/core/agent.js +0 -58
- package/dist/core/agent.js.map +0 -1
- package/dist/core/brain.d.ts +0 -50
- package/dist/core/brain.d.ts.map +0 -1
- package/dist/core/brain.js +0 -95
- package/dist/core/brain.js.map +0 -1
- package/dist/framework/tool-scheduler.d.ts +0 -191
- package/dist/framework/tool-scheduler.d.ts.map +0 -1
- package/dist/framework/tool-scheduler.js +0 -573
- package/dist/framework/tool-scheduler.js.map +0 -1
- package/dist/harness/harness.d.ts +0 -58
- package/dist/harness/harness.d.ts.map +0 -1
- package/dist/harness/harness.js +0 -195
- package/dist/harness/harness.js.map +0 -1
- package/dist/harness/safety.d.ts +0 -101
- package/dist/harness/safety.d.ts.map +0 -1
- package/dist/harness/safety.js +0 -322
- package/dist/harness/safety.js.map +0 -1
- package/dist/init.d.ts +0 -108
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -393
- package/dist/init.js.map +0 -1
- package/dist/ink-ui/App.d.ts +0 -9
- package/dist/ink-ui/App.d.ts.map +0 -1
- package/dist/ink-ui/App.js +0 -12
- package/dist/ink-ui/App.js.map +0 -1
- package/dist/ink-ui/components/Markdown.d.ts +0 -10
- package/dist/ink-ui/components/Markdown.d.ts.map +0 -1
- package/dist/ink-ui/components/Markdown.js +0 -210
- package/dist/ink-ui/components/Markdown.js.map +0 -1
- package/dist/ink-ui/components/NativeCursor.d.ts +0 -12
- package/dist/ink-ui/components/NativeCursor.d.ts.map +0 -1
- package/dist/ink-ui/components/NativeCursor.js +0 -35
- package/dist/ink-ui/components/NativeCursor.js.map +0 -1
- package/dist/ink-ui/components/PixelHorseBanner.d.ts +0 -8
- package/dist/ink-ui/components/PixelHorseBanner.d.ts.map +0 -1
- package/dist/ink-ui/components/PixelHorseBanner.js +0 -97
- package/dist/ink-ui/components/PixelHorseBanner.js.map +0 -1
- package/dist/ink-ui/components/PromptInput.d.ts +0 -13
- package/dist/ink-ui/components/PromptInput.d.ts.map +0 -1
- package/dist/ink-ui/components/PromptInput.js +0 -30
- package/dist/ink-ui/components/PromptInput.js.map +0 -1
- package/dist/ink-ui/components/RunningHorseIndicator.d.ts +0 -13
- package/dist/ink-ui/components/RunningHorseIndicator.d.ts.map +0 -1
- package/dist/ink-ui/components/RunningHorseIndicator.js +0 -53
- package/dist/ink-ui/components/RunningHorseIndicator.js.map +0 -1
- package/dist/ink-ui/components/SelectList.d.ts +0 -16
- package/dist/ink-ui/components/SelectList.d.ts.map +0 -1
- package/dist/ink-ui/components/SelectList.js +0 -60
- package/dist/ink-ui/components/SelectList.js.map +0 -1
- package/dist/ink-ui/components/StatusLine.d.ts +0 -11
- package/dist/ink-ui/components/StatusLine.d.ts.map +0 -1
- package/dist/ink-ui/components/StatusLine.js +0 -70
- package/dist/ink-ui/components/StatusLine.js.map +0 -1
- package/dist/ink-ui/components/ToolActivity.d.ts +0 -19
- package/dist/ink-ui/components/ToolActivity.d.ts.map +0 -1
- package/dist/ink-ui/components/ToolActivity.js +0 -134
- package/dist/ink-ui/components/ToolActivity.js.map +0 -1
- package/dist/ink-ui/components/Transcript.d.ts +0 -14
- package/dist/ink-ui/components/Transcript.d.ts.map +0 -1
- package/dist/ink-ui/components/Transcript.js +0 -66
- package/dist/ink-ui/components/Transcript.js.map +0 -1
- package/dist/ink-ui/controllers/chat-controller.d.ts +0 -2
- package/dist/ink-ui/controllers/chat-controller.d.ts.map +0 -1
- package/dist/ink-ui/controllers/chat-controller.js.map +0 -1
- package/dist/ink-ui/hooks/use-raw-input-bridge.d.ts +0 -6
- package/dist/ink-ui/hooks/use-raw-input-bridge.d.ts.map +0 -1
- package/dist/ink-ui/hooks/use-raw-input-bridge.js +0 -27
- package/dist/ink-ui/hooks/use-raw-input-bridge.js.map +0 -1
- package/dist/ink-ui/hooks/use-terminal-size.d.ts +0 -7
- package/dist/ink-ui/hooks/use-terminal-size.d.ts.map +0 -1
- package/dist/ink-ui/hooks/use-terminal-size.js +0 -34
- package/dist/ink-ui/hooks/use-terminal-size.js.map +0 -1
- package/dist/ink-ui/launch.d.ts +0 -9
- package/dist/ink-ui/launch.d.ts.map +0 -1
- package/dist/ink-ui/launch.js +0 -101
- package/dist/ink-ui/launch.js.map +0 -1
- package/dist/ink-ui/runtime/grapheme.d.ts +0 -10
- package/dist/ink-ui/runtime/grapheme.d.ts.map +0 -1
- package/dist/ink-ui/runtime/grapheme.js +0 -17
- package/dist/ink-ui/runtime/grapheme.js.map +0 -1
- package/dist/ink-ui/runtime/input-buffer.d.ts +0 -10
- package/dist/ink-ui/runtime/input-buffer.d.ts.map +0 -1
- package/dist/ink-ui/runtime/input-buffer.js +0 -18
- package/dist/ink-ui/runtime/input-buffer.js.map +0 -1
- package/dist/ink-ui/runtime/layout-budget.d.ts +0 -13
- package/dist/ink-ui/runtime/layout-budget.d.ts.map +0 -1
- package/dist/ink-ui/runtime/layout-budget.js +0 -25
- package/dist/ink-ui/runtime/layout-budget.js.map +0 -1
- package/dist/ink-ui/runtime/native-cursor.d.ts +0 -62
- package/dist/ink-ui/runtime/native-cursor.d.ts.map +0 -1
- package/dist/ink-ui/runtime/native-cursor.js +0 -398
- package/dist/ink-ui/runtime/native-cursor.js.map +0 -1
- package/dist/ink-ui/runtime/prompt-layout.d.ts +0 -10
- package/dist/ink-ui/runtime/prompt-layout.d.ts.map +0 -1
- package/dist/ink-ui/runtime/prompt-layout.js +0 -21
- package/dist/ink-ui/runtime/prompt-layout.js.map +0 -1
- package/dist/ink-ui/runtime/raw-input.d.ts +0 -4
- package/dist/ink-ui/runtime/raw-input.d.ts.map +0 -1
- package/dist/ink-ui/runtime/raw-input.js +0 -15
- package/dist/ink-ui/runtime/raw-input.js.map +0 -1
- package/dist/ink-ui/runtime/transcript-state.d.ts +0 -37
- package/dist/ink-ui/runtime/transcript-state.d.ts.map +0 -1
- package/dist/ink-ui/runtime/transcript-state.js +0 -91
- package/dist/ink-ui/runtime/transcript-state.js.map +0 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts +0 -27
- package/dist/ink-ui/screens/ReplScreen.d.ts.map +0 -1
- package/dist/ink-ui/screens/ReplScreen.js +0 -781
- package/dist/ink-ui/screens/ReplScreen.js.map +0 -1
- package/dist/ink-ui/types.d.ts +0 -2
- package/dist/ink-ui/types.d.ts.map +0 -1
- package/dist/ink-ui/types.js.map +0 -1
- package/dist/runtime/chat-checkpoint.d.ts +0 -17
- package/dist/runtime/chat-checkpoint.d.ts.map +0 -1
- package/dist/runtime/chat-checkpoint.js +0 -105
- package/dist/runtime/chat-checkpoint.js.map +0 -1
- package/dist/runtime/chat-command-scope.d.ts +0 -5
- package/dist/runtime/chat-command-scope.d.ts.map +0 -1
- package/dist/runtime/chat-command-scope.js +0 -22
- package/dist/runtime/chat-command-scope.js.map +0 -1
- package/dist/runtime/chat-compact.d.ts +0 -26
- package/dist/runtime/chat-compact.d.ts.map +0 -1
- package/dist/runtime/chat-compact.js +0 -132
- package/dist/runtime/chat-compact.js.map +0 -1
- package/dist/runtime/chat-controller.d.ts +0 -62
- package/dist/runtime/chat-controller.d.ts.map +0 -1
- package/dist/runtime/chat-controller.js +0 -1620
- package/dist/runtime/chat-controller.js.map +0 -1
- package/dist/runtime/chat-effort.d.ts +0 -5
- package/dist/runtime/chat-effort.d.ts.map +0 -1
- package/dist/runtime/chat-effort.js +0 -47
- package/dist/runtime/chat-effort.js.map +0 -1
- package/dist/runtime/chat-presentation.d.ts +0 -63
- package/dist/runtime/chat-presentation.d.ts.map +0 -1
- package/dist/runtime/chat-presentation.js +0 -561
- package/dist/runtime/chat-presentation.js.map +0 -1
- package/dist/runtime/chat-trace.d.ts +0 -52
- package/dist/runtime/chat-trace.d.ts.map +0 -1
- package/dist/runtime/chat-trace.js +0 -234
- package/dist/runtime/chat-trace.js.map +0 -1
- package/dist/runtime/chat-workspace.d.ts +0 -22
- package/dist/runtime/chat-workspace.d.ts.map +0 -1
- package/dist/runtime/chat-workspace.js +0 -154
- package/dist/runtime/chat-workspace.js.map +0 -1
- package/dist/runtime/goals/accounting.d.ts +0 -45
- package/dist/runtime/goals/accounting.d.ts.map +0 -1
- package/dist/runtime/goals/accounting.js +0 -114
- package/dist/runtime/goals/accounting.js.map +0 -1
- package/dist/runtime/goals/coordinator.d.ts +0 -92
- package/dist/runtime/goals/coordinator.d.ts.map +0 -1
- package/dist/runtime/goals/coordinator.js +0 -1471
- package/dist/runtime/goals/coordinator.js.map +0 -1
- package/dist/runtime/goals/lifecycle.d.ts +0 -13
- package/dist/runtime/goals/lifecycle.d.ts.map +0 -1
- package/dist/runtime/goals/lifecycle.js +0 -46
- package/dist/runtime/goals/lifecycle.js.map +0 -1
- package/dist/runtime/goals/prompt.d.ts +0 -16
- package/dist/runtime/goals/prompt.d.ts.map +0 -1
- package/dist/runtime/goals/prompt.js +0 -88
- package/dist/runtime/goals/prompt.js.map +0 -1
- package/dist/runtime/goals/stop-policy.d.ts +0 -9
- package/dist/runtime/goals/stop-policy.d.ts.map +0 -1
- package/dist/runtime/goals/stop-policy.js +0 -83
- package/dist/runtime/goals/stop-policy.js.map +0 -1
- package/dist/runtime/goals/tools.d.ts +0 -61
- package/dist/runtime/goals/tools.d.ts.map +0 -1
- package/dist/runtime/goals/tools.js +0 -568
- package/dist/runtime/goals/tools.js.map +0 -1
- package/dist/sdk/index.d.ts +0 -10
- package/dist/sdk/index.d.ts.map +0 -1
- package/dist/sdk/index.js +0 -23
- package/dist/sdk/index.js.map +0 -1
- package/dist/sdk/init.d.ts +0 -24
- package/dist/sdk/init.d.ts.map +0 -1
- package/dist/sdk/init.js +0 -48
- package/dist/sdk/init.js.map +0 -1
- package/dist/sdk/query.d.ts +0 -19
- package/dist/sdk/query.d.ts.map +0 -1
- package/dist/sdk/query.js +0 -42
- package/dist/sdk/query.js.map +0 -1
- package/dist/sdk/sessions.d.ts +0 -19
- package/dist/sdk/sessions.d.ts.map +0 -1
- package/dist/sdk/sessions.js +0 -57
- package/dist/sdk/sessions.js.map +0 -1
- package/dist/sdk/types.d.ts +0 -47
- package/dist/sdk/types.d.ts.map +0 -1
- package/dist/sdk/types.js +0 -8
- package/dist/sdk/types.js.map +0 -1
- package/dist/services/agent-runner.d.ts +0 -71
- package/dist/services/agent-runner.d.ts.map +0 -1
- package/dist/services/agent-runner.js +0 -185
- package/dist/services/agent-runner.js.map +0 -1
- package/dist/services/task-manager.d.ts +0 -161
- package/dist/services/task-manager.d.ts.map +0 -1
- package/dist/services/task-manager.js +0 -315
- package/dist/services/task-manager.js.map +0 -1
- package/dist/skills/discovery.d.ts +0 -22
- package/dist/skills/discovery.d.ts.map +0 -1
- package/dist/skills/discovery.js +0 -75
- package/dist/skills/discovery.js.map +0 -1
- package/dist/skills/index.d.ts +0 -11
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/loader.d.ts +0 -53
- package/dist/skills/loader.d.ts.map +0 -1
- package/dist/skills/loader.js +0 -421
- package/dist/skills/loader.js.map +0 -1
- package/dist/skills/registry.d.ts +0 -41
- package/dist/skills/registry.d.ts.map +0 -1
- package/dist/skills/registry.js +0 -157
- package/dist/skills/registry.js.map +0 -1
- package/dist/skills/runtime.d.ts +0 -46
- package/dist/skills/runtime.d.ts.map +0 -1
- package/dist/skills/runtime.js +0 -363
- package/dist/skills/runtime.js.map +0 -1
- package/dist/skills/types.d.ts +0 -112
- package/dist/skills/types.d.ts.map +0 -1
- package/dist/skills/types.js +0 -24
- package/dist/skills/types.js.map +0 -1
- package/dist/tools/index.d.ts +0 -52
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -2268
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/mcp.d.ts +0 -99
- package/dist/tools/mcp.d.ts.map +0 -1
- package/dist/tools/mcp.js +0 -695
- package/dist/tools/mcp.js.map +0 -1
- package/dist/tools/plan.d.ts +0 -17
- package/dist/tools/plan.d.ts.map +0 -1
- package/dist/tools/plan.js +0 -84
- package/dist/tools/plan.js.map +0 -1
- package/docs/migration/v0.1.8-to-v0.1.9.md +0 -60
- package/docs/plan/v0.1.9-release-checklist.md +0 -64
|
@@ -1,1471 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* v0.2.24 — Goal Coordinator.
|
|
4
|
-
*
|
|
5
|
-
* Single-flight state machine that manages goal lifecycle: creation,
|
|
6
|
-
* pause/resume, auto-continuation, completion/blocked audit, and
|
|
7
|
-
* persistence. Owned by AgentRuntimeController — NOT a global singleton.
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.GoalCoordinator = void 0;
|
|
11
|
-
exports.goalRequiresBoundaryConfirmation = goalRequiresBoundaryConfirmation;
|
|
12
|
-
const crypto_1 = require("crypto");
|
|
13
|
-
const fs_1 = require("fs");
|
|
14
|
-
const path_1 = require("path");
|
|
15
|
-
const types_1 = require("./types");
|
|
16
|
-
const stop_policy_1 = require("./stop-policy");
|
|
17
|
-
const goal_storage_1 = require("../../services/goal-storage");
|
|
18
|
-
const accounting_1 = require("./accounting");
|
|
19
|
-
const completion_audit_1 = require("./completion-audit");
|
|
20
|
-
const redaction_1 = require("../../services/redaction");
|
|
21
|
-
const config_dir_1 = require("../../services/config-dir");
|
|
22
|
-
const objective_1 = require("./objective");
|
|
23
|
-
const MAX_EVIDENCE_LEDGER_RECORDS = 500;
|
|
24
|
-
const MAX_EVIDENCE_TRUNCATION_COUNT = 1000000000;
|
|
25
|
-
function addSafeInteger(value, increment, field) {
|
|
26
|
-
if (!Number.isSafeInteger(value) ||
|
|
27
|
-
value < 0 ||
|
|
28
|
-
!Number.isSafeInteger(increment) ||
|
|
29
|
-
increment < 0 ||
|
|
30
|
-
value > Number.MAX_SAFE_INTEGER - increment) {
|
|
31
|
-
throw new RangeError(`${field} would exceed the non-negative safe integer range`);
|
|
32
|
-
}
|
|
33
|
-
return value + increment;
|
|
34
|
-
}
|
|
35
|
-
function boundedTruncationCount(current, increment) {
|
|
36
|
-
return Math.min(MAX_EVIDENCE_TRUNCATION_COUNT, current + increment);
|
|
37
|
-
}
|
|
38
|
-
function appendBoundedEvidence(existing, incoming, objectiveRevision, previousTruncation) {
|
|
39
|
-
const all = [...existing, ...incoming];
|
|
40
|
-
const carried = previousTruncation?.objectiveRevision === objectiveRevision ? previousTruncation : undefined;
|
|
41
|
-
if (all.length <= MAX_EVIDENCE_LEDGER_RECORDS) {
|
|
42
|
-
return { ledger: all, truncation: carried };
|
|
43
|
-
}
|
|
44
|
-
const retained = new Set();
|
|
45
|
-
const retainNewest = (records) => {
|
|
46
|
-
for (let index = records.length - 1; index >= 0; index -= 1) {
|
|
47
|
-
if (retained.size >= MAX_EVIDENCE_LEDGER_RECORDS)
|
|
48
|
-
return;
|
|
49
|
-
retained.add(records[index]);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
// Negative evidence for the current objective epoch is safety-critical. Keep
|
|
53
|
-
// it ahead of passing and old-epoch records; if more than the entire bounded
|
|
54
|
-
// ledger is negative, the truncation summary below makes completion fail
|
|
55
|
-
// closed even after later passing evidence arrives.
|
|
56
|
-
retainNewest(all.filter(record => record.objectiveRevision === objectiveRevision && record.result !== 'passed'));
|
|
57
|
-
retainNewest(all.filter(record => record.objectiveRevision === objectiveRevision));
|
|
58
|
-
retainNewest(all);
|
|
59
|
-
const ledger = all.filter(record => retained.has(record));
|
|
60
|
-
const dropped = all.filter(record => record.objectiveRevision === objectiveRevision && !retained.has(record));
|
|
61
|
-
if (dropped.length === 0)
|
|
62
|
-
return { ledger, truncation: carried };
|
|
63
|
-
const increment = (result) => dropped.filter(record => record.result === result).length;
|
|
64
|
-
return {
|
|
65
|
-
ledger,
|
|
66
|
-
truncation: {
|
|
67
|
-
objectiveRevision,
|
|
68
|
-
droppedPassed: boundedTruncationCount(carried?.droppedPassed ?? 0, increment('passed')),
|
|
69
|
-
droppedFailed: boundedTruncationCount(carried?.droppedFailed ?? 0, increment('failed')),
|
|
70
|
-
droppedInconclusive: boundedTruncationCount(carried?.droppedInconclusive ?? 0, increment('inconclusive')),
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function finalEvidenceReceipt(record) {
|
|
75
|
-
return {
|
|
76
|
-
evidenceId: record.id,
|
|
77
|
-
kind: record.kind,
|
|
78
|
-
provenance: record.kind === 'user'
|
|
79
|
-
? 'user_acceptance'
|
|
80
|
-
: record.kind === 'external'
|
|
81
|
-
? 'external'
|
|
82
|
-
: 'runtime_automatic',
|
|
83
|
-
result: record.result,
|
|
84
|
-
subject: record.subject,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function noProgressTurnSummary(outcome) {
|
|
88
|
-
const evidence = outcome.evidenceRecords ?? [];
|
|
89
|
-
return {
|
|
90
|
-
turnId: (0, redaction_1.redactTraceText)(String(outcome.turnId)).slice(0, 80),
|
|
91
|
-
endedAt: outcome.endedAt,
|
|
92
|
-
finishReason: (0, redaction_1.redactTraceText)(outcome.finishReason).slice(0, 80),
|
|
93
|
-
passedEvidence: evidence.filter(record => record.result === 'passed').length,
|
|
94
|
-
failedEvidence: evidence.filter(record => record.result === 'failed').length,
|
|
95
|
-
inconclusiveEvidence: evidence.filter(record => record.result === 'inconclusive').length,
|
|
96
|
-
planUpdateProposed: Boolean(outcome.pendingPlanUpdate),
|
|
97
|
-
blockerCategory: outcome.blocker?.category,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function formatNoProgressTurns(turns) {
|
|
101
|
-
return turns
|
|
102
|
-
.map(turn => `${turn.turnId} finish=${turn.finishReason} evidence=${turn.passedEvidence}p/${turn.failedEvidence}f/${turn.inconclusiveEvidence}i plan=${turn.planUpdateProposed ? 'no-change' : 'none'}${turn.blockerCategory ? ` blocker=${turn.blockerCategory}` : ''}`)
|
|
103
|
-
.join('; ');
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Build a minimal pending contract from an objective string. Used at creation
|
|
107
|
-
* and at load time to normalize v0.1.1 sidecars (which have no contract).
|
|
108
|
-
*
|
|
109
|
-
* The primary criterion is `source=user` because it is the user's verbatim
|
|
110
|
-
* objective, with a stable id so repeated
|
|
111
|
-
* normalizations of the same goal produce the same id (no churn on reload).
|
|
112
|
-
* User-supplied criteria (`source=user`) are added via a separate path.
|
|
113
|
-
*/
|
|
114
|
-
function minimalContract(objective, now, originalObjective = objective, completionAction) {
|
|
115
|
-
return {
|
|
116
|
-
originalObjective,
|
|
117
|
-
objectiveRevision: 0,
|
|
118
|
-
...(completionAction ? { completionAction } : {}),
|
|
119
|
-
constraints: [],
|
|
120
|
-
successCriteria: [
|
|
121
|
-
{
|
|
122
|
-
id: 'criterion:primary',
|
|
123
|
-
statement: objective,
|
|
124
|
-
source: 'user',
|
|
125
|
-
status: 'pending',
|
|
126
|
-
// External completion actions cannot be proven by local process output.
|
|
127
|
-
// Other primary criteria accept local runtime evidence; model natural
|
|
128
|
-
// language is never an accepted kind.
|
|
129
|
-
requiredEvidenceKinds: (0, completion_audit_1.criterionRequiresExternalCompletionEvidence)(objective)
|
|
130
|
-
? ['external', 'user']
|
|
131
|
-
: ['test', 'build', 'file', 'runtime'],
|
|
132
|
-
evidenceRefs: [],
|
|
133
|
-
},
|
|
134
|
-
],
|
|
135
|
-
planSnapshot: {
|
|
136
|
-
revision: 0,
|
|
137
|
-
phase: 'initial',
|
|
138
|
-
steps: [],
|
|
139
|
-
updatedAt: now,
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
const CONTRACT_EVIDENCE_KINDS = new Set([
|
|
144
|
-
'test',
|
|
145
|
-
'build',
|
|
146
|
-
'lint',
|
|
147
|
-
'file',
|
|
148
|
-
'runtime',
|
|
149
|
-
'external',
|
|
150
|
-
'user',
|
|
151
|
-
]);
|
|
152
|
-
const BOUNDARY_CONFIRMATION_PATTERN = /\b(publish|deploy|delete|erase|remove|drop|migrate|send|email|message|post|pay|purchase|merge|push|tag|overwrite|destroy|revoke|transfer|upload)\b|发布|部署|删除|清空|迁移|发送|付款|购买|合并|推送|打标签|覆盖|销毁|撤销|转账|上传/i;
|
|
153
|
-
/** High-impact external or destructive goals must not auto-start from model-created text. */
|
|
154
|
-
function goalRequiresBoundaryConfirmation(objective, input = {}) {
|
|
155
|
-
return [
|
|
156
|
-
objective,
|
|
157
|
-
...(input.constraints ?? []),
|
|
158
|
-
...(input.successCriteria ?? []).map(criterion => criterion.statement),
|
|
159
|
-
].some(statement => (0, completion_audit_1.hasUnnegatedActionMatch)(statement, BOUNDARY_CONFIRMATION_PATTERN));
|
|
160
|
-
}
|
|
161
|
-
function boundaryConfirmationState(objectiveRevision, now) {
|
|
162
|
-
return {
|
|
163
|
-
status: 'paused',
|
|
164
|
-
stopReason: {
|
|
165
|
-
kind: 'user',
|
|
166
|
-
message: 'Boundary confirmation required for an external, destructive, or high-impact Goal. Review the objective and constraints, then use /target resume to confirm.',
|
|
167
|
-
at: now,
|
|
168
|
-
},
|
|
169
|
-
boundaryConfirmation: {
|
|
170
|
-
requiredAt: now,
|
|
171
|
-
reason: 'external_destructive_or_high_impact',
|
|
172
|
-
objectiveRevision,
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function pauseForBoundaryConfirmation(goal, now) {
|
|
177
|
-
return {
|
|
178
|
-
...goal,
|
|
179
|
-
...boundaryConfirmationState(goal.contract?.objectiveRevision ?? 0, now),
|
|
180
|
-
updatedAt: now,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
function creationContract(objective, now, input, originalObjective = objective, completionAction) {
|
|
184
|
-
const constraints = input.constraints ?? [];
|
|
185
|
-
const successCriteria = input.successCriteria ?? [];
|
|
186
|
-
if (constraints.length > 50 || successCriteria.length > 50)
|
|
187
|
-
return null;
|
|
188
|
-
if (constraints.some(statement => !statement.trim()) ||
|
|
189
|
-
successCriteria.some(criterion => !criterion.statement.trim() ||
|
|
190
|
-
criterion.requiredEvidenceKinds.length === 0 ||
|
|
191
|
-
criterion.requiredEvidenceKinds.some(kind => !CONTRACT_EVIDENCE_KINDS.has(kind)))) {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
const contract = minimalContract(objective, now, originalObjective, completionAction);
|
|
195
|
-
contract.constraints = constraints.map((statement, index) => ({
|
|
196
|
-
id: `constraint:user:${index + 1}`,
|
|
197
|
-
statement: statement.trim(),
|
|
198
|
-
source: 'user',
|
|
199
|
-
}));
|
|
200
|
-
contract.successCriteria.push(...successCriteria.map((criterion, index) => ({
|
|
201
|
-
id: `criterion:user:${index + 1}`,
|
|
202
|
-
statement: criterion.statement.trim(),
|
|
203
|
-
source: 'user',
|
|
204
|
-
status: 'pending',
|
|
205
|
-
requiredEvidenceKinds: [...new Set(criterion.requiredEvidenceKinds)],
|
|
206
|
-
evidenceRefs: [],
|
|
207
|
-
})));
|
|
208
|
-
return contract;
|
|
209
|
-
}
|
|
210
|
-
function compactPlanValue(value) {
|
|
211
|
-
const compact = value?.replace(/\s+/gu, ' ').trim();
|
|
212
|
-
return compact || undefined;
|
|
213
|
-
}
|
|
214
|
-
function stablePlanStepKey(value) {
|
|
215
|
-
return value
|
|
216
|
-
.normalize('NFKC')
|
|
217
|
-
.toLowerCase()
|
|
218
|
-
.replace(/[^\p{L}\p{N}]+/gu, ' ')
|
|
219
|
-
.trim()
|
|
220
|
-
.replace(/\s+/gu, ' ');
|
|
221
|
-
}
|
|
222
|
-
const OBJECTIVE_TRACE_STOP_WORDS = new Set([
|
|
223
|
-
'add',
|
|
224
|
-
'build',
|
|
225
|
-
'check',
|
|
226
|
-
'code',
|
|
227
|
-
'complete',
|
|
228
|
-
'create',
|
|
229
|
-
'goal',
|
|
230
|
-
'implement',
|
|
231
|
-
'pass',
|
|
232
|
-
'run',
|
|
233
|
-
'test',
|
|
234
|
-
'update',
|
|
235
|
-
'verify',
|
|
236
|
-
]);
|
|
237
|
-
function objectiveTraceTokens(value) {
|
|
238
|
-
const tokens = new Set();
|
|
239
|
-
for (const raw of value
|
|
240
|
-
.normalize('NFKC')
|
|
241
|
-
.toLowerCase()
|
|
242
|
-
.match(/[\p{L}\p{N}_-]+/gu) ?? []) {
|
|
243
|
-
if (raw.length >= 3 && !OBJECTIVE_TRACE_STOP_WORDS.has(raw))
|
|
244
|
-
tokens.add(raw);
|
|
245
|
-
if (/\p{Script=Han}/u.test(raw)) {
|
|
246
|
-
const characters = Array.from(raw);
|
|
247
|
-
for (let index = 0; index < characters.length - 1; index += 1) {
|
|
248
|
-
tokens.add(`${characters[index]}${characters[index + 1]}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return tokens;
|
|
253
|
-
}
|
|
254
|
-
function criterionTracesToObjective(statement, contract) {
|
|
255
|
-
const objectiveTokens = objectiveTraceTokens(contract.originalObjective);
|
|
256
|
-
if (objectiveTokens.size === 0)
|
|
257
|
-
return false;
|
|
258
|
-
const criterionTokens = objectiveTraceTokens(statement);
|
|
259
|
-
return [...criterionTokens].some(token => objectiveTokens.has(token));
|
|
260
|
-
}
|
|
261
|
-
function substantivePlanProgress(contract, update, derivedCriteria) {
|
|
262
|
-
const current = contract.planSnapshot;
|
|
263
|
-
const completedStableStep = Boolean(current?.steps.some(step => {
|
|
264
|
-
if (step.done)
|
|
265
|
-
return false;
|
|
266
|
-
const key = stablePlanStepKey(step.description);
|
|
267
|
-
return Boolean(key && update.steps.some(next => next.done && stablePlanStepKey(next.description) === key));
|
|
268
|
-
}));
|
|
269
|
-
const traceableCriterionAdded = derivedCriteria.some(criterion => criterionTracesToObjective(criterion.statement, contract));
|
|
270
|
-
return completedStableStep || traceableCriterionAdded;
|
|
271
|
-
}
|
|
272
|
-
function stableEvidenceSource(sourceRef) {
|
|
273
|
-
const tool = /^tool:[^:]+:(.+)$/iu.exec(sourceRef.trim());
|
|
274
|
-
return compactPlanValue(tool ? `tool:${tool[1]}` : sourceRef)?.toLowerCase() ?? 'unknown';
|
|
275
|
-
}
|
|
276
|
-
function normalizedEvidenceSubject(subject) {
|
|
277
|
-
return (0, redaction_1.redactTraceText)(subject)
|
|
278
|
-
.normalize('NFKC')
|
|
279
|
-
.toLowerCase()
|
|
280
|
-
.replace(/[^\p{L}\p{N}_-]+/gu, ' ')
|
|
281
|
-
.trim()
|
|
282
|
-
.replace(/\s+/gu, ' ');
|
|
283
|
-
}
|
|
284
|
-
function evidenceProgressKeys(incoming, contract) {
|
|
285
|
-
const keys = new Set();
|
|
286
|
-
for (const record of incoming) {
|
|
287
|
-
if (record.result !== 'passed')
|
|
288
|
-
continue;
|
|
289
|
-
const stableSource = stableEvidenceSource(record.sourceRef);
|
|
290
|
-
const normalizedSubject = normalizedEvidenceSubject(record.subject);
|
|
291
|
-
const evidenceTokens = objectiveTraceTokens(`${normalizedSubject} ${stableSource}`);
|
|
292
|
-
for (const criterion of contract.successCriteria) {
|
|
293
|
-
if (!criterion.requiredEvidenceKinds.includes(record.kind))
|
|
294
|
-
continue;
|
|
295
|
-
const directCriterionReference = normalizedSubject.includes(criterion.id.toLowerCase()) ||
|
|
296
|
-
stableSource.includes(criterion.id.toLowerCase());
|
|
297
|
-
const criterionTokens = objectiveTraceTokens(criterion.statement);
|
|
298
|
-
const semanticallyRelated = [...criterionTokens].some(token => evidenceTokens.has(token));
|
|
299
|
-
if (!directCriterionReference && !semanticallyRelated)
|
|
300
|
-
continue;
|
|
301
|
-
const materialIdentity = [
|
|
302
|
-
record.objectiveRevision,
|
|
303
|
-
criterion.id,
|
|
304
|
-
record.kind,
|
|
305
|
-
stableSource,
|
|
306
|
-
normalizedSubject,
|
|
307
|
-
record.workspaceFingerprint ?? 'workspace:none',
|
|
308
|
-
].join('\u0000');
|
|
309
|
-
keys.add((0, crypto_1.createHash)('sha256').update(materialIdentity).digest('hex'));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return [...keys];
|
|
313
|
-
}
|
|
314
|
-
function criterionStateAdvanced(before, after, evidenceLedger) {
|
|
315
|
-
if (!after)
|
|
316
|
-
return false;
|
|
317
|
-
const passedEvidence = new Set(evidenceLedger.filter(record => record.result === 'passed').map(record => record.id));
|
|
318
|
-
const priorById = new Map(before.successCriteria.map(criterion => [criterion.id, criterion]));
|
|
319
|
-
return after.successCriteria.some(criterion => {
|
|
320
|
-
const prior = priorById.get(criterion.id);
|
|
321
|
-
if (!prior)
|
|
322
|
-
return false;
|
|
323
|
-
if (prior.status !== 'passed' && criterion.status === 'passed')
|
|
324
|
-
return true;
|
|
325
|
-
const priorRefs = new Set(prior.evidenceRefs);
|
|
326
|
-
return criterion.evidenceRefs.some(ref => !priorRefs.has(ref) && passedEvidence.has(ref));
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
function planContentChanged(contract, update) {
|
|
330
|
-
const current = contract.planSnapshot;
|
|
331
|
-
if (!current)
|
|
332
|
-
return true;
|
|
333
|
-
if (compactPlanValue(current.phase) !== compactPlanValue(update.phase))
|
|
334
|
-
return true;
|
|
335
|
-
if (compactPlanValue(current.nextAction) !== compactPlanValue(update.nextAction))
|
|
336
|
-
return true;
|
|
337
|
-
if (current.steps.length !== update.steps.length)
|
|
338
|
-
return true;
|
|
339
|
-
return current.steps.some((step, index) => {
|
|
340
|
-
const next = update.steps[index];
|
|
341
|
-
return (compactPlanValue(step.description) !== compactPlanValue(next.description) ||
|
|
342
|
-
step.done !== next.done);
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
function newDerivedCriteria(contract, update, planRevision) {
|
|
346
|
-
const existingStatements = new Set(contract.successCriteria.map(criterion => criterion.statement.trim().toLowerCase()));
|
|
347
|
-
return update.derivedCriteria
|
|
348
|
-
.filter(item => !existingStatements.has(item.statement.trim().toLowerCase()))
|
|
349
|
-
.map((item, index) => ({
|
|
350
|
-
id: `criterion:derived:${planRevision}:${index + 1}`,
|
|
351
|
-
statement: item.statement,
|
|
352
|
-
source: 'derived',
|
|
353
|
-
status: 'pending',
|
|
354
|
-
requiredEvidenceKinds: item.requiredEvidenceKinds,
|
|
355
|
-
evidenceRefs: [],
|
|
356
|
-
}));
|
|
357
|
-
}
|
|
358
|
-
/** Ensure a loaded goal carries a contract; normalize v0.1.1 sidecars. */
|
|
359
|
-
function ensureContract(goal) {
|
|
360
|
-
const normalized = (0, objective_1.normalizeGoalObjective)(goal.objective);
|
|
361
|
-
const shouldMigrateExitAction = normalized.completionAction === 'exit_goal' &&
|
|
362
|
-
Boolean(normalized.objective) &&
|
|
363
|
-
goal.status !== 'complete';
|
|
364
|
-
if (goal.contract && shouldMigrateExitAction) {
|
|
365
|
-
const failedAudit = goal.completionAudit?.passed === false;
|
|
366
|
-
const normalizedContract = {
|
|
367
|
-
...goal.contract,
|
|
368
|
-
completionAction: 'exit_goal',
|
|
369
|
-
successCriteria: goal.contract.successCriteria.map(criterion => criterion.id === 'criterion:primary'
|
|
370
|
-
? {
|
|
371
|
-
...criterion,
|
|
372
|
-
statement: normalized.objective,
|
|
373
|
-
...(failedAudit ? { status: 'pending' } : {}),
|
|
374
|
-
}
|
|
375
|
-
: criterion),
|
|
376
|
-
...(failedAudit && goal.contract.planSnapshot
|
|
377
|
-
? {
|
|
378
|
-
planSnapshot: {
|
|
379
|
-
...goal.contract.planSnapshot,
|
|
380
|
-
phase: 'execution',
|
|
381
|
-
nextAction: `Verify and complete: ${normalized.objective}`,
|
|
382
|
-
},
|
|
383
|
-
}
|
|
384
|
-
: {}),
|
|
385
|
-
};
|
|
386
|
-
return {
|
|
387
|
-
...goal,
|
|
388
|
-
objective: normalized.objective,
|
|
389
|
-
contract: normalizedContract,
|
|
390
|
-
completionAudit: failedAudit ? undefined : goal.completionAudit,
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
if (goal.contract)
|
|
394
|
-
return goal;
|
|
395
|
-
const objective = shouldMigrateExitAction ? normalized.objective : goal.objective;
|
|
396
|
-
const contract = minimalContract(objective, goal.updatedAt || goal.createdAt, shouldMigrateExitAction ? normalized.originalObjective : objective, shouldMigrateExitAction ? normalized.completionAction : undefined);
|
|
397
|
-
const normalizedLegacy = {
|
|
398
|
-
...goal,
|
|
399
|
-
objective,
|
|
400
|
-
contract,
|
|
401
|
-
completedAt: undefined,
|
|
402
|
-
completionAudit: undefined,
|
|
403
|
-
};
|
|
404
|
-
if (goal.status === 'active') {
|
|
405
|
-
return {
|
|
406
|
-
...normalizedLegacy,
|
|
407
|
-
blocker: undefined,
|
|
408
|
-
stopReason: undefined,
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
if (goal.status === 'blocked' && (!goal.blocker || goal.stopReason?.kind !== 'blocked')) {
|
|
412
|
-
return {
|
|
413
|
-
...normalizedLegacy,
|
|
414
|
-
status: 'paused',
|
|
415
|
-
blocker: undefined,
|
|
416
|
-
stopReason: {
|
|
417
|
-
kind: 'user',
|
|
418
|
-
message: 'Legacy blocked state requires v0.1.2 blocker re-verification.',
|
|
419
|
-
at: Date.now(),
|
|
420
|
-
},
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
if (goal.status !== 'complete')
|
|
424
|
-
return normalizedLegacy;
|
|
425
|
-
const now = Date.now();
|
|
426
|
-
return {
|
|
427
|
-
...normalizedLegacy,
|
|
428
|
-
status: 'paused',
|
|
429
|
-
stopReason: {
|
|
430
|
-
kind: 'user',
|
|
431
|
-
message: 'Legacy completion requires v0.1.2 evidence re-verification.',
|
|
432
|
-
at: now,
|
|
433
|
-
},
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
class GoalCoordinator {
|
|
437
|
-
constructor(projectPath, sessionId) {
|
|
438
|
-
this.projectPath = projectPath;
|
|
439
|
-
this.sessionId = sessionId;
|
|
440
|
-
this.state = { goal: null, generation: 0, continuationDeferred: false };
|
|
441
|
-
this.loadIssue = null;
|
|
442
|
-
/** A failed reload requires storage recovery before a fresh Goal may be written. */
|
|
443
|
-
this.loadRecoveryRequired = false;
|
|
444
|
-
/** Runtime-only dedupe for interrupted stale turns; in-flight turns do not survive restart. */
|
|
445
|
-
this.accountedStaleTurnKeys = new Set();
|
|
446
|
-
/** Last disk-authoritative state, used when both a write and recovery read fail. */
|
|
447
|
-
this.persistedGoalSnapshot = null;
|
|
448
|
-
}
|
|
449
|
-
// ==========================================================================
|
|
450
|
-
// Queries
|
|
451
|
-
// ==========================================================================
|
|
452
|
-
get goal() {
|
|
453
|
-
return this.state.goal;
|
|
454
|
-
}
|
|
455
|
-
get generation() {
|
|
456
|
-
return this.state.generation;
|
|
457
|
-
}
|
|
458
|
-
get boundSessionId() {
|
|
459
|
-
return this.sessionId;
|
|
460
|
-
}
|
|
461
|
-
get isActive() {
|
|
462
|
-
return this.state.goal?.status === 'active';
|
|
463
|
-
}
|
|
464
|
-
get canContinue() {
|
|
465
|
-
return (this.isActive &&
|
|
466
|
-
!this.state.continuationDeferred &&
|
|
467
|
-
!(0, accounting_1.isBudgetExceeded)(this.state.goal.tokensUsed, this.state.goal.tokenBudget));
|
|
468
|
-
}
|
|
469
|
-
/** Typed explanation for the current Goal boundary; active Goals have no stop decision. */
|
|
470
|
-
get stopDecision() {
|
|
471
|
-
return (0, stop_policy_1.goalStopDecision)(this.state.goal);
|
|
472
|
-
}
|
|
473
|
-
get lastLoadIssue() {
|
|
474
|
-
return this.loadIssue;
|
|
475
|
-
}
|
|
476
|
-
addGoalInteger(value, increment, field) {
|
|
477
|
-
try {
|
|
478
|
-
return addSafeInteger(value, increment, field);
|
|
479
|
-
}
|
|
480
|
-
catch (error) {
|
|
481
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
482
|
-
this.failClosedAfterPersistenceError(message);
|
|
483
|
-
throw error;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
loadRecoveryMessage() {
|
|
487
|
-
const detail = this.loadIssue?.message ?? 'Goal storage state is not readable.';
|
|
488
|
-
return `Goal storage recovery is required before creating or replacing a Goal. ${detail}`;
|
|
489
|
-
}
|
|
490
|
-
snapshot() {
|
|
491
|
-
const g = this.state.goal;
|
|
492
|
-
if (!g)
|
|
493
|
-
return null;
|
|
494
|
-
const criteria = g.contract?.successCriteria ?? [];
|
|
495
|
-
return {
|
|
496
|
-
goalId: g.goalId,
|
|
497
|
-
revision: g.revision,
|
|
498
|
-
objective: g.objective,
|
|
499
|
-
status: g.status,
|
|
500
|
-
tokenBudget: g.tokenBudget,
|
|
501
|
-
tokensUsed: g.tokensUsed,
|
|
502
|
-
timeUsedMs: g.timeUsedMs,
|
|
503
|
-
continuationCount: g.continuationCount,
|
|
504
|
-
automaticContinuationStreak: g.automaticContinuationStreak ?? 0,
|
|
505
|
-
updatedAt: g.updatedAt,
|
|
506
|
-
stopReason: g.stopReason?.message,
|
|
507
|
-
criteria: {
|
|
508
|
-
passed: criteria.filter(criterion => criterion.status === 'passed').length,
|
|
509
|
-
failed: criteria.filter(criterion => criterion.status === 'failed').length,
|
|
510
|
-
stale: criteria.filter(criterion => criterion.status === 'stale').length,
|
|
511
|
-
total: criteria.length,
|
|
512
|
-
},
|
|
513
|
-
planRevision: g.contract?.planSnapshot?.revision,
|
|
514
|
-
planPhase: g.contract?.planSnapshot?.phase,
|
|
515
|
-
nextAction: g.contract?.planSnapshot?.nextAction,
|
|
516
|
-
auditRemaining: g.completionAudit?.remainingRequirements,
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
// ==========================================================================
|
|
520
|
-
// Lifecycle
|
|
521
|
-
// ==========================================================================
|
|
522
|
-
load(recoverActive = false) {
|
|
523
|
-
const result = (0, goal_storage_1.loadGoal)(this.projectPath, this.sessionId);
|
|
524
|
-
if (result.ok) {
|
|
525
|
-
this.loadIssue = null;
|
|
526
|
-
this.loadRecoveryRequired = false;
|
|
527
|
-
// v0.1.2: normalize v0.1.1 sidecars (no contract) into a minimal pending
|
|
528
|
-
// contract. This is in-memory only; it does not rewrite the sidecar
|
|
529
|
-
// until the next real state update.
|
|
530
|
-
this.state.goal = ensureContract(result.value);
|
|
531
|
-
this.persistedGoalSnapshot = structuredClone(this.state.goal);
|
|
532
|
-
// Every reload replaces the in-memory authority, even if the disk bytes
|
|
533
|
-
// are unchanged. Advance the runtime epoch so pre-reload outcomes cannot
|
|
534
|
-
// finalize or account against the newly loaded state.
|
|
535
|
-
this.state.generation += 1;
|
|
536
|
-
this.state.continuationDeferred = false;
|
|
537
|
-
if (recoverActive && this.state.goal.status === 'active') {
|
|
538
|
-
const loadedGoal = this.state.goal;
|
|
539
|
-
const lockPath = (0, path_1.join)((0, config_dir_1.getProjectSessionsDir)(this.projectPath), `${this.sessionId}.goal.json.lock`);
|
|
540
|
-
if ((0, fs_1.existsSync)(lockPath)) {
|
|
541
|
-
const message = `Restart recovery could not persist a paused Goal because storage is temporarily locked at ${lockPath}. No continuation was started; resolve the lock, then use /target resume.`;
|
|
542
|
-
this.loadIssue = { code: 'io_error', message };
|
|
543
|
-
this.loadRecoveryRequired = true;
|
|
544
|
-
this.failClosedAfterPersistenceError(message);
|
|
545
|
-
return true;
|
|
546
|
-
}
|
|
547
|
-
try {
|
|
548
|
-
this.state.goal = {
|
|
549
|
-
...loadedGoal,
|
|
550
|
-
status: 'paused',
|
|
551
|
-
revision: addSafeInteger(loadedGoal.revision, 1, 'revision'),
|
|
552
|
-
updatedAt: Date.now(),
|
|
553
|
-
stopReason: {
|
|
554
|
-
kind: 'user',
|
|
555
|
-
message: 'Recovered after restart. Use /target resume to continue.',
|
|
556
|
-
at: Date.now(),
|
|
557
|
-
},
|
|
558
|
-
};
|
|
559
|
-
this.state.continuationDeferred = true;
|
|
560
|
-
this.persist();
|
|
561
|
-
}
|
|
562
|
-
catch (error) {
|
|
563
|
-
const detail = (0, redaction_1.redactTraceText)(error instanceof Error ? error.message : String(error));
|
|
564
|
-
const message = `Restart recovery could not persist a paused Goal. No continuation was started; resolve the storage error, then use /target resume. ${detail}`;
|
|
565
|
-
this.loadIssue = { code: 'io_error', message };
|
|
566
|
-
this.loadRecoveryRequired = true;
|
|
567
|
-
this.failClosedAfterPersistenceError(message);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return true;
|
|
571
|
-
}
|
|
572
|
-
this.loadIssue = ['corrupt', 'metadata_mismatch', 'incompatible_schema', 'io_error'].includes(result.error)
|
|
573
|
-
? {
|
|
574
|
-
code: result.error,
|
|
575
|
-
message: result.message,
|
|
576
|
-
}
|
|
577
|
-
: null;
|
|
578
|
-
// A missing sidecar is an authoritative empty state and permits a fresh
|
|
579
|
-
// create. Every other load failure leaves the write path recovery-gated;
|
|
580
|
-
// otherwise create/replace could hide the unreadable sidecar.
|
|
581
|
-
this.loadRecoveryRequired = result.error !== 'not_found';
|
|
582
|
-
// A failed repeat load makes the disk state authoritative and the previous
|
|
583
|
-
// in-memory Goal unsafe to continue. Invalidate in-flight work and discard
|
|
584
|
-
// both cached copies without attempting to write the stale Goal back.
|
|
585
|
-
this.state.generation += 1;
|
|
586
|
-
this.state.continuationDeferred = true;
|
|
587
|
-
this.state.goal = null;
|
|
588
|
-
this.persistedGoalSnapshot = null;
|
|
589
|
-
return false;
|
|
590
|
-
}
|
|
591
|
-
create(objective, contractInput = {}) {
|
|
592
|
-
if (this.loadRecoveryRequired) {
|
|
593
|
-
return { ok: false, error: this.loadRecoveryMessage() };
|
|
594
|
-
}
|
|
595
|
-
if (this.state.goal && !types_1.GOAL_TERMINAL_STATES.has(this.state.goal.status)) {
|
|
596
|
-
return {
|
|
597
|
-
ok: false,
|
|
598
|
-
error: 'An active goal already exists. Use /target replace to change it.',
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
const normalized = (0, objective_1.normalizeGoalObjective)(objective);
|
|
602
|
-
if (!normalized.originalObjective) {
|
|
603
|
-
return { ok: false, error: 'Objective cannot be empty.' };
|
|
604
|
-
}
|
|
605
|
-
if (!normalized.objective && normalized.completionAction === 'exit_goal') {
|
|
606
|
-
return {
|
|
607
|
-
ok: false,
|
|
608
|
-
error: 'Goal exit is a lifecycle command, not an objective. Use /goal exit.',
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
if (normalized.originalObjective.length > types_1.GOAL_INVARIANTS.maxObjectiveChars) {
|
|
612
|
-
return {
|
|
613
|
-
ok: false,
|
|
614
|
-
error: `Objective too long (max ${types_1.GOAL_INVARIANTS.maxObjectiveChars} chars).`,
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
const now = Date.now();
|
|
618
|
-
const contract = creationContract(normalized.objective, now, contractInput, normalized.originalObjective, normalized.completionAction);
|
|
619
|
-
if (!contract) {
|
|
620
|
-
return { ok: false, error: 'Goal constraints or success criteria are invalid.' };
|
|
621
|
-
}
|
|
622
|
-
const requiresBoundaryConfirmation = goalRequiresBoundaryConfirmation(normalized.objective, contractInput);
|
|
623
|
-
const result = (0, goal_storage_1.createGoal)(this.projectPath, this.sessionId, normalized.objective, contract, this.state.goal?.revision, requiresBoundaryConfirmation
|
|
624
|
-
? boundaryConfirmationState(contract.objectiveRevision, now)
|
|
625
|
-
: undefined);
|
|
626
|
-
if (!result.ok)
|
|
627
|
-
return { ok: false, error: result.message };
|
|
628
|
-
const created = result.value;
|
|
629
|
-
this.state.goal = created;
|
|
630
|
-
this.persistedGoalSnapshot = structuredClone(created);
|
|
631
|
-
this.state.generation += 1;
|
|
632
|
-
this.state.continuationDeferred = created.status !== 'active';
|
|
633
|
-
return { ok: true };
|
|
634
|
-
}
|
|
635
|
-
pause() {
|
|
636
|
-
if (!this.state.goal || this.state.goal.status !== 'active')
|
|
637
|
-
return false;
|
|
638
|
-
this.state.goal = {
|
|
639
|
-
...this.state.goal,
|
|
640
|
-
status: 'paused',
|
|
641
|
-
revision: this.addGoalInteger(this.state.goal.revision, 1, 'revision'),
|
|
642
|
-
updatedAt: Date.now(),
|
|
643
|
-
stopReason: { kind: 'user', message: 'Paused by user.', at: Date.now() },
|
|
644
|
-
};
|
|
645
|
-
this.persist();
|
|
646
|
-
this.state.continuationDeferred = true;
|
|
647
|
-
return true;
|
|
648
|
-
}
|
|
649
|
-
resume(options = {}) {
|
|
650
|
-
if (!this.state.goal || !types_1.GOAL_USER_RECOVERABLE_STATES.has(this.state.goal.status))
|
|
651
|
-
return false;
|
|
652
|
-
const pendingBoundary = this.state.goal.boundaryConfirmation &&
|
|
653
|
-
this.state.goal.boundaryConfirmation.confirmedAt === undefined;
|
|
654
|
-
if (pendingBoundary &&
|
|
655
|
-
(!options.confirmBoundary ||
|
|
656
|
-
options.expectedGoalId !== this.state.goal.goalId ||
|
|
657
|
-
options.expectedRevision !== this.state.goal.revision)) {
|
|
658
|
-
return false;
|
|
659
|
-
}
|
|
660
|
-
const resumedAt = Date.now();
|
|
661
|
-
this.state.goal = {
|
|
662
|
-
...this.state.goal,
|
|
663
|
-
status: 'active',
|
|
664
|
-
revision: this.addGoalInteger(this.state.goal.revision, 1, 'revision'),
|
|
665
|
-
updatedAt: resumedAt,
|
|
666
|
-
activeSince: resumedAt,
|
|
667
|
-
stopReason: undefined,
|
|
668
|
-
blocker: undefined,
|
|
669
|
-
noProgressCount: 0,
|
|
670
|
-
automaticContinuationStreak: 0,
|
|
671
|
-
recentNoProgressTurns: [],
|
|
672
|
-
boundaryConfirmation: pendingBoundary
|
|
673
|
-
? {
|
|
674
|
-
...this.state.goal.boundaryConfirmation,
|
|
675
|
-
confirmedAt: resumedAt,
|
|
676
|
-
confirmedRevision: this.state.goal.revision,
|
|
677
|
-
}
|
|
678
|
-
: this.state.goal.boundaryConfirmation,
|
|
679
|
-
};
|
|
680
|
-
this.persist();
|
|
681
|
-
this.state.continuationDeferred = false;
|
|
682
|
-
return true;
|
|
683
|
-
}
|
|
684
|
-
edit(objective, reason = 'User invoked /target edit.') {
|
|
685
|
-
if (!this.state.goal || types_1.GOAL_TERMINAL_STATES.has(this.state.goal.status))
|
|
686
|
-
return false;
|
|
687
|
-
const normalized = (0, objective_1.normalizeGoalObjective)(objective);
|
|
688
|
-
if (!normalized.objective)
|
|
689
|
-
return false;
|
|
690
|
-
const g = this.state.goal;
|
|
691
|
-
const nextObjective = normalized.objective;
|
|
692
|
-
const currentContract = g.contract ?? minimalContract(g.objective, g.updatedAt);
|
|
693
|
-
if (nextObjective === g.objective &&
|
|
694
|
-
normalized.completionAction === currentContract.completionAction) {
|
|
695
|
-
return true;
|
|
696
|
-
}
|
|
697
|
-
const changedAt = Date.now();
|
|
698
|
-
// v0.1.2: preserve originalObjective; record an objective revision on the
|
|
699
|
-
// contract so steering can never silently rewrite the root goal. The
|
|
700
|
-
// top-level `objective` reflects the current wording.
|
|
701
|
-
const objectiveRevision = this.addGoalInteger(currentContract.objectiveRevision, 1, 'contract.objectiveRevision');
|
|
702
|
-
const contract = {
|
|
703
|
-
...currentContract,
|
|
704
|
-
originalObjective: currentContract.originalObjective,
|
|
705
|
-
objectiveRevision,
|
|
706
|
-
completionAction: normalized.completionAction,
|
|
707
|
-
objectiveHistory: [
|
|
708
|
-
...(currentContract.objectiveHistory ?? []),
|
|
709
|
-
{
|
|
710
|
-
revision: objectiveRevision,
|
|
711
|
-
previousObjective: g.objective,
|
|
712
|
-
objective: nextObjective,
|
|
713
|
-
reason: reason.trim() || 'User invoked /target edit.',
|
|
714
|
-
changedAt,
|
|
715
|
-
source: 'user',
|
|
716
|
-
},
|
|
717
|
-
].slice(-50),
|
|
718
|
-
successCriteria: currentContract.successCriteria.map(criterion => criterion.id === 'criterion:primary'
|
|
719
|
-
? {
|
|
720
|
-
...criterion,
|
|
721
|
-
statement: nextObjective,
|
|
722
|
-
source: 'user',
|
|
723
|
-
status: 'pending',
|
|
724
|
-
evidenceRefs: [],
|
|
725
|
-
}
|
|
726
|
-
: criterion),
|
|
727
|
-
};
|
|
728
|
-
const edited = {
|
|
729
|
-
...g,
|
|
730
|
-
objective: nextObjective,
|
|
731
|
-
contract,
|
|
732
|
-
revision: this.addGoalInteger(g.revision, 1, 'revision'),
|
|
733
|
-
updatedAt: changedAt,
|
|
734
|
-
completionAudit: undefined,
|
|
735
|
-
// Truncation is scoped to an objective epoch. A user edit intentionally
|
|
736
|
-
// starts a fresh verification epoch; old evidence remains provenance but
|
|
737
|
-
// cannot permanently block the edited objective.
|
|
738
|
-
evidenceLedgerTruncation: undefined,
|
|
739
|
-
};
|
|
740
|
-
const preservedContractInput = {
|
|
741
|
-
constraints: contract.constraints.map(constraint => constraint.statement),
|
|
742
|
-
successCriteria: contract.successCriteria.map(criterion => ({
|
|
743
|
-
statement: criterion.statement,
|
|
744
|
-
requiredEvidenceKinds: criterion.requiredEvidenceKinds,
|
|
745
|
-
})),
|
|
746
|
-
};
|
|
747
|
-
this.state.goal = goalRequiresBoundaryConfirmation(nextObjective, preservedContractInput)
|
|
748
|
-
? { ...pauseForBoundaryConfirmation(edited, changedAt), revision: edited.revision }
|
|
749
|
-
: { ...edited, boundaryConfirmation: undefined };
|
|
750
|
-
this.persist();
|
|
751
|
-
this.state.continuationDeferred = this.state.goal.status !== 'active';
|
|
752
|
-
return true;
|
|
753
|
-
}
|
|
754
|
-
/** Record trusted human acceptance for a criterion that requires user evidence. */
|
|
755
|
-
confirmCriterion(criterionId) {
|
|
756
|
-
const goal = this.state.goal;
|
|
757
|
-
const contract = goal?.contract;
|
|
758
|
-
if (!goal || !contract || types_1.GOAL_TERMINAL_STATES.has(goal.status))
|
|
759
|
-
return false;
|
|
760
|
-
const criterion = contract.successCriteria.find(item => item.id === criterionId.trim());
|
|
761
|
-
if (!criterion || !criterion.requiredEvidenceKinds.includes('user'))
|
|
762
|
-
return false;
|
|
763
|
-
const now = Date.now();
|
|
764
|
-
const revision = this.addGoalInteger(goal.revision, 1, 'revision');
|
|
765
|
-
const evidenceId = `evidence:user:${(0, crypto_1.randomUUID)()}`;
|
|
766
|
-
const record = {
|
|
767
|
-
id: evidenceId,
|
|
768
|
-
goalId: goal.goalId,
|
|
769
|
-
goalRevision: revision,
|
|
770
|
-
objectiveRevision: contract.objectiveRevision,
|
|
771
|
-
turnId: `user-confirmation:${revision}`,
|
|
772
|
-
kind: 'user',
|
|
773
|
-
subject: `User confirmed ${criterion.id}: ${criterion.statement}`.slice(0, 240),
|
|
774
|
-
result: 'passed',
|
|
775
|
-
sourceRef: 'user:/target-confirm',
|
|
776
|
-
capturedAt: now,
|
|
777
|
-
redacted: true,
|
|
778
|
-
};
|
|
779
|
-
const boundedEvidence = appendBoundedEvidence(goal.evidenceLedger ?? [], [record], contract.objectiveRevision, goal.evidenceLedgerTruncation);
|
|
780
|
-
this.state.goal = {
|
|
781
|
-
...goal,
|
|
782
|
-
revision,
|
|
783
|
-
updatedAt: now,
|
|
784
|
-
evidenceLedger: boundedEvidence.ledger,
|
|
785
|
-
evidenceLedgerTruncation: boundedEvidence.truncation,
|
|
786
|
-
contract: {
|
|
787
|
-
...contract,
|
|
788
|
-
successCriteria: contract.successCriteria.map(item => item.id === criterion.id
|
|
789
|
-
? {
|
|
790
|
-
...item,
|
|
791
|
-
status: 'passed',
|
|
792
|
-
evidenceRefs: [...new Set([...item.evidenceRefs, evidenceId])],
|
|
793
|
-
}
|
|
794
|
-
: item),
|
|
795
|
-
},
|
|
796
|
-
completionAudit: undefined,
|
|
797
|
-
};
|
|
798
|
-
this.persist();
|
|
799
|
-
return true;
|
|
800
|
-
}
|
|
801
|
-
addConstraint(statement) {
|
|
802
|
-
const goal = this.state.goal;
|
|
803
|
-
const trimmed = statement.trim();
|
|
804
|
-
if (!goal || goal.status === 'complete' || !trimmed)
|
|
805
|
-
return false;
|
|
806
|
-
const contract = goal.contract ?? minimalContract(goal.objective, goal.updatedAt);
|
|
807
|
-
if (contract.constraints.some(constraint => constraint.statement === trimmed))
|
|
808
|
-
return true;
|
|
809
|
-
const revision = this.addGoalInteger(goal.revision, 1, 'revision');
|
|
810
|
-
this.state.goal = {
|
|
811
|
-
...goal,
|
|
812
|
-
contract: {
|
|
813
|
-
...contract,
|
|
814
|
-
constraints: [
|
|
815
|
-
...contract.constraints,
|
|
816
|
-
{
|
|
817
|
-
id: `constraint:user:${revision}`,
|
|
818
|
-
statement: trimmed,
|
|
819
|
-
source: 'user',
|
|
820
|
-
},
|
|
821
|
-
],
|
|
822
|
-
},
|
|
823
|
-
revision,
|
|
824
|
-
updatedAt: Date.now(),
|
|
825
|
-
};
|
|
826
|
-
this.persist();
|
|
827
|
-
return true;
|
|
828
|
-
}
|
|
829
|
-
replace(objective) {
|
|
830
|
-
if (this.loadRecoveryRequired)
|
|
831
|
-
return false;
|
|
832
|
-
const normalized = (0, objective_1.normalizeGoalObjective)(objective);
|
|
833
|
-
if (!normalized.objective)
|
|
834
|
-
return false;
|
|
835
|
-
// Create new goal with fresh goalId and fresh contract; old generation
|
|
836
|
-
// invalidated. Does not reuse the old goal's completion state.
|
|
837
|
-
const now = Date.now();
|
|
838
|
-
const contract = minimalContract(normalized.objective, now, normalized.originalObjective, normalized.completionAction);
|
|
839
|
-
const requiresBoundaryConfirmation = goalRequiresBoundaryConfirmation(normalized.objective);
|
|
840
|
-
const result = (0, goal_storage_1.createGoal)(this.projectPath, this.sessionId, normalized.objective, contract, this.state.goal?.revision, requiresBoundaryConfirmation
|
|
841
|
-
? boundaryConfirmationState(contract.objectiveRevision, now)
|
|
842
|
-
: undefined);
|
|
843
|
-
if (!result.ok) {
|
|
844
|
-
this.restoreDiskAuthorityAfterMutationFailure();
|
|
845
|
-
return false;
|
|
846
|
-
}
|
|
847
|
-
const replacement = result.value;
|
|
848
|
-
this.state.goal = replacement;
|
|
849
|
-
this.persistedGoalSnapshot = structuredClone(replacement);
|
|
850
|
-
this.state.generation += 1;
|
|
851
|
-
this.state.continuationDeferred = replacement.status !== 'active';
|
|
852
|
-
return true;
|
|
853
|
-
}
|
|
854
|
-
setBudget(tokenBudget) {
|
|
855
|
-
if (!this.state.goal || this.state.goal.status === 'complete')
|
|
856
|
-
return false;
|
|
857
|
-
this.state.goal = {
|
|
858
|
-
...this.state.goal,
|
|
859
|
-
tokenBudget: tokenBudget ?? undefined,
|
|
860
|
-
revision: this.addGoalInteger(this.state.goal.revision, 1, 'revision'),
|
|
861
|
-
updatedAt: Date.now(),
|
|
862
|
-
};
|
|
863
|
-
this.persist();
|
|
864
|
-
return true;
|
|
865
|
-
}
|
|
866
|
-
clear() {
|
|
867
|
-
if (!this.state.goal)
|
|
868
|
-
return false;
|
|
869
|
-
const result = (0, goal_storage_1.deleteGoal)(this.projectPath, this.sessionId, this.state.goal.revision, this.state.goal.goalId);
|
|
870
|
-
if (!result.ok) {
|
|
871
|
-
this.restoreDiskAuthorityAfterMutationFailure();
|
|
872
|
-
throw new Error(`${result.error}: ${result.message}`);
|
|
873
|
-
}
|
|
874
|
-
this.state.goal = null;
|
|
875
|
-
this.persistedGoalSnapshot = null;
|
|
876
|
-
this.state.generation += 1;
|
|
877
|
-
this.state.continuationDeferred = false;
|
|
878
|
-
return true;
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* Detach a completed Goal from the live runtime after its session binding is
|
|
882
|
-
* cleared. The persisted sidecar remains the immutable completion receipt.
|
|
883
|
-
*/
|
|
884
|
-
detachCompletedReceipt(expectedGoalId) {
|
|
885
|
-
const goal = this.state.goal;
|
|
886
|
-
if (!goal ||
|
|
887
|
-
goal.goalId !== expectedGoalId ||
|
|
888
|
-
goal.status !== 'complete' ||
|
|
889
|
-
goal.completionAudit?.passed !== true) {
|
|
890
|
-
return false;
|
|
891
|
-
}
|
|
892
|
-
this.state.goal = null;
|
|
893
|
-
this.persistedGoalSnapshot = null;
|
|
894
|
-
this.state.generation += 1;
|
|
895
|
-
this.state.continuationDeferred = false;
|
|
896
|
-
return true;
|
|
897
|
-
}
|
|
898
|
-
// ==========================================================================
|
|
899
|
-
// Turn integration
|
|
900
|
-
// ==========================================================================
|
|
901
|
-
buildContinuationRequest() {
|
|
902
|
-
if (!this.canContinue)
|
|
903
|
-
return null;
|
|
904
|
-
const g = this.state.goal;
|
|
905
|
-
let continuationIndex;
|
|
906
|
-
try {
|
|
907
|
-
continuationIndex = this.addGoalInteger(g.continuationCount, 1, 'continuationCount');
|
|
908
|
-
}
|
|
909
|
-
catch {
|
|
910
|
-
return null;
|
|
911
|
-
}
|
|
912
|
-
return {
|
|
913
|
-
inputKind: 'goal_continuation',
|
|
914
|
-
sessionId: this.sessionId,
|
|
915
|
-
persistAsUserMessage: false,
|
|
916
|
-
echoToTranscript: false,
|
|
917
|
-
generation: this.state.generation,
|
|
918
|
-
goal: {
|
|
919
|
-
goalId: g.goalId,
|
|
920
|
-
revision: g.revision,
|
|
921
|
-
continuationIndex,
|
|
922
|
-
},
|
|
923
|
-
};
|
|
924
|
-
}
|
|
925
|
-
finalizeTurn(outcome) {
|
|
926
|
-
const g = this.state.goal;
|
|
927
|
-
if (!g)
|
|
928
|
-
return;
|
|
929
|
-
if (outcome.sessionId !== this.sessionId ||
|
|
930
|
-
outcome.goalId !== g.goalId ||
|
|
931
|
-
outcome.goalRevision !== g.revision ||
|
|
932
|
-
(outcome.goalGeneration !== undefined && outcome.goalGeneration !== this.state.generation))
|
|
933
|
-
return;
|
|
934
|
-
if (outcome.usageComplete === false) {
|
|
935
|
-
const accounting = (0, accounting_1.accumulateTurn)({
|
|
936
|
-
tokensUsed: g.tokensUsed,
|
|
937
|
-
timeUsedMs: g.timeUsedMs,
|
|
938
|
-
continuationCount: g.continuationCount,
|
|
939
|
-
noProgressCount: g.noProgressCount,
|
|
940
|
-
}, outcome);
|
|
941
|
-
const pausedAt = Date.now();
|
|
942
|
-
const tokensUsed = this.addGoalInteger(accounting.tokensUsed, 0, 'tokensUsed');
|
|
943
|
-
const timeUsedMs = this.addGoalInteger(accounting.timeUsedMs, 0, 'timeUsedMs');
|
|
944
|
-
const continuationCount = this.addGoalInteger(accounting.continuationCount, 0, 'continuationCount');
|
|
945
|
-
const noProgressCount = this.addGoalInteger(accounting.noProgressCount, 0, 'noProgressCount');
|
|
946
|
-
const automaticContinuationStreak = outcome.inputKind === 'goal_continuation'
|
|
947
|
-
? this.addGoalInteger(g.automaticContinuationStreak ?? 0, 1, 'automaticContinuationStreak')
|
|
948
|
-
: 0;
|
|
949
|
-
this.state.goal = {
|
|
950
|
-
...g,
|
|
951
|
-
tokensUsed,
|
|
952
|
-
timeUsedMs,
|
|
953
|
-
continuationCount,
|
|
954
|
-
automaticContinuationStreak,
|
|
955
|
-
noProgressCount,
|
|
956
|
-
status: 'paused',
|
|
957
|
-
revision: this.addGoalInteger(g.revision, 1, 'revision'),
|
|
958
|
-
updatedAt: pausedAt,
|
|
959
|
-
lastTurn: {
|
|
960
|
-
turnId: outcome.turnId,
|
|
961
|
-
finishReason: outcome.finishReason,
|
|
962
|
-
endedAt: outcome.endedAt,
|
|
963
|
-
promptTokens: outcome.usage.promptTokens,
|
|
964
|
-
completionTokens: outcome.usage.completionTokens,
|
|
965
|
-
subagentTokens: outcome.usage.subagentTokens,
|
|
966
|
-
totalTokens: outcome.usage.totalTokens,
|
|
967
|
-
madeProgress: outcome.madeProgress,
|
|
968
|
-
},
|
|
969
|
-
stopReason: {
|
|
970
|
-
kind: 'runtime_error',
|
|
971
|
-
message: 'Paused because provider usage was missing or incomplete across retry/fallback attempts; known usage was recorded, and budget accounting is incomplete.',
|
|
972
|
-
at: pausedAt,
|
|
973
|
-
},
|
|
974
|
-
};
|
|
975
|
-
this.state.continuationDeferred = true;
|
|
976
|
-
this.persist();
|
|
977
|
-
return;
|
|
978
|
-
}
|
|
979
|
-
const currentContract = g.contract ?? minimalContract(g.objective, g.updatedAt);
|
|
980
|
-
const pendingPlanRevision = outcome.pendingPlanUpdate
|
|
981
|
-
? this.addGoalInteger(currentContract.planSnapshot?.revision ?? 0, 1, 'contract.planSnapshot.revision')
|
|
982
|
-
: 0;
|
|
983
|
-
const pendingDerivedCriteria = outcome.pendingPlanUpdate
|
|
984
|
-
? newDerivedCriteria(currentContract, outcome.pendingPlanUpdate, pendingPlanRevision)
|
|
985
|
-
: [];
|
|
986
|
-
const pendingPlanChangesContent = outcome.pendingPlanUpdate
|
|
987
|
-
? planContentChanged(currentContract, outcome.pendingPlanUpdate)
|
|
988
|
-
: false;
|
|
989
|
-
const pendingPlanMutatesContract = Boolean(outcome.pendingPlanUpdate && (pendingPlanChangesContent || pendingDerivedCriteria.length > 0));
|
|
990
|
-
const newEvidence = (outcome.evidenceRecords ?? []).filter(record => record.goalId === g.goalId &&
|
|
991
|
-
record.goalRevision === g.revision &&
|
|
992
|
-
record.objectiveRevision === (g.contract?.objectiveRevision ?? 0) &&
|
|
993
|
-
record.turnId === outcome.turnId);
|
|
994
|
-
const planAdvanced = Boolean(outcome.pendingPlanUpdate &&
|
|
995
|
-
substantivePlanProgress(currentContract, outcome.pendingPlanUpdate, pendingDerivedCriteria));
|
|
996
|
-
const evidenceContract = pendingDerivedCriteria.length
|
|
997
|
-
? {
|
|
998
|
-
...currentContract,
|
|
999
|
-
successCriteria: [...currentContract.successCriteria, ...pendingDerivedCriteria],
|
|
1000
|
-
}
|
|
1001
|
-
: currentContract;
|
|
1002
|
-
const incomingEvidenceKeys = evidenceProgressKeys(newEvidence, evidenceContract);
|
|
1003
|
-
const recordedEvidenceKeys = new Set(g.progressEvidenceKeys ?? []);
|
|
1004
|
-
const evidenceAdvanced = incomingEvidenceKeys.some(key => !recordedEvidenceKeys.has(key));
|
|
1005
|
-
const hasAuditableProgressInputs = outcome.workspaceChanged !== undefined ||
|
|
1006
|
-
outcome.evidenceRecords !== undefined ||
|
|
1007
|
-
outcome.pendingPlanUpdate !== undefined;
|
|
1008
|
-
// Text-only plan churn is still persisted as a snapshot for observability,
|
|
1009
|
-
// but phase/next-action/description rewrites are not Goal progress. Runtime
|
|
1010
|
-
// turns must present an auditable signal; legacy direct callers without the
|
|
1011
|
-
// new metadata retain their explicit madeProgress value for compatibility.
|
|
1012
|
-
const madeAuditableProgress = Boolean(outcome.workspaceChanged) || evidenceAdvanced || planAdvanced;
|
|
1013
|
-
const accountingOutcome = {
|
|
1014
|
-
...outcome,
|
|
1015
|
-
madeProgress: hasAuditableProgressInputs ? madeAuditableProgress : outcome.madeProgress,
|
|
1016
|
-
};
|
|
1017
|
-
// Accumulate per-turn usage.
|
|
1018
|
-
const acc = (0, accounting_1.accumulateTurn)({
|
|
1019
|
-
tokensUsed: g.tokensUsed,
|
|
1020
|
-
timeUsedMs: g.timeUsedMs,
|
|
1021
|
-
continuationCount: g.continuationCount,
|
|
1022
|
-
noProgressCount: g.noProgressCount,
|
|
1023
|
-
}, accountingOutcome);
|
|
1024
|
-
const tokensUsed = this.addGoalInteger(acc.tokensUsed, 0, 'tokensUsed');
|
|
1025
|
-
const timeUsedMs = this.addGoalInteger(acc.timeUsedMs, 0, 'timeUsedMs');
|
|
1026
|
-
const continuationCount = this.addGoalInteger(acc.continuationCount, 0, 'continuationCount');
|
|
1027
|
-
const noProgressCount = this.addGoalInteger(acc.noProgressCount, 0, 'noProgressCount');
|
|
1028
|
-
const automaticContinuationStreak = outcome.inputKind === 'goal_continuation'
|
|
1029
|
-
? this.addGoalInteger(g.automaticContinuationStreak ?? 0, 1, 'automaticContinuationStreak')
|
|
1030
|
-
: 0;
|
|
1031
|
-
const updated = {
|
|
1032
|
-
...g,
|
|
1033
|
-
tokensUsed,
|
|
1034
|
-
timeUsedMs,
|
|
1035
|
-
continuationCount,
|
|
1036
|
-
automaticContinuationStreak,
|
|
1037
|
-
noProgressCount,
|
|
1038
|
-
recentNoProgressTurns: accountingOutcome.madeProgress
|
|
1039
|
-
? []
|
|
1040
|
-
: [...(g.recentNoProgressTurns ?? []), noProgressTurnSummary(accountingOutcome)].slice(-3),
|
|
1041
|
-
progressEvidenceKeys: [
|
|
1042
|
-
...(g.progressEvidenceKeys ?? []),
|
|
1043
|
-
...incomingEvidenceKeys.filter(key => !recordedEvidenceKeys.has(key)),
|
|
1044
|
-
].slice(-1000),
|
|
1045
|
-
revision: this.addGoalInteger(g.revision, 1, 'revision'),
|
|
1046
|
-
updatedAt: Date.now(),
|
|
1047
|
-
lastTurn: {
|
|
1048
|
-
turnId: outcome.turnId,
|
|
1049
|
-
finishReason: outcome.finishReason,
|
|
1050
|
-
endedAt: outcome.endedAt,
|
|
1051
|
-
promptTokens: outcome.usage.promptTokens,
|
|
1052
|
-
completionTokens: outcome.usage.completionTokens,
|
|
1053
|
-
subagentTokens: outcome.usage.subagentTokens,
|
|
1054
|
-
totalTokens: outcome.usage.totalTokens,
|
|
1055
|
-
madeProgress: accountingOutcome.madeProgress,
|
|
1056
|
-
},
|
|
1057
|
-
};
|
|
1058
|
-
if (outcome.pendingPlanUpdate && pendingPlanMutatesContract) {
|
|
1059
|
-
const contract = updated.contract ?? minimalContract(updated.objective, updated.updatedAt);
|
|
1060
|
-
updated.contract = {
|
|
1061
|
-
...contract,
|
|
1062
|
-
successCriteria: [...contract.successCriteria, ...pendingDerivedCriteria],
|
|
1063
|
-
planSnapshot: {
|
|
1064
|
-
revision: pendingPlanRevision,
|
|
1065
|
-
phase: outcome.pendingPlanUpdate.phase,
|
|
1066
|
-
steps: outcome.pendingPlanUpdate.steps.map((step, index) => ({
|
|
1067
|
-
id: `plan:${pendingPlanRevision}:${index + 1}`,
|
|
1068
|
-
description: step.description,
|
|
1069
|
-
done: step.done,
|
|
1070
|
-
})),
|
|
1071
|
-
nextAction: outcome.pendingPlanUpdate.nextAction,
|
|
1072
|
-
updatedAt: Date.now(),
|
|
1073
|
-
},
|
|
1074
|
-
};
|
|
1075
|
-
}
|
|
1076
|
-
const boundedEvidence = appendBoundedEvidence(g.evidenceLedger ?? [], newEvidence, currentContract.objectiveRevision, g.evidenceLedgerTruncation);
|
|
1077
|
-
const evidenceLedger = boundedEvidence.ledger;
|
|
1078
|
-
updated.evidenceLedger = evidenceLedger;
|
|
1079
|
-
updated.evidenceLedgerTruncation = boundedEvidence.truncation;
|
|
1080
|
-
// Process a terminal request only when it belongs to this exact turn and
|
|
1081
|
-
// goal revision. A stale tool call can never close a newer goal.
|
|
1082
|
-
const terminalRequest = outcome.pendingTerminalRequest;
|
|
1083
|
-
const currentBlockedSignal = Boolean(terminalRequest?.requestedStatus === 'blocked' &&
|
|
1084
|
-
terminalRequest.goalId === g.goalId &&
|
|
1085
|
-
terminalRequest.goalRevision === g.revision &&
|
|
1086
|
-
terminalRequest.turnId === outcome.turnId &&
|
|
1087
|
-
outcome.blocker &&
|
|
1088
|
-
updated.blocker?.fingerprint === outcome.blocker.fingerprint);
|
|
1089
|
-
// Consecutive means every Goal turn. Any intervening turn without the same
|
|
1090
|
-
// current-turn blocker breaks the streak instead of leaving an old counter
|
|
1091
|
-
// available for a later terminal request.
|
|
1092
|
-
if (updated.blocker && !currentBlockedSignal)
|
|
1093
|
-
updated.blocker = undefined;
|
|
1094
|
-
if (terminalRequest &&
|
|
1095
|
-
terminalRequest.goalId === g.goalId &&
|
|
1096
|
-
terminalRequest.goalRevision === g.revision &&
|
|
1097
|
-
terminalRequest.turnId === outcome.turnId) {
|
|
1098
|
-
if (terminalRequest.requestedStatus === 'complete') {
|
|
1099
|
-
if (updated.contract && terminalRequest.criterionEvidence) {
|
|
1100
|
-
const ledgerById = new Map(evidenceLedger.map(record => [record.id, record]));
|
|
1101
|
-
const criterionCounts = new Map();
|
|
1102
|
-
const evidenceCounts = new Map();
|
|
1103
|
-
for (const mapping of terminalRequest.criterionEvidence) {
|
|
1104
|
-
criterionCounts.set(mapping.criterionId, (criterionCounts.get(mapping.criterionId) ?? 0) + 1);
|
|
1105
|
-
for (const id of mapping.evidenceIds) {
|
|
1106
|
-
evidenceCounts.set(id, (evidenceCounts.get(id) ?? 0) + 1);
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
const mappings = new Map(terminalRequest.criterionEvidence.map(mapping => [
|
|
1110
|
-
mapping.criterionId,
|
|
1111
|
-
mapping.evidenceIds,
|
|
1112
|
-
]));
|
|
1113
|
-
updated.contract = {
|
|
1114
|
-
...updated.contract,
|
|
1115
|
-
successCriteria: updated.contract.successCriteria.map(criterion => {
|
|
1116
|
-
if (criterionCounts.get(criterion.id) !== 1)
|
|
1117
|
-
return criterion;
|
|
1118
|
-
const refs = (mappings.get(criterion.id) ?? []).filter(id => {
|
|
1119
|
-
const record = ledgerById.get(id);
|
|
1120
|
-
return Boolean(record &&
|
|
1121
|
-
evidenceCounts.get(id) === 1 &&
|
|
1122
|
-
record.goalId === g.goalId &&
|
|
1123
|
-
record.goalRevision <= g.revision &&
|
|
1124
|
-
record.objectiveRevision === (updated.contract?.objectiveRevision ?? 0) &&
|
|
1125
|
-
criterion.requiredEvidenceKinds.includes(record.kind));
|
|
1126
|
-
});
|
|
1127
|
-
return {
|
|
1128
|
-
...criterion,
|
|
1129
|
-
evidenceRefs: [...new Set([...criterion.evidenceRefs, ...refs])],
|
|
1130
|
-
};
|
|
1131
|
-
}),
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
|
-
const audit = (0, completion_audit_1.auditCompletion)({
|
|
1135
|
-
objective: updated.objective,
|
|
1136
|
-
contract: updated.contract ?? minimalContract(updated.objective, updated.updatedAt),
|
|
1137
|
-
evidenceLedger,
|
|
1138
|
-
evidenceLedgerTruncation: updated.evidenceLedgerTruncation,
|
|
1139
|
-
goalId: g.goalId,
|
|
1140
|
-
goalRevision: g.revision,
|
|
1141
|
-
requestedAt: terminalRequest.requestedAt,
|
|
1142
|
-
verificationSummary: outcome.verificationSummary ?? outcome.finishReason,
|
|
1143
|
-
workspaceFingerprint: outcome.workspaceFingerprint,
|
|
1144
|
-
});
|
|
1145
|
-
updated.completionAudit = audit;
|
|
1146
|
-
if (updated.contract) {
|
|
1147
|
-
const statusById = new Map(audit.criterionResults?.map(result => [result.criterionId, result.status]) ?? []);
|
|
1148
|
-
updated.contract = {
|
|
1149
|
-
...updated.contract,
|
|
1150
|
-
successCriteria: updated.contract.successCriteria.map(criterion => ({
|
|
1151
|
-
...criterion,
|
|
1152
|
-
status: statusById.get(criterion.id) ?? 'pending',
|
|
1153
|
-
})),
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
if (audit.passed) {
|
|
1157
|
-
const completedAt = Date.now();
|
|
1158
|
-
const criterionResults = audit.criterionResults ?? [];
|
|
1159
|
-
const finalLedgerById = new Map(evidenceLedger.map(record => [record.id, record]));
|
|
1160
|
-
updated.completionAudit = {
|
|
1161
|
-
...audit,
|
|
1162
|
-
finalSummary: {
|
|
1163
|
-
originalObjective: updated.contract?.originalObjective ?? updated.objective,
|
|
1164
|
-
currentObjective: updated.objective,
|
|
1165
|
-
objectiveRevision: updated.contract?.objectiveRevision ?? 0,
|
|
1166
|
-
completedAt,
|
|
1167
|
-
verificationSummary: audit.verificationSummary,
|
|
1168
|
-
criterionResults: criterionResults.map(result => ({
|
|
1169
|
-
criterionId: result.criterionId,
|
|
1170
|
-
status: result.status,
|
|
1171
|
-
evidenceRefs: result.evidenceRefs,
|
|
1172
|
-
evidence: result.evidenceRefs.flatMap(id => {
|
|
1173
|
-
const record = finalLedgerById.get(id);
|
|
1174
|
-
return record ? [finalEvidenceReceipt(record)] : [];
|
|
1175
|
-
}),
|
|
1176
|
-
})),
|
|
1177
|
-
evidenceRefs: audit.evidenceRefs,
|
|
1178
|
-
accounting: {
|
|
1179
|
-
tokensUsed: updated.tokensUsed,
|
|
1180
|
-
timeUsedMs: updated.timeUsedMs,
|
|
1181
|
-
continuationCount: updated.continuationCount,
|
|
1182
|
-
usageComplete: true,
|
|
1183
|
-
},
|
|
1184
|
-
remainingRequirements: [],
|
|
1185
|
-
stopReason: 'completed',
|
|
1186
|
-
},
|
|
1187
|
-
};
|
|
1188
|
-
updated.status = 'complete';
|
|
1189
|
-
updated.completedAt = completedAt;
|
|
1190
|
-
delete updated.activeSince;
|
|
1191
|
-
delete updated.blocker;
|
|
1192
|
-
delete updated.stopReason;
|
|
1193
|
-
if (updated.contract) {
|
|
1194
|
-
const currentPlan = updated.contract.planSnapshot;
|
|
1195
|
-
updated.contract = {
|
|
1196
|
-
...updated.contract,
|
|
1197
|
-
planSnapshot: {
|
|
1198
|
-
revision: this.addGoalInteger(currentPlan?.revision ?? 0, 1, 'contract.planSnapshot.revision'),
|
|
1199
|
-
phase: 'complete',
|
|
1200
|
-
steps: currentPlan?.steps ?? [],
|
|
1201
|
-
nextAction: undefined,
|
|
1202
|
-
updatedAt: completedAt,
|
|
1203
|
-
},
|
|
1204
|
-
};
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
else if (updated.contract) {
|
|
1208
|
-
const currentPlan = updated.contract.planSnapshot;
|
|
1209
|
-
updated.contract = {
|
|
1210
|
-
...updated.contract,
|
|
1211
|
-
planSnapshot: {
|
|
1212
|
-
revision: this.addGoalInteger(currentPlan?.revision ?? 0, 1, 'contract.planSnapshot.revision'),
|
|
1213
|
-
phase: 'verification',
|
|
1214
|
-
steps: currentPlan?.steps ?? [],
|
|
1215
|
-
nextAction: audit.remainingRequirements[0],
|
|
1216
|
-
updatedAt: Date.now(),
|
|
1217
|
-
},
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
else if (terminalRequest.requestedStatus === 'blocked') {
|
|
1222
|
-
const blocker = outcome.blocker;
|
|
1223
|
-
if (blocker) {
|
|
1224
|
-
const fingerprint = blocker.fingerprint;
|
|
1225
|
-
const same = (0, completion_audit_1.blockersMatch)(updated.blocker, fingerprint);
|
|
1226
|
-
const newBlocker = {
|
|
1227
|
-
category: blocker.category,
|
|
1228
|
-
fingerprint,
|
|
1229
|
-
firstSeenAt: same && updated.blocker ? updated.blocker.firstSeenAt : Date.now(),
|
|
1230
|
-
lastSeenAt: Date.now(),
|
|
1231
|
-
consecutiveTurns: same
|
|
1232
|
-
? this.addGoalInteger(updated.blocker?.consecutiveTurns ?? 0, 1, 'blocker.consecutiveTurns')
|
|
1233
|
-
: 1,
|
|
1234
|
-
summary: blocker.summary,
|
|
1235
|
-
retryable: false,
|
|
1236
|
-
};
|
|
1237
|
-
updated.blocker = newBlocker;
|
|
1238
|
-
const blockAudit = (0, completion_audit_1.auditBlocked)({
|
|
1239
|
-
blocker: newBlocker,
|
|
1240
|
-
noProgressCount: updated.noProgressCount,
|
|
1241
|
-
});
|
|
1242
|
-
if (blockAudit.allowed) {
|
|
1243
|
-
updated.status = 'blocked';
|
|
1244
|
-
updated.stopReason = { kind: 'blocked', message: blockAudit.reason, at: Date.now() };
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
if (updated.lastTurn &&
|
|
1250
|
-
!updated.lastTurn.madeProgress &&
|
|
1251
|
-
criterionStateAdvanced(currentContract, updated.contract, evidenceLedger)) {
|
|
1252
|
-
updated.noProgressCount = 0;
|
|
1253
|
-
updated.recentNoProgressTurns = [];
|
|
1254
|
-
updated.lastTurn = { ...updated.lastTurn, madeProgress: true };
|
|
1255
|
-
}
|
|
1256
|
-
const providerStop = (0, accounting_1.classifyStopReason)(outcome.providerError);
|
|
1257
|
-
if (providerStop && updated.status === 'active') {
|
|
1258
|
-
updated.status = providerStop.kind === 'usage_limit' ? 'usage_limited' : 'paused';
|
|
1259
|
-
updated.stopReason = {
|
|
1260
|
-
kind: providerStop.kind,
|
|
1261
|
-
message: providerStop.message,
|
|
1262
|
-
at: Date.now(),
|
|
1263
|
-
};
|
|
1264
|
-
this.state.continuationDeferred = true;
|
|
1265
|
-
}
|
|
1266
|
-
const recentBlockedContinuations = (updated.recentNoProgressTurns ?? []).slice(-types_1.GOAL_INVARIANTS.maxConsecutiveBlockedContinuationTurns);
|
|
1267
|
-
if (outcome.inputKind === 'goal_continuation' &&
|
|
1268
|
-
(updated.automaticContinuationStreak ?? 0) >=
|
|
1269
|
-
types_1.GOAL_INVARIANTS.maxConsecutiveBlockedContinuationTurns &&
|
|
1270
|
-
recentBlockedContinuations.length ===
|
|
1271
|
-
types_1.GOAL_INVARIANTS.maxConsecutiveBlockedContinuationTurns &&
|
|
1272
|
-
recentBlockedContinuations.every(turn => turn.finishReason === 'blocked') &&
|
|
1273
|
-
updated.status === 'active') {
|
|
1274
|
-
updated.status = 'paused';
|
|
1275
|
-
updated.stopReason = {
|
|
1276
|
-
kind: 'user',
|
|
1277
|
-
message: `Auto-paused after ${types_1.GOAL_INVARIANTS.maxConsecutiveBlockedContinuationTurns} blocked autonomous continuations. Inspect the unmet completion gate or external blocker, then use /goal resume to continue or /goal exit to abandon.`,
|
|
1278
|
-
at: Date.now(),
|
|
1279
|
-
};
|
|
1280
|
-
this.state.continuationDeferred = true;
|
|
1281
|
-
}
|
|
1282
|
-
// Auto-pause on no-progress threshold.
|
|
1283
|
-
if (updated.noProgressCount >= types_1.GOAL_INVARIANTS.maxConsecutiveNoProgressTurns &&
|
|
1284
|
-
updated.status === 'active') {
|
|
1285
|
-
updated.status = 'paused';
|
|
1286
|
-
const recent = updated.recentNoProgressTurns ?? [];
|
|
1287
|
-
updated.stopReason = {
|
|
1288
|
-
kind: 'user',
|
|
1289
|
-
message: `Auto-paused: no progress for ${types_1.GOAL_INVARIANTS.maxConsecutiveNoProgressTurns} consecutive turns. Recent turns: ${formatNoProgressTurns(recent)}.`,
|
|
1290
|
-
at: Date.now(),
|
|
1291
|
-
};
|
|
1292
|
-
this.state.continuationDeferred = true;
|
|
1293
|
-
}
|
|
1294
|
-
// Budget limit.
|
|
1295
|
-
if ((0, accounting_1.isBudgetExceeded)(updated.tokensUsed, updated.tokenBudget) && updated.status === 'active') {
|
|
1296
|
-
updated.status = 'budget_limited';
|
|
1297
|
-
updated.stopReason = {
|
|
1298
|
-
kind: 'budget_limit',
|
|
1299
|
-
message: `Token budget reached: ${updated.tokensUsed}/${updated.tokenBudget}`,
|
|
1300
|
-
at: Date.now(),
|
|
1301
|
-
};
|
|
1302
|
-
}
|
|
1303
|
-
this.state.goal = updated;
|
|
1304
|
-
this.persist();
|
|
1305
|
-
}
|
|
1306
|
-
/**
|
|
1307
|
-
* Account an interrupted turn whose request revision was superseded by live steering.
|
|
1308
|
-
*
|
|
1309
|
-
* This deliberately ignores every semantic payload on the stale outcome: evidence,
|
|
1310
|
-
* plan updates, blockers, and terminal requests belong to the old contract revision.
|
|
1311
|
-
* Only already-incurred token/time/turn accounting is retained, without changing the
|
|
1312
|
-
* revised Goal's no-progress streak.
|
|
1313
|
-
*/
|
|
1314
|
-
accountStaleTurn(outcome) {
|
|
1315
|
-
const g = this.state.goal;
|
|
1316
|
-
if (!g ||
|
|
1317
|
-
outcome.sessionId !== this.sessionId ||
|
|
1318
|
-
outcome.goalId !== g.goalId ||
|
|
1319
|
-
outcome.goalRevision === undefined ||
|
|
1320
|
-
outcome.goalRevision >= g.revision ||
|
|
1321
|
-
(outcome.goalGeneration !== undefined && outcome.goalGeneration !== this.state.generation)) {
|
|
1322
|
-
return false;
|
|
1323
|
-
}
|
|
1324
|
-
const key = `${outcome.goalId}:${outcome.goalGeneration ?? this.state.generation}:${outcome.turnId}`;
|
|
1325
|
-
if (this.accountedStaleTurnKeys.has(key))
|
|
1326
|
-
return false;
|
|
1327
|
-
const endedAt = Math.max(outcome.startedAt, outcome.endedAt);
|
|
1328
|
-
const elapsedMs = endedAt - outcome.startedAt;
|
|
1329
|
-
const tokensUsed = this.addGoalInteger(g.tokensUsed, Math.max(0, outcome.usage.totalTokens), 'tokensUsed');
|
|
1330
|
-
const timeUsedMs = this.addGoalInteger(g.timeUsedMs, elapsedMs, 'timeUsedMs');
|
|
1331
|
-
const continuationCount = this.addGoalInteger(g.continuationCount, 1, 'continuationCount');
|
|
1332
|
-
const revision = this.addGoalInteger(g.revision, 1, 'revision');
|
|
1333
|
-
this.accountedStaleTurnKeys.add(key);
|
|
1334
|
-
const updated = {
|
|
1335
|
-
...g,
|
|
1336
|
-
tokensUsed,
|
|
1337
|
-
timeUsedMs,
|
|
1338
|
-
continuationCount,
|
|
1339
|
-
automaticContinuationStreak: 0,
|
|
1340
|
-
revision,
|
|
1341
|
-
updatedAt: Date.now(),
|
|
1342
|
-
lastTurn: {
|
|
1343
|
-
turnId: outcome.turnId,
|
|
1344
|
-
finishReason: outcome.finishReason,
|
|
1345
|
-
endedAt,
|
|
1346
|
-
promptTokens: Math.max(0, outcome.usage.promptTokens),
|
|
1347
|
-
completionTokens: Math.max(0, outcome.usage.completionTokens),
|
|
1348
|
-
subagentTokens: Math.max(0, outcome.usage.subagentTokens),
|
|
1349
|
-
totalTokens: Math.max(0, outcome.usage.totalTokens),
|
|
1350
|
-
madeProgress: false,
|
|
1351
|
-
},
|
|
1352
|
-
};
|
|
1353
|
-
if ((0, accounting_1.isBudgetExceeded)(updated.tokensUsed, updated.tokenBudget) && updated.status === 'active') {
|
|
1354
|
-
updated.status = 'budget_limited';
|
|
1355
|
-
updated.stopReason = {
|
|
1356
|
-
kind: 'budget_limit',
|
|
1357
|
-
message: `Token budget reached: ${updated.tokensUsed}/${updated.tokenBudget}`,
|
|
1358
|
-
at: Date.now(),
|
|
1359
|
-
};
|
|
1360
|
-
this.state.continuationDeferred = true;
|
|
1361
|
-
}
|
|
1362
|
-
this.state.goal = updated;
|
|
1363
|
-
try {
|
|
1364
|
-
this.persist();
|
|
1365
|
-
}
|
|
1366
|
-
catch (error) {
|
|
1367
|
-
// The key protects an in-flight attempt, but a failed pre-commit save did
|
|
1368
|
-
// not durably account the turn. Release it only after persist() restores
|
|
1369
|
-
// disk authority so the same outcome can be retried exactly once.
|
|
1370
|
-
this.accountedStaleTurnKeys.delete(key);
|
|
1371
|
-
throw error;
|
|
1372
|
-
}
|
|
1373
|
-
return true;
|
|
1374
|
-
}
|
|
1375
|
-
deferContinuation() {
|
|
1376
|
-
if (!this.state.goal || this.state.goal.status !== 'active')
|
|
1377
|
-
return;
|
|
1378
|
-
this.state.continuationDeferred = true;
|
|
1379
|
-
const g = this.state.goal;
|
|
1380
|
-
this.state.goal = {
|
|
1381
|
-
...g,
|
|
1382
|
-
status: 'paused',
|
|
1383
|
-
revision: this.addGoalInteger(g.revision, 1, 'revision'),
|
|
1384
|
-
updatedAt: Date.now(),
|
|
1385
|
-
stopReason: { kind: 'user', message: 'Paused by interrupt.', at: Date.now() },
|
|
1386
|
-
};
|
|
1387
|
-
this.persist();
|
|
1388
|
-
}
|
|
1389
|
-
limitBudget(reason) {
|
|
1390
|
-
const goal = this.state.goal;
|
|
1391
|
-
if (!goal || goal.status !== 'active')
|
|
1392
|
-
return;
|
|
1393
|
-
this.state.goal = {
|
|
1394
|
-
...goal,
|
|
1395
|
-
status: 'budget_limited',
|
|
1396
|
-
revision: this.addGoalInteger(goal.revision, 1, 'revision'),
|
|
1397
|
-
updatedAt: Date.now(),
|
|
1398
|
-
stopReason: { kind: 'budget_limit', message: reason, at: Date.now() },
|
|
1399
|
-
};
|
|
1400
|
-
this.state.continuationDeferred = true;
|
|
1401
|
-
this.persist();
|
|
1402
|
-
}
|
|
1403
|
-
/**
|
|
1404
|
-
* Apply a runtime-only safety overlay after a mutation failed to persist.
|
|
1405
|
-
* `persist()` has already restored the disk-authoritative Goal. Keep its
|
|
1406
|
-
* revision intact so `/target resume` can save normally once storage recovers,
|
|
1407
|
-
* while invalidating every in-flight request and queued continuation now.
|
|
1408
|
-
*/
|
|
1409
|
-
failClosedAfterPersistenceError(reason) {
|
|
1410
|
-
const goal = this.state.goal;
|
|
1411
|
-
this.state.generation += 1;
|
|
1412
|
-
this.state.continuationDeferred = true;
|
|
1413
|
-
if (!goal || goal.status === 'complete')
|
|
1414
|
-
return;
|
|
1415
|
-
this.state.goal = {
|
|
1416
|
-
...goal,
|
|
1417
|
-
status: 'paused',
|
|
1418
|
-
updatedAt: Date.now(),
|
|
1419
|
-
stopReason: {
|
|
1420
|
-
kind: 'runtime_error',
|
|
1421
|
-
message: (0, redaction_1.redactTraceText)(reason).slice(0, 600),
|
|
1422
|
-
at: Date.now(),
|
|
1423
|
-
},
|
|
1424
|
-
};
|
|
1425
|
-
}
|
|
1426
|
-
// ==========================================================================
|
|
1427
|
-
// Persistence
|
|
1428
|
-
// ==========================================================================
|
|
1429
|
-
/** Restore disk authority without reviving a deletion-fenced Goal. */
|
|
1430
|
-
restoreDiskAuthorityAfterMutationFailure() {
|
|
1431
|
-
const persisted = (0, goal_storage_1.loadGoal)(this.projectPath, this.sessionId);
|
|
1432
|
-
if (persisted.ok) {
|
|
1433
|
-
this.loadRecoveryRequired = false;
|
|
1434
|
-
this.state.goal = ensureContract(persisted.value);
|
|
1435
|
-
this.persistedGoalSnapshot = structuredClone(this.state.goal);
|
|
1436
|
-
this.state.continuationDeferred = true;
|
|
1437
|
-
return;
|
|
1438
|
-
}
|
|
1439
|
-
if (persisted.error === 'not_found') {
|
|
1440
|
-
this.loadRecoveryRequired = false;
|
|
1441
|
-
this.state.goal = null;
|
|
1442
|
-
this.persistedGoalSnapshot = null;
|
|
1443
|
-
this.state.generation += 1;
|
|
1444
|
-
this.state.continuationDeferred = false;
|
|
1445
|
-
return;
|
|
1446
|
-
}
|
|
1447
|
-
if (this.persistedGoalSnapshot) {
|
|
1448
|
-
this.state.goal = structuredClone(this.persistedGoalSnapshot);
|
|
1449
|
-
}
|
|
1450
|
-
else {
|
|
1451
|
-
this.state.goal = null;
|
|
1452
|
-
}
|
|
1453
|
-
this.loadRecoveryRequired = true;
|
|
1454
|
-
this.state.continuationDeferred = true;
|
|
1455
|
-
}
|
|
1456
|
-
persist() {
|
|
1457
|
-
if (!this.state.goal)
|
|
1458
|
-
return;
|
|
1459
|
-
const result = (0, goal_storage_1.saveGoal)(this.projectPath, this.sessionId, this.state.goal, Math.max(0, this.state.goal.revision - 1));
|
|
1460
|
-
if (result.ok) {
|
|
1461
|
-
this.persistedGoalSnapshot = structuredClone(this.state.goal);
|
|
1462
|
-
return;
|
|
1463
|
-
}
|
|
1464
|
-
if (!result.ok) {
|
|
1465
|
-
this.restoreDiskAuthorityAfterMutationFailure();
|
|
1466
|
-
throw new Error(`Goal persistence failed (${result.error}): ${result.message}`);
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
exports.GoalCoordinator = GoalCoordinator;
|
|
1471
|
-
//# sourceMappingURL=coordinator.js.map
|