@sema-ai/core 1.275.1
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 +5433 -0
- package/LICENSE +27 -0
- package/NOTICE.md +30 -0
- package/README.md +1040 -0
- package/dist/agents/agent-definition.d.ts +10 -0
- package/dist/agents/agent-definition.d.ts.map +1 -0
- package/dist/agents/agent-definition.js +18 -0
- package/dist/agents/agent-definition.js.map +1 -0
- package/dist/agents/builtin-agents.d.ts +69 -0
- package/dist/agents/builtin-agents.d.ts.map +1 -0
- package/dist/agents/builtin-agents.js +177 -0
- package/dist/agents/builtin-agents.js.map +1 -0
- package/dist/agents/cascade.d.ts +101 -0
- package/dist/agents/cascade.d.ts.map +1 -0
- package/dist/agents/cascade.js +189 -0
- package/dist/agents/cascade.js.map +1 -0
- package/dist/agents/observer.d.ts +209 -0
- package/dist/agents/observer.d.ts.map +1 -0
- package/dist/agents/observer.js +495 -0
- package/dist/agents/observer.js.map +1 -0
- package/dist/agents/repair-loop.d.ts +236 -0
- package/dist/agents/repair-loop.d.ts.map +1 -0
- package/dist/agents/repair-loop.js +293 -0
- package/dist/agents/repair-loop.js.map +1 -0
- package/dist/agents/session-util.d.ts +8 -0
- package/dist/agents/session-util.d.ts.map +1 -0
- package/dist/agents/session-util.js +9 -0
- package/dist/agents/session-util.js.map +1 -0
- package/dist/agents/subagent-steps.d.ts +93 -0
- package/dist/agents/subagent-steps.d.ts.map +1 -0
- package/dist/agents/subagent-steps.js +206 -0
- package/dist/agents/subagent-steps.js.map +1 -0
- package/dist/agents/subagent.d.ts +441 -0
- package/dist/agents/subagent.d.ts.map +1 -0
- package/dist/agents/subagent.js +2492 -0
- package/dist/agents/subagent.js.map +1 -0
- package/dist/agents/suspend-guard.d.ts +35 -0
- package/dist/agents/suspend-guard.d.ts.map +1 -0
- package/dist/agents/suspend-guard.js +48 -0
- package/dist/agents/suspend-guard.js.map +1 -0
- package/dist/agents/teacher.d.ts +137 -0
- package/dist/agents/teacher.d.ts.map +1 -0
- package/dist/agents/teacher.js +575 -0
- package/dist/agents/teacher.js.map +1 -0
- package/dist/agents/team.d.ts +211 -0
- package/dist/agents/team.d.ts.map +1 -0
- package/dist/agents/team.js +293 -0
- package/dist/agents/team.js.map +1 -0
- package/dist/agents/tool-filter.d.ts +29 -0
- package/dist/agents/tool-filter.d.ts.map +1 -0
- package/dist/agents/tool-filter.js +50 -0
- package/dist/agents/tool-filter.js.map +1 -0
- package/dist/agents/verify.d.ts +177 -0
- package/dist/agents/verify.d.ts.map +1 -0
- package/dist/agents/verify.js +305 -0
- package/dist/agents/verify.js.map +1 -0
- package/dist/bench/metrics.d.ts +714 -0
- package/dist/bench/metrics.d.ts.map +1 -0
- package/dist/bench/metrics.js +618 -0
- package/dist/bench/metrics.js.map +1 -0
- package/dist/bin/sema-tb.d.ts +3 -0
- package/dist/bin/sema-tb.d.ts.map +1 -0
- package/dist/bin/sema-tb.js +516 -0
- package/dist/bin/sema-tb.js.map +1 -0
- package/dist/bin/tb-env.d.ts +13 -0
- package/dist/bin/tb-env.d.ts.map +1 -0
- package/dist/bin/tb-env.js +26 -0
- package/dist/bin/tb-env.js.map +1 -0
- package/dist/brain/anthropic.d.ts +46 -0
- package/dist/brain/anthropic.d.ts.map +1 -0
- package/dist/brain/anthropic.js +830 -0
- package/dist/brain/anthropic.js.map +1 -0
- package/dist/brain/circuit-breaker.d.ts +46 -0
- package/dist/brain/circuit-breaker.d.ts.map +1 -0
- package/dist/brain/circuit-breaker.js +173 -0
- package/dist/brain/circuit-breaker.js.map +1 -0
- package/dist/brain/degrading.d.ts +98 -0
- package/dist/brain/degrading.d.ts.map +1 -0
- package/dist/brain/degrading.js +249 -0
- package/dist/brain/degrading.js.map +1 -0
- package/dist/brain/errors.d.ts +31 -0
- package/dist/brain/errors.d.ts.map +1 -0
- package/dist/brain/errors.js +58 -0
- package/dist/brain/errors.js.map +1 -0
- package/dist/brain/failover.d.ts +18 -0
- package/dist/brain/failover.d.ts.map +1 -0
- package/dist/brain/failover.js +118 -0
- package/dist/brain/failover.js.map +1 -0
- package/dist/brain/model-presets.d.ts +36 -0
- package/dist/brain/model-presets.d.ts.map +1 -0
- package/dist/brain/model-presets.js +54 -0
- package/dist/brain/model-presets.js.map +1 -0
- package/dist/brain/openai.d.ts +43 -0
- package/dist/brain/openai.d.ts.map +1 -0
- package/dist/brain/openai.js +784 -0
- package/dist/brain/openai.js.map +1 -0
- package/dist/brain/reasoning.d.ts +138 -0
- package/dist/brain/reasoning.d.ts.map +1 -0
- package/dist/brain/reasoning.js +146 -0
- package/dist/brain/reasoning.js.map +1 -0
- package/dist/brain/repetition.d.ts +60 -0
- package/dist/brain/repetition.d.ts.map +1 -0
- package/dist/brain/repetition.js +121 -0
- package/dist/brain/repetition.js.map +1 -0
- package/dist/brain/request-params.d.ts +29 -0
- package/dist/brain/request-params.d.ts.map +1 -0
- package/dist/brain/request-params.js +78 -0
- package/dist/brain/request-params.js.map +1 -0
- package/dist/brain/retry.d.ts +18 -0
- package/dist/brain/retry.d.ts.map +1 -0
- package/dist/brain/retry.js +42 -0
- package/dist/brain/retry.js.map +1 -0
- package/dist/brain/routing.d.ts +19 -0
- package/dist/brain/routing.d.ts.map +1 -0
- package/dist/brain/routing.js +44 -0
- package/dist/brain/routing.js.map +1 -0
- package/dist/brain/status-sink.d.ts +46 -0
- package/dist/brain/status-sink.d.ts.map +1 -0
- package/dist/brain/status-sink.js +36 -0
- package/dist/brain/status-sink.js.map +1 -0
- package/dist/brain/stream-engine.d.ts +85 -0
- package/dist/brain/stream-engine.d.ts.map +1 -0
- package/dist/brain/stream-engine.js +391 -0
- package/dist/brain/stream-engine.js.map +1 -0
- package/dist/brain/timeout.d.ts +44 -0
- package/dist/brain/timeout.d.ts.map +1 -0
- package/dist/brain/timeout.js +41 -0
- package/dist/brain/timeout.js.map +1 -0
- package/dist/brain/tool-call-repair.d.ts +15 -0
- package/dist/brain/tool-call-repair.d.ts.map +1 -0
- package/dist/brain/tool-call-repair.js +67 -0
- package/dist/brain/tool-call-repair.js.map +1 -0
- package/dist/brain/walltime.d.ts +14 -0
- package/dist/brain/walltime.d.ts.map +1 -0
- package/dist/brain/walltime.js +14 -0
- package/dist/brain/walltime.js.map +1 -0
- package/dist/core/arg-summary.d.ts +19 -0
- package/dist/core/arg-summary.d.ts.map +1 -0
- package/dist/core/arg-summary.js +96 -0
- package/dist/core/arg-summary.js.map +1 -0
- package/dist/core/ask-question.d.ts +113 -0
- package/dist/core/ask-question.d.ts.map +1 -0
- package/dist/core/ask-question.js +246 -0
- package/dist/core/ask-question.js.map +1 -0
- package/dist/core/auto-compaction.d.ts +341 -0
- package/dist/core/auto-compaction.d.ts.map +1 -0
- package/dist/core/auto-compaction.js +495 -0
- package/dist/core/auto-compaction.js.map +1 -0
- package/dist/core/auto-promote.d.ts +126 -0
- package/dist/core/auto-promote.d.ts.map +1 -0
- package/dist/core/auto-promote.js +171 -0
- package/dist/core/auto-promote.js.map +1 -0
- package/dist/core/background-shell.d.ts +128 -0
- package/dist/core/background-shell.d.ts.map +1 -0
- package/dist/core/background-shell.js +42 -0
- package/dist/core/background-shell.js.map +1 -0
- package/dist/core/cache-break-detector.d.ts +63 -0
- package/dist/core/cache-break-detector.d.ts.map +1 -0
- package/dist/core/cache-break-detector.js +0 -0
- package/dist/core/cache-break-detector.js.map +1 -0
- package/dist/core/canonical-json.d.ts +45 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +132 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/checkpoint-store.d.ts +1101 -0
- package/dist/core/checkpoint-store.d.ts.map +1 -0
- package/dist/core/checkpoint-store.js +514 -0
- package/dist/core/checkpoint-store.js.map +1 -0
- package/dist/core/consolidate-scope.d.ts +94 -0
- package/dist/core/consolidate-scope.d.ts.map +1 -0
- package/dist/core/consolidate-scope.js +158 -0
- package/dist/core/consolidate-scope.js.map +1 -0
- package/dist/core/context-edit.d.ts +82 -0
- package/dist/core/context-edit.d.ts.map +1 -0
- package/dist/core/context-edit.js +149 -0
- package/dist/core/context-edit.js.map +1 -0
- package/dist/core/context-guard.d.ts +43 -0
- package/dist/core/context-guard.d.ts.map +1 -0
- package/dist/core/context-guard.js +171 -0
- package/dist/core/context-guard.js.map +1 -0
- package/dist/core/dynamic-recall.d.ts +100 -0
- package/dist/core/dynamic-recall.d.ts.map +1 -0
- package/dist/core/dynamic-recall.js +108 -0
- package/dist/core/dynamic-recall.js.map +1 -0
- package/dist/core/exec-gate.d.ts +74 -0
- package/dist/core/exec-gate.d.ts.map +1 -0
- package/dist/core/exec-gate.js +143 -0
- package/dist/core/exec-gate.js.map +1 -0
- package/dist/core/exec-output-tail.d.ts +37 -0
- package/dist/core/exec-output-tail.d.ts.map +1 -0
- package/dist/core/exec-output-tail.js +63 -0
- package/dist/core/exec-output-tail.js.map +1 -0
- package/dist/core/file-snapshot-store.d.ts +137 -0
- package/dist/core/file-snapshot-store.d.ts.map +1 -0
- package/dist/core/file-snapshot-store.js +319 -0
- package/dist/core/file-snapshot-store.js.map +1 -0
- package/dist/core/git-worktree-env.d.ts +41 -0
- package/dist/core/git-worktree-env.d.ts.map +1 -0
- package/dist/core/git-worktree-env.js +64 -0
- package/dist/core/git-worktree-env.js.map +1 -0
- package/dist/core/hooks.d.ts +372 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +269 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/lsp-diagnostics.d.ts +74 -0
- package/dist/core/lsp-diagnostics.d.ts.map +1 -0
- package/dist/core/lsp-diagnostics.js +125 -0
- package/dist/core/lsp-diagnostics.js.map +1 -0
- package/dist/core/lsp-protocol.d.ts +28 -0
- package/dist/core/lsp-protocol.d.ts.map +1 -0
- package/dist/core/lsp-protocol.js +179 -0
- package/dist/core/lsp-protocol.js.map +1 -0
- package/dist/core/lsp-session.d.ts +56 -0
- package/dist/core/lsp-session.d.ts.map +1 -0
- package/dist/core/lsp-session.js +185 -0
- package/dist/core/lsp-session.js.map +1 -0
- package/dist/core/lsp.d.ts +132 -0
- package/dist/core/lsp.d.ts.map +1 -0
- package/dist/core/lsp.js +147 -0
- package/dist/core/lsp.js.map +1 -0
- package/dist/core/mcp.d.ts +294 -0
- package/dist/core/mcp.d.ts.map +1 -0
- package/dist/core/mcp.js +992 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/media-byte-cap.d.ts +34 -0
- package/dist/core/media-byte-cap.d.ts.map +1 -0
- package/dist/core/media-byte-cap.js +76 -0
- package/dist/core/media-byte-cap.js.map +1 -0
- package/dist/core/memory-engine/data-plane.d.ts +103 -0
- package/dist/core/memory-engine/data-plane.d.ts.map +1 -0
- package/dist/core/memory-engine/data-plane.js +272 -0
- package/dist/core/memory-engine/data-plane.js.map +1 -0
- package/dist/core/memory-engine/dual-root.d.ts +40 -0
- package/dist/core/memory-engine/dual-root.d.ts.map +1 -0
- package/dist/core/memory-engine/dual-root.js +95 -0
- package/dist/core/memory-engine/dual-root.js.map +1 -0
- package/dist/core/memory-engine/engine.d.ts +161 -0
- package/dist/core/memory-engine/engine.d.ts.map +1 -0
- package/dist/core/memory-engine/engine.js +1110 -0
- package/dist/core/memory-engine/engine.js.map +1 -0
- package/dist/core/memory-engine/file-backend.d.ts +162 -0
- package/dist/core/memory-engine/file-backend.d.ts.map +1 -0
- package/dist/core/memory-engine/file-backend.js +948 -0
- package/dist/core/memory-engine/file-backend.js.map +1 -0
- package/dist/core/memory-engine/frontmatter.d.ts +24 -0
- package/dist/core/memory-engine/frontmatter.d.ts.map +1 -0
- package/dist/core/memory-engine/frontmatter.js +135 -0
- package/dist/core/memory-engine/frontmatter.js.map +1 -0
- package/dist/core/memory-engine/index.d.ts +13 -0
- package/dist/core/memory-engine/index.d.ts.map +1 -0
- package/dist/core/memory-engine/index.js +28 -0
- package/dist/core/memory-engine/index.js.map +1 -0
- package/dist/core/memory-engine/layout.d.ts +123 -0
- package/dist/core/memory-engine/layout.d.ts.map +1 -0
- package/dist/core/memory-engine/layout.js +643 -0
- package/dist/core/memory-engine/layout.js.map +1 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts +22 -0
- package/dist/core/memory-engine/memory-backend-contract.d.ts.map +1 -0
- package/dist/core/memory-engine/memory-backend-contract.js +271 -0
- package/dist/core/memory-engine/memory-backend-contract.js.map +1 -0
- package/dist/core/memory-engine/migrate.d.ts +17 -0
- package/dist/core/memory-engine/migrate.d.ts.map +1 -0
- package/dist/core/memory-engine/migrate.js +35 -0
- package/dist/core/memory-engine/migrate.js.map +1 -0
- package/dist/core/memory-engine/scan.d.ts +20 -0
- package/dist/core/memory-engine/scan.d.ts.map +1 -0
- package/dist/core/memory-engine/scan.js +84 -0
- package/dist/core/memory-engine/scan.js.map +1 -0
- package/dist/core/memory-engine/scope-contract.d.ts +104 -0
- package/dist/core/memory-engine/scope-contract.d.ts.map +1 -0
- package/dist/core/memory-engine/scope-contract.js +288 -0
- package/dist/core/memory-engine/scope-contract.js.map +1 -0
- package/dist/core/memory-engine/sync-client.d.ts +100 -0
- package/dist/core/memory-engine/sync-client.d.ts.map +1 -0
- package/dist/core/memory-engine/sync-client.js +328 -0
- package/dist/core/memory-engine/sync-client.js.map +1 -0
- package/dist/core/memory-engine/sync.d.ts +97 -0
- package/dist/core/memory-engine/sync.d.ts.map +1 -0
- package/dist/core/memory-engine/sync.js +91 -0
- package/dist/core/memory-engine/sync.js.map +1 -0
- package/dist/core/memory-engine/types.d.ts +279 -0
- package/dist/core/memory-engine/types.d.ts.map +1 -0
- package/dist/core/memory-engine/types.js +9 -0
- package/dist/core/memory-engine/types.js.map +1 -0
- package/dist/core/memory-recall.d.ts +261 -0
- package/dist/core/memory-recall.d.ts.map +1 -0
- package/dist/core/memory-recall.js +600 -0
- package/dist/core/memory-recall.js.map +1 -0
- package/dist/core/memory-vector.d.ts +24 -0
- package/dist/core/memory-vector.d.ts.map +1 -0
- package/dist/core/memory-vector.js +51 -0
- package/dist/core/memory-vector.js.map +1 -0
- package/dist/core/memory.d.ts +502 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +881 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/message-utils.d.ts +7 -0
- package/dist/core/message-utils.d.ts.map +1 -0
- package/dist/core/message-utils.js +10 -0
- package/dist/core/message-utils.js.map +1 -0
- package/dist/core/oracle-isolation.d.ts +85 -0
- package/dist/core/oracle-isolation.d.ts.map +1 -0
- package/dist/core/oracle-isolation.js +121 -0
- package/dist/core/oracle-isolation.js.map +1 -0
- package/dist/core/permission-rules.d.ts +102 -0
- package/dist/core/permission-rules.d.ts.map +1 -0
- package/dist/core/permission-rules.js +357 -0
- package/dist/core/permission-rules.js.map +1 -0
- package/dist/core/present-plan-tool.d.ts +28 -0
- package/dist/core/present-plan-tool.d.ts.map +1 -0
- package/dist/core/present-plan-tool.js +119 -0
- package/dist/core/present-plan-tool.js.map +1 -0
- package/dist/core/pricing.d.ts +48 -0
- package/dist/core/pricing.d.ts.map +1 -0
- package/dist/core/pricing.js +46 -0
- package/dist/core/pricing.js.map +1 -0
- package/dist/core/property-harness.d.ts +126 -0
- package/dist/core/property-harness.d.ts.map +1 -0
- package/dist/core/property-harness.js +192 -0
- package/dist/core/property-harness.js.map +1 -0
- package/dist/core/push-queue.d.ts +10 -0
- package/dist/core/push-queue.d.ts.map +1 -0
- package/dist/core/push-queue.js +42 -0
- package/dist/core/push-queue.js.map +1 -0
- package/dist/core/remote-env.d.ts +432 -0
- package/dist/core/remote-env.d.ts.map +1 -0
- package/dist/core/remote-env.js +77 -0
- package/dist/core/remote-env.js.map +1 -0
- package/dist/core/roles.d.ts +74 -0
- package/dist/core/roles.d.ts.map +1 -0
- package/dist/core/roles.js +272 -0
- package/dist/core/roles.js.map +1 -0
- package/dist/core/runner/active-skill-scope.d.ts +64 -0
- package/dist/core/runner/active-skill-scope.d.ts.map +1 -0
- package/dist/core/runner/active-skill-scope.js +197 -0
- package/dist/core/runner/active-skill-scope.js.map +1 -0
- package/dist/core/runner/assemble-result.d.ts +191 -0
- package/dist/core/runner/assemble-result.d.ts.map +1 -0
- package/dist/core/runner/assemble-result.js +250 -0
- package/dist/core/runner/assemble-result.js.map +1 -0
- package/dist/core/runner/call-cap.d.ts +130 -0
- package/dist/core/runner/call-cap.d.ts.map +1 -0
- package/dist/core/runner/call-cap.js +151 -0
- package/dist/core/runner/call-cap.js.map +1 -0
- package/dist/core/runner/grounding-signal.d.ts +12 -0
- package/dist/core/runner/grounding-signal.d.ts.map +1 -0
- package/dist/core/runner/grounding-signal.js +94 -0
- package/dist/core/runner/grounding-signal.js.map +1 -0
- package/dist/core/runner/image.d.ts +23 -0
- package/dist/core/runner/image.d.ts.map +1 -0
- package/dist/core/runner/image.js +151 -0
- package/dist/core/runner/image.js.map +1 -0
- package/dist/core/runner/memory-consolidation.d.ts +112 -0
- package/dist/core/runner/memory-consolidation.d.ts.map +1 -0
- package/dist/core/runner/memory-consolidation.js +372 -0
- package/dist/core/runner/memory-consolidation.js.map +1 -0
- package/dist/core/runner/prepare-task.d.ts +583 -0
- package/dist/core/runner/prepare-task.d.ts.map +1 -0
- package/dist/core/runner/prepare-task.js +3612 -0
- package/dist/core/runner/prepare-task.js.map +1 -0
- package/dist/core/runner/prompt-suggestions.d.ts +33 -0
- package/dist/core/runner/prompt-suggestions.d.ts.map +1 -0
- package/dist/core/runner/prompt-suggestions.js +116 -0
- package/dist/core/runner/prompt-suggestions.js.map +1 -0
- package/dist/core/runner/runtask.d.ts +274 -0
- package/dist/core/runner/runtask.d.ts.map +1 -0
- package/dist/core/runner/runtask.js +4606 -0
- package/dist/core/runner/runtask.js.map +1 -0
- package/dist/core/runner/session-rule-policy.d.ts +28 -0
- package/dist/core/runner/session-rule-policy.d.ts.map +1 -0
- package/dist/core/runner/session-rule-policy.js +110 -0
- package/dist/core/runner/session-rule-policy.js.map +1 -0
- package/dist/core/runner/strict-output-schema.d.ts +36 -0
- package/dist/core/runner/strict-output-schema.d.ts.map +1 -0
- package/dist/core/runner/strict-output-schema.js +365 -0
- package/dist/core/runner/strict-output-schema.js.map +1 -0
- package/dist/core/runner/synthetic-tools.d.ts +72 -0
- package/dist/core/runner/synthetic-tools.d.ts.map +1 -0
- package/dist/core/runner/synthetic-tools.js +203 -0
- package/dist/core/runner/synthetic-tools.js.map +1 -0
- package/dist/core/runner/tool-disclosure.d.ts +117 -0
- package/dist/core/runner/tool-disclosure.d.ts.map +1 -0
- package/dist/core/runner/tool-disclosure.js +0 -0
- package/dist/core/runner/tool-disclosure.js.map +1 -0
- package/dist/core/runner/turn-attachments.d.ts +381 -0
- package/dist/core/runner/turn-attachments.d.ts.map +1 -0
- package/dist/core/runner/turn-attachments.js +596 -0
- package/dist/core/runner/turn-attachments.js.map +1 -0
- package/dist/core/runner/usage-accounting.d.ts +35 -0
- package/dist/core/runner/usage-accounting.d.ts.map +1 -0
- package/dist/core/runner/usage-accounting.js +45 -0
- package/dist/core/runner/usage-accounting.js.map +1 -0
- package/dist/core/runtime.d.ts +9 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +17 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/safety-axis-vocab.d.ts +33 -0
- package/dist/core/safety-axis-vocab.d.ts.map +1 -0
- package/dist/core/safety-axis-vocab.js +35 -0
- package/dist/core/safety-axis-vocab.js.map +1 -0
- package/dist/core/safety-merge-corpus.d.ts +48 -0
- package/dist/core/safety-merge-corpus.d.ts.map +1 -0
- package/dist/core/safety-merge-corpus.js +203 -0
- package/dist/core/safety-merge-corpus.js.map +1 -0
- package/dist/core/scheduler.d.ts +126 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +54 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/secret-env.d.ts +23 -0
- package/dist/core/secret-env.d.ts.map +1 -0
- package/dist/core/secret-env.js +35 -0
- package/dist/core/secret-env.js.map +1 -0
- package/dist/core/select-model.d.ts +26 -0
- package/dist/core/select-model.d.ts.map +1 -0
- package/dist/core/select-model.js +58 -0
- package/dist/core/select-model.js.map +1 -0
- package/dist/core/sensitive-path-policy.d.ts +24 -0
- package/dist/core/sensitive-path-policy.d.ts.map +1 -0
- package/dist/core/sensitive-path-policy.js +96 -0
- package/dist/core/sensitive-path-policy.js.map +1 -0
- package/dist/core/session-policy-store.d.ts +102 -0
- package/dist/core/session-policy-store.d.ts.map +1 -0
- package/dist/core/session-policy-store.js +177 -0
- package/dist/core/session-policy-store.js.map +1 -0
- package/dist/core/session-reconcile.d.ts +63 -0
- package/dist/core/session-reconcile.d.ts.map +1 -0
- package/dist/core/session-reconcile.js +71 -0
- package/dist/core/session-reconcile.js.map +1 -0
- package/dist/core/session-store.d.ts +99 -0
- package/dist/core/session-store.d.ts.map +1 -0
- package/dist/core/session-store.js +298 -0
- package/dist/core/session-store.js.map +1 -0
- package/dist/core/session.d.ts +144 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +56 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/spec-contract.d.ts +147 -0
- package/dist/core/spec-contract.d.ts.map +1 -0
- package/dist/core/spec-contract.js +340 -0
- package/dist/core/spec-contract.js.map +1 -0
- package/dist/core/strategy-store.d.ts +50 -0
- package/dist/core/strategy-store.d.ts.map +1 -0
- package/dist/core/strategy-store.js +100 -0
- package/dist/core/strategy-store.js.map +1 -0
- package/dist/core/stub-env.d.ts +35 -0
- package/dist/core/stub-env.d.ts.map +1 -0
- package/dist/core/stub-env.js +69 -0
- package/dist/core/stub-env.js.map +1 -0
- package/dist/core/task-notification.d.ts +115 -0
- package/dist/core/task-notification.d.ts.map +1 -0
- package/dist/core/task-notification.js +247 -0
- package/dist/core/task-notification.js.map +1 -0
- package/dist/core/task-outcome.d.ts +80 -0
- package/dist/core/task-outcome.d.ts.map +1 -0
- package/dist/core/task-outcome.js +40 -0
- package/dist/core/task-outcome.js.map +1 -0
- package/dist/core/task-registry.d.ts +349 -0
- package/dist/core/task-registry.d.ts.map +1 -0
- package/dist/core/task-registry.js +1751 -0
- package/dist/core/task-registry.js.map +1 -0
- package/dist/core/tighten-task-spec.d.ts +27 -0
- package/dist/core/tighten-task-spec.d.ts.map +1 -0
- package/dist/core/tighten-task-spec.js +95 -0
- package/dist/core/tighten-task-spec.js.map +1 -0
- package/dist/core/tool-detach.d.ts +31 -0
- package/dist/core/tool-detach.d.ts.map +1 -0
- package/dist/core/tool-detach.js +62 -0
- package/dist/core/tool-detach.js.map +1 -0
- package/dist/core/tool-errors.d.ts +72 -0
- package/dist/core/tool-errors.d.ts.map +1 -0
- package/dist/core/tool-errors.js +194 -0
- package/dist/core/tool-errors.js.map +1 -0
- package/dist/core/tool-name-aliases.d.ts +5 -0
- package/dist/core/tool-name-aliases.d.ts.map +1 -0
- package/dist/core/tool-name-aliases.js +130 -0
- package/dist/core/tool-name-aliases.js.map +1 -0
- package/dist/core/tool-policy.d.ts +295 -0
- package/dist/core/tool-policy.d.ts.map +1 -0
- package/dist/core/tool-policy.js +567 -0
- package/dist/core/tool-policy.js.map +1 -0
- package/dist/core/tool-result-budget.d.ts +44 -0
- package/dist/core/tool-result-budget.d.ts.map +1 -0
- package/dist/core/tool-result-budget.js +140 -0
- package/dist/core/tool-result-budget.js.map +1 -0
- package/dist/core/tool-result-store.d.ts +136 -0
- package/dist/core/tool-result-store.d.ts.map +1 -0
- package/dist/core/tool-result-store.js +219 -0
- package/dist/core/tool-result-store.js.map +1 -0
- package/dist/core/tools.d.ts +14 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +98 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/core/trace.d.ts +340 -0
- package/dist/core/trace.d.ts.map +1 -0
- package/dist/core/trace.js +12 -0
- package/dist/core/trace.js.map +1 -0
- package/dist/core/types.d.ts +2828 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/untrusted-egress.d.ts +32 -0
- package/dist/core/untrusted-egress.d.ts.map +1 -0
- package/dist/core/untrusted-egress.js +49 -0
- package/dist/core/untrusted-egress.js.map +1 -0
- package/dist/core/untrusted-text.d.ts +64 -0
- package/dist/core/untrusted-text.d.ts.map +1 -0
- package/dist/core/untrusted-text.js +119 -0
- package/dist/core/untrusted-text.js.map +1 -0
- package/dist/core/warm-resume.d.ts +23 -0
- package/dist/core/warm-resume.d.ts.map +1 -0
- package/dist/core/warm-resume.js +28 -0
- package/dist/core/warm-resume.js.map +1 -0
- package/dist/core/with-retry.d.ts +43 -0
- package/dist/core/with-retry.d.ts.map +1 -0
- package/dist/core/with-retry.js +59 -0
- package/dist/core/with-retry.js.map +1 -0
- package/dist/core/workflow-journal-store.d.ts +44 -0
- package/dist/core/workflow-journal-store.d.ts.map +1 -0
- package/dist/core/workflow-journal-store.js +47 -0
- package/dist/core/workflow-journal-store.js.map +1 -0
- package/dist/core/workflow-run-store-contract.d.ts +31 -0
- package/dist/core/workflow-run-store-contract.d.ts.map +1 -0
- package/dist/core/workflow-run-store-contract.js +191 -0
- package/dist/core/workflow-run-store-contract.js.map +1 -0
- package/dist/core/workflow-run-store.d.ts +149 -0
- package/dist/core/workflow-run-store.d.ts.map +1 -0
- package/dist/core/workflow-run-store.js +110 -0
- package/dist/core/workflow-run-store.js.map +1 -0
- package/dist/engine/compaction/compaction.d.ts +139 -0
- package/dist/engine/compaction/compaction.d.ts.map +1 -0
- package/dist/engine/compaction/compaction.js +1030 -0
- package/dist/engine/compaction/compaction.js.map +1 -0
- package/dist/engine/compaction/utils.d.ts +45 -0
- package/dist/engine/compaction/utils.d.ts.map +1 -0
- package/dist/engine/compaction/utils.js +203 -0
- package/dist/engine/compaction/utils.js.map +1 -0
- package/dist/engine/execution-env/kill-tree.d.ts +20 -0
- package/dist/engine/execution-env/kill-tree.d.ts.map +1 -0
- package/dist/engine/execution-env/kill-tree.js +183 -0
- package/dist/engine/execution-env/kill-tree.js.map +1 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +133 -0
- package/dist/engine/execution-env/node-execution-env.d.ts.map +1 -0
- package/dist/engine/execution-env/node-execution-env.js +1031 -0
- package/dist/engine/execution-env/node-execution-env.js.map +1 -0
- package/dist/engine/harness/agent-harness.d.ts +174 -0
- package/dist/engine/harness/agent-harness.d.ts.map +1 -0
- package/dist/engine/harness/agent-harness.js +1053 -0
- package/dist/engine/harness/agent-harness.js.map +1 -0
- package/dist/engine/harness/messages.d.ts +17 -0
- package/dist/engine/harness/messages.d.ts.map +1 -0
- package/dist/engine/harness/messages.js +122 -0
- package/dist/engine/harness/messages.js.map +1 -0
- package/dist/engine/harness/types.d.ts +713 -0
- package/dist/engine/harness/types.d.ts.map +1 -0
- package/dist/engine/harness/types.js +100 -0
- package/dist/engine/harness/types.js.map +1 -0
- package/dist/engine/llm/diagnostics.d.ts +23 -0
- package/dist/engine/llm/diagnostics.d.ts.map +1 -0
- package/dist/engine/llm/diagnostics.js +32 -0
- package/dist/engine/llm/diagnostics.js.map +1 -0
- package/dist/engine/llm/event-stream.d.ts +25 -0
- package/dist/engine/llm/event-stream.d.ts.map +1 -0
- package/dist/engine/llm/event-stream.js +103 -0
- package/dist/engine/llm/event-stream.js.map +1 -0
- package/dist/engine/llm/index.d.ts +12 -0
- package/dist/engine/llm/index.d.ts.map +1 -0
- package/dist/engine/llm/index.js +12 -0
- package/dist/engine/llm/index.js.map +1 -0
- package/dist/engine/llm/types.d.ts +753 -0
- package/dist/engine/llm/types.d.ts.map +1 -0
- package/dist/engine/llm/types.js +2 -0
- package/dist/engine/llm/types.js.map +1 -0
- package/dist/engine/llm/validation.d.ts +8 -0
- package/dist/engine/llm/validation.d.ts.map +1 -0
- package/dist/engine/llm/validation.js +318 -0
- package/dist/engine/llm/validation.js.map +1 -0
- package/dist/engine/loop/agent-loop.d.ts +74 -0
- package/dist/engine/loop/agent-loop.d.ts.map +1 -0
- package/dist/engine/loop/agent-loop.js +1490 -0
- package/dist/engine/loop/agent-loop.js.map +1 -0
- package/dist/engine/loop/runtime-deps.d.ts +17 -0
- package/dist/engine/loop/runtime-deps.d.ts.map +1 -0
- package/dist/engine/loop/runtime-deps.js +21 -0
- package/dist/engine/loop/runtime-deps.js.map +1 -0
- package/dist/engine/loop/types.d.ts +609 -0
- package/dist/engine/loop/types.d.ts.map +1 -0
- package/dist/engine/loop/types.js +2 -0
- package/dist/engine/loop/types.js.map +1 -0
- package/dist/engine/lsp/frame-decoder.d.ts +16 -0
- package/dist/engine/lsp/frame-decoder.d.ts.map +1 -0
- package/dist/engine/lsp/frame-decoder.js +53 -0
- package/dist/engine/lsp/frame-decoder.js.map +1 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +105 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts.map +1 -0
- package/dist/engine/lsp/node-lsp-manager.js +343 -0
- package/dist/engine/lsp/node-lsp-manager.js.map +1 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts +37 -0
- package/dist/engine/lsp/stdio-lsp-transport.d.ts.map +1 -0
- package/dist/engine/lsp/stdio-lsp-transport.js +185 -0
- package/dist/engine/lsp/stdio-lsp-transport.js.map +1 -0
- package/dist/engine/session/import-validate.d.ts +44 -0
- package/dist/engine/session/import-validate.d.ts.map +1 -0
- package/dist/engine/session/import-validate.js +92 -0
- package/dist/engine/session/import-validate.js.map +1 -0
- package/dist/engine/session/memory-repo.d.ts +25 -0
- package/dist/engine/session/memory-repo.d.ts.map +1 -0
- package/dist/engine/session/memory-repo.js +59 -0
- package/dist/engine/session/memory-repo.js.map +1 -0
- package/dist/engine/session/memory-storage.d.ts +14 -0
- package/dist/engine/session/memory-storage.d.ts.map +1 -0
- package/dist/engine/session/memory-storage.js +17 -0
- package/dist/engine/session/memory-storage.js.map +1 -0
- package/dist/engine/session/repo-utils.d.ts +11 -0
- package/dist/engine/session/repo-utils.d.ts.map +1 -0
- package/dist/engine/session/repo-utils.js +40 -0
- package/dist/engine/session/repo-utils.js.map +1 -0
- package/dist/engine/session/session.d.ts +34 -0
- package/dist/engine/session/session.d.ts.map +1 -0
- package/dist/engine/session/session.js +227 -0
- package/dist/engine/session/session.js.map +1 -0
- package/dist/engine/session/storage-base.d.ts +38 -0
- package/dist/engine/session/storage-base.d.ts.map +1 -0
- package/dist/engine/session/storage-base.js +157 -0
- package/dist/engine/session/storage-base.js.map +1 -0
- package/dist/engine/session/timestamps.d.ts +3 -0
- package/dist/engine/session/timestamps.d.ts.map +1 -0
- package/dist/engine/session/timestamps.js +15 -0
- package/dist/engine/session/timestamps.js.map +1 -0
- package/dist/engine/session/uuid.d.ts +2 -0
- package/dist/engine/session/uuid.d.ts.map +1 -0
- package/dist/engine/session/uuid.js +50 -0
- package/dist/engine/session/uuid.js.map +1 -0
- package/dist/index.d.ts +160 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +374 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/harness.d.ts +26 -0
- package/dist/internal/harness.d.ts.map +1 -0
- package/dist/internal/harness.js +24 -0
- package/dist/internal/harness.js.map +1 -0
- package/dist/internal/llm.d.ts +9 -0
- package/dist/internal/llm.d.ts.map +1 -0
- package/dist/internal/llm.js +8 -0
- package/dist/internal/llm.js.map +1 -0
- package/dist/orchestration/builtin-workflows.d.ts +44 -0
- package/dist/orchestration/builtin-workflows.d.ts.map +1 -0
- package/dist/orchestration/builtin-workflows.js +165 -0
- package/dist/orchestration/builtin-workflows.js.map +1 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts +24 -0
- package/dist/orchestration/dev-vm-script-runner.d.ts.map +1 -0
- package/dist/orchestration/dev-vm-script-runner.js +106 -0
- package/dist/orchestration/dev-vm-script-runner.js.map +1 -0
- package/dist/orchestration/goal.d.ts +97 -0
- package/dist/orchestration/goal.d.ts.map +1 -0
- package/dist/orchestration/goal.js +248 -0
- package/dist/orchestration/goal.js.map +1 -0
- package/dist/orchestration/run-spec.d.ts +63 -0
- package/dist/orchestration/run-spec.d.ts.map +1 -0
- package/dist/orchestration/run-spec.js +274 -0
- package/dist/orchestration/run-spec.js.map +1 -0
- package/dist/orchestration/run-workflow-tool.d.ts +187 -0
- package/dist/orchestration/run-workflow-tool.d.ts.map +1 -0
- package/dist/orchestration/run-workflow-tool.js +612 -0
- package/dist/orchestration/run-workflow-tool.js.map +1 -0
- package/dist/orchestration/workflow-governance.d.ts +70 -0
- package/dist/orchestration/workflow-governance.d.ts.map +1 -0
- package/dist/orchestration/workflow-governance.js +176 -0
- package/dist/orchestration/workflow-governance.js.map +1 -0
- package/dist/orchestration/workflow-meta.d.ts +41 -0
- package/dist/orchestration/workflow-meta.d.ts.map +1 -0
- package/dist/orchestration/workflow-meta.js +426 -0
- package/dist/orchestration/workflow-meta.js.map +1 -0
- package/dist/orchestration/workflow-observe.d.ts +77 -0
- package/dist/orchestration/workflow-observe.d.ts.map +1 -0
- package/dist/orchestration/workflow-observe.js +177 -0
- package/dist/orchestration/workflow-observe.js.map +1 -0
- package/dist/orchestration/workflow-primitives.d.ts +31 -0
- package/dist/orchestration/workflow-primitives.d.ts.map +1 -0
- package/dist/orchestration/workflow-primitives.js +104 -0
- package/dist/orchestration/workflow-primitives.js.map +1 -0
- package/dist/orchestration/workflow-sandbox-conformance.d.ts +34 -0
- package/dist/orchestration/workflow-sandbox-conformance.d.ts.map +1 -0
- package/dist/orchestration/workflow-sandbox-conformance.js +301 -0
- package/dist/orchestration/workflow-sandbox-conformance.js.map +1 -0
- package/dist/orchestration/workflow-script-runner.d.ts +127 -0
- package/dist/orchestration/workflow-script-runner.d.ts.map +1 -0
- package/dist/orchestration/workflow-script-runner.js +48 -0
- package/dist/orchestration/workflow-script-runner.js.map +1 -0
- package/dist/orchestration/workflow-script-store.d.ts +99 -0
- package/dist/orchestration/workflow-script-store.d.ts.map +1 -0
- package/dist/orchestration/workflow-script-store.js +133 -0
- package/dist/orchestration/workflow-script-store.js.map +1 -0
- package/dist/orchestration/workflow-size-guideline.d.ts +50 -0
- package/dist/orchestration/workflow-size-guideline.d.ts.map +1 -0
- package/dist/orchestration/workflow-size-guideline.js +78 -0
- package/dist/orchestration/workflow-size-guideline.js.map +1 -0
- package/dist/orchestration/workflow.d.ts +624 -0
- package/dist/orchestration/workflow.d.ts.map +1 -0
- package/dist/orchestration/workflow.js +1596 -0
- package/dist/orchestration/workflow.js.map +1 -0
- package/dist/prompts/default.d.ts +474 -0
- package/dist/prompts/default.d.ts.map +1 -0
- package/dist/prompts/default.js +676 -0
- package/dist/prompts/default.js.map +1 -0
- package/dist/prompts/supervisor.d.ts +60 -0
- package/dist/prompts/supervisor.d.ts.map +1 -0
- package/dist/prompts/supervisor.js +162 -0
- package/dist/prompts/supervisor.js.map +1 -0
- package/dist/scenarios/env.d.ts +41 -0
- package/dist/scenarios/env.d.ts.map +1 -0
- package/dist/scenarios/env.js +65 -0
- package/dist/scenarios/env.js.map +1 -0
- package/dist/scenarios/full-body.d.ts +47 -0
- package/dist/scenarios/full-body.d.ts.map +1 -0
- package/dist/scenarios/full-body.js +36 -0
- package/dist/scenarios/full-body.js.map +1 -0
- package/dist/scenarios/scenario-registry.d.ts +107 -0
- package/dist/scenarios/scenario-registry.d.ts.map +1 -0
- package/dist/scenarios/scenario-registry.js +192 -0
- package/dist/scenarios/scenario-registry.js.map +1 -0
- package/dist/scenarios/teacher-quickstart.d.ts +41 -0
- package/dist/scenarios/teacher-quickstart.d.ts.map +1 -0
- package/dist/scenarios/teacher-quickstart.js +32 -0
- package/dist/scenarios/teacher-quickstart.js.map +1 -0
- package/dist/server/http.d.ts +36 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +144 -0
- package/dist/server/http.js.map +1 -0
- package/dist/stores/file/checkpoint-store.d.ts +62 -0
- package/dist/stores/file/checkpoint-store.d.ts.map +1 -0
- package/dist/stores/file/checkpoint-store.js +250 -0
- package/dist/stores/file/checkpoint-store.js.map +1 -0
- package/dist/stores/file/file-snapshot-store.d.ts +43 -0
- package/dist/stores/file/file-snapshot-store.d.ts.map +1 -0
- package/dist/stores/file/file-snapshot-store.js +374 -0
- package/dist/stores/file/file-snapshot-store.js.map +1 -0
- package/dist/stores/file/fs-atomic.d.ts +95 -0
- package/dist/stores/file/fs-atomic.d.ts.map +1 -0
- package/dist/stores/file/fs-atomic.js +415 -0
- package/dist/stores/file/fs-atomic.js.map +1 -0
- package/dist/stores/file/index.d.ts +98 -0
- package/dist/stores/file/index.d.ts.map +1 -0
- package/dist/stores/file/index.js +109 -0
- package/dist/stores/file/index.js.map +1 -0
- package/dist/stores/file/memory-store.d.ts +95 -0
- package/dist/stores/file/memory-store.d.ts.map +1 -0
- package/dist/stores/file/memory-store.js +393 -0
- package/dist/stores/file/memory-store.js.map +1 -0
- package/dist/stores/file/session-policy-store.d.ts +24 -0
- package/dist/stores/file/session-policy-store.d.ts.map +1 -0
- package/dist/stores/file/session-policy-store.js +123 -0
- package/dist/stores/file/session-policy-store.js.map +1 -0
- package/dist/stores/file/session-store.d.ts +34 -0
- package/dist/stores/file/session-store.d.ts.map +1 -0
- package/dist/stores/file/session-store.js +175 -0
- package/dist/stores/file/session-store.js.map +1 -0
- package/dist/stores/file/tool-result-store.d.ts +23 -0
- package/dist/stores/file/tool-result-store.d.ts.map +1 -0
- package/dist/stores/file/tool-result-store.js +61 -0
- package/dist/stores/file/tool-result-store.js.map +1 -0
- package/dist/stores/file/workflow-journal-store.d.ts +36 -0
- package/dist/stores/file/workflow-journal-store.d.ts.map +1 -0
- package/dist/stores/file/workflow-journal-store.js +157 -0
- package/dist/stores/file/workflow-journal-store.js.map +1 -0
- package/dist/stores/file/workflow-run-store.d.ts +58 -0
- package/dist/stores/file/workflow-run-store.d.ts.map +1 -0
- package/dist/stores/file/workflow-run-store.js +178 -0
- package/dist/stores/file/workflow-run-store.js.map +1 -0
- package/dist/stores/pg.d.ts +210 -0
- package/dist/stores/pg.d.ts.map +1 -0
- package/dist/stores/pg.js +652 -0
- package/dist/stores/pg.js.map +1 -0
- package/dist/tools/fs/encoding.d.ts +51 -0
- package/dist/tools/fs/encoding.d.ts.map +1 -0
- package/dist/tools/fs/encoding.js +74 -0
- package/dist/tools/fs/encoding.js.map +1 -0
- package/dist/tools/fs/gh-rate-limit.d.ts +19 -0
- package/dist/tools/fs/gh-rate-limit.d.ts.map +1 -0
- package/dist/tools/fs/gh-rate-limit.js +35 -0
- package/dist/tools/fs/gh-rate-limit.js.map +1 -0
- package/dist/tools/fs/index.d.ts +246 -0
- package/dist/tools/fs/index.d.ts.map +1 -0
- package/dist/tools/fs/index.js +2130 -0
- package/dist/tools/fs/index.js.map +1 -0
- package/dist/tools/fs/pdf.d.ts +106 -0
- package/dist/tools/fs/pdf.d.ts.map +1 -0
- package/dist/tools/fs/pdf.js +178 -0
- package/dist/tools/fs/pdf.js.map +1 -0
- package/dist/tools/fs/repo-map.d.ts +15 -0
- package/dist/tools/fs/repo-map.d.ts.map +1 -0
- package/dist/tools/fs/repo-map.js +251 -0
- package/dist/tools/fs/repo-map.js.map +1 -0
- package/dist/tools/fs/safety.d.ts +168 -0
- package/dist/tools/fs/safety.d.ts.map +1 -0
- package/dist/tools/fs/safety.js +479 -0
- package/dist/tools/fs/safety.js.map +1 -0
- package/dist/tools/fs/search.d.ts +118 -0
- package/dist/tools/fs/search.d.ts.map +1 -0
- package/dist/tools/fs/search.js +650 -0
- package/dist/tools/fs/search.js.map +1 -0
- package/dist/tools/gitea-issue.d.ts +39 -0
- package/dist/tools/gitea-issue.d.ts.map +1 -0
- package/dist/tools/gitea-issue.js +91 -0
- package/dist/tools/gitea-issue.js.map +1 -0
- package/dist/tools/monitor.d.ts +64 -0
- package/dist/tools/monitor.d.ts.map +1 -0
- package/dist/tools/monitor.js +135 -0
- package/dist/tools/monitor.js.map +1 -0
- package/dist/tools/scheduler-tools.d.ts +48 -0
- package/dist/tools/scheduler-tools.d.ts.map +1 -0
- package/dist/tools/scheduler-tools.js +449 -0
- package/dist/tools/scheduler-tools.js.map +1 -0
- package/dist/tools/sql-adapters.d.ts +32 -0
- package/dist/tools/sql-adapters.d.ts.map +1 -0
- package/dist/tools/sql-adapters.js +31 -0
- package/dist/tools/sql-adapters.js.map +1 -0
- package/dist/tools/sql.d.ts +36 -0
- package/dist/tools/sql.d.ts.map +1 -0
- package/dist/tools/sql.js +131 -0
- package/dist/tools/sql.js.map +1 -0
- package/dist/tools/task-list.d.ts +26 -0
- package/dist/tools/task-list.d.ts.map +1 -0
- package/dist/tools/task-list.js +352 -0
- package/dist/tools/task-list.js.map +1 -0
- package/dist/tools/todo.d.ts +11 -0
- package/dist/tools/todo.d.ts.map +1 -0
- package/dist/tools/todo.js +126 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/web.d.ts +59 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +607 -0
- package/dist/tools/web.js.map +1 -0
- package/dist/tools/worktree.d.ts +88 -0
- package/dist/tools/worktree.d.ts.map +1 -0
- package/dist/tools/worktree.js +434 -0
- package/dist/tools/worktree.js.map +1 -0
- package/docs/A1-ATTRIBUTION-ROUND1-2026-07-09.md +181 -0
- package/docs/AB-ORACLE-GATE-VERDICT-2026-07-10.md +100 -0
- package/docs/ANCHOR-GAP-INVENTORY-2026-07-09.md +143 -0
- package/docs/ARCHITECTURE.md +125 -0
- package/docs/BUGHUNT-2026-07-05-NIGHT.md +98 -0
- package/docs/BUILD.md +63 -0
- package/docs/CANCEL-ASYNC-ATTRIBUTION-2026-07-09.md +98 -0
- package/docs/CC-198-VS-201-DRIFT-2026-07-09.md +70 -0
- package/docs/CC-BASELINE-FAKE-ZERO-AUDIT-2026-07-09.md +51 -0
- package/docs/CC-DRIFT-198-206-AGENT-TYPES-2026-07-10.md +82 -0
- package/docs/CC-DRIFT-198-206-CHANGELOG-2026-07-10.md +82 -0
- package/docs/CC-DRIFT-198-206-REMINDERS-2026-07-10.md +96 -0
- package/docs/CC-DRIFT-198-206-ROADMAP-2026-07-10.md +110 -0
- package/docs/CC-DRIFT-198-206-TOOL-INVENTORY-2026-07-10.md +53 -0
- package/docs/CC-DRIFT-198-206-USAGE-CONSTANTS-2026-07-10.md +64 -0
- package/docs/CC-DRIFT-198-206-WORKFLOW-2026-07-10.md +83 -0
- package/docs/CC-PARITY-CHECKLIST.md +220 -0
- package/docs/CC-PARITY-DEEP-SWEEP-2026-07-07.md +149 -0
- package/docs/CC-SUBAGENT-PROMPT-STUDY-2026-07-09.md +219 -0
- package/docs/CC-TASK-REMINDER-CADENCE-STUDY-2026-07-09.md +396 -0
- package/docs/CC-TOOL-PARITY-SWEEP-2026-07.md +56 -0
- package/docs/CC-TOOL-PROMPT-DEEP-DIFF-2026-07-08.md +274 -0
- package/docs/CC-TOOLSURFACE-DEEP-DIVE-2026-07-07.md +197 -0
- package/docs/CC206-OBSERVER-ANCHORS-2026-07-11.md +463 -0
- package/docs/CC207-CORE-SWEEP-BACKLOG-2026-07-12.md +155 -0
- package/docs/CENTER-CONTROL-PLANE-SEAM.md +86 -0
- package/docs/CLEANUP-CONTRACT-ANCHOR-2026-07-09.md +83 -0
- package/docs/COLD-START-RSI-2026-07-09.md +72 -0
- package/docs/COMPACTION-LIVE-AUDIT-2026-07-09.md +114 -0
- package/docs/CONTEXT-lifecycle-extension-points-and-stop-attribution.md +71 -0
- package/docs/COREWARS-POLYGLOT-TRIAGE-2026-07-09.md +85 -0
- package/docs/DEADTARGET-OVERFULL-HBOX-2026-07-10.md +92 -0
- package/docs/DEADTARGET-PATH-TRACING-REVERSE-2026-07-10.md +87 -0
- package/docs/DEADTARGET-WINNING-AVG-COREWARS-2026-07-10.md +96 -0
- package/docs/DEEPSEEK-API-LIMITS-PROBE-2026-07-09.md +118 -0
- package/docs/DESIGN-140-MOCK-VERIFY-2026-07-11.md +79 -0
- package/docs/DESIGN-140-VERIFICATION-2026-07-11.md +43 -0
- package/docs/DESIGN-DRAFT-workflow-collab-2026-07-11.md +56 -0
- package/docs/DESIGN-ORACLE-GROUNDING-GATE-2026-07-10.md +167 -0
- package/docs/DESIGN-TFRAG-RECONCILE-SCAFFOLD-2026-07-09.md +102 -0
- package/docs/EXP-PA2-PE-DESIGN-2026-07-11.md +220 -0
- package/docs/EXT-DOGFOOD-2026-07-12.md +50 -0
- package/docs/FINAL-VERIFY-SURFACE-AUDIT-2026-07-09.md +44 -0
- package/docs/FRAG-RECON-INVESTIGATION-2026-07-09.md +183 -0
- package/docs/HANDOFF.md +121 -0
- package/docs/KNOWN-ISSUES.md +96 -0
- package/docs/LEGW-WINDOW-TAX-2026-07-10.md +82 -0
- package/docs/LIVE-PROBE-BATCH-2026-07-11.md +207 -0
- package/docs/M2-CERT-ATTRIBUTION-2026-07-10.md +61 -0
- package/docs/M25-LEG-VARIANCE-ATTRIBUTION-2026-07-10.md +81 -0
- package/docs/MAILMAN-TIMEOUT-ATTRIBUTION-2026-07-10.md +88 -0
- package/docs/MEMORY-BACKEND-DIALECT-NOTES.md +69 -0
- package/docs/MTEB-ESCAPE-HATCH-ATTRIBUTION-2026-07-09.md +57 -0
- package/docs/MTEB-LEADERBOARD-ATTRIBUTION-2026-07-10.md +134 -0
- package/docs/ORACLE-GATE-NEGATIVE-SAMPLE-2026-07-11.md +28 -0
- package/docs/PARITY-CONTEXT-TRANSACTIONS-2026-07-10.md +67 -0
- package/docs/PARITY-PROGRESS-MATRIX-2026-07-10.md +37 -0
- package/docs/PARITY-SPOT-AGENT-TYPES-2026-07-10.md +70 -0
- package/docs/PARITY-SPOT-REMINDERS-2026-07-10.md +144 -0
- package/docs/PARITY-SPOT-TOOL-INVENTORY-2026-07-10.md +61 -0
- package/docs/PARITY-SPOT-USAGE-CONSTANTS-2026-07-10.md +95 -0
- package/docs/PARITY-SPOT-WORKFLOW-2026-07-10.md +93 -0
- package/docs/PASSWORD-RECOVERY-PANEL-VERDICT-2026-07-10.md +62 -0
- package/docs/R8-R9-FINALIZE-COORDINATION-2026-07-09.md +124 -0
- package/docs/REPL-CODE-MODE-EVALUATION-2026-07-10.md +187 -0
- package/docs/REPORT-1249-TARGETED.md +48 -0
- package/docs/RESEARCH-3P-MEMORY-SWAP-2026-07-12.md +273 -0
- package/docs/ROADMAP.md +111 -0
- package/docs/RSI-CLOUD-DEPLOY-2026-07-06.md +289 -0
- package/docs/RSI-PROCESS-AI-COLDSTART-2026-07-11.md +68 -0
- package/docs/S18-THOROUGHNESS-AUDIT-2026-07-09.md +113 -0
- package/docs/SERVICE-INTEGRATION-GUIDE.md +298 -0
- package/docs/SUBAGENT-STREAM-RESILIENCE-PARITY-2026-07-10.md +118 -0
- package/docs/SWEBENCH-PRO-RECON-2026-07-11.md +31 -0
- package/docs/TB-EFFICIENCY-TELEMETRY-2026-07-08.md +114 -0
- package/docs/TB-FAILURE-AUTOPSY-2026-07-05-RERUN.md +67 -0
- package/docs/TB-FAIRNESS-AUDIT-2026-07-08.md +141 -0
- package/docs/TB-FULL-1257-2026-07-08.md +77 -0
- package/docs/TB-LEG-GAP-ATTRIBUTION-1261-1263-2026-07-11.md +154 -0
- package/docs/TB-REGRESSION-DAEMON-KILL-2026-07-08.md +58 -0
- package/docs/TB-RSI-CROSSCHECK-2026-07-06.md +68 -0
- package/docs/TB-RSI-LEDGER.md +30 -0
- package/docs/TB-STABLE-SET-2026-07-08.md +127 -0
- package/docs/TB21-RECON-2026-07-11.md +28 -0
- package/docs/TEST-DESIGN-BATCH-1-2-3.md +97 -0
- package/docs/THIRD-PARTY-INTEGRATION.md +45 -0
- package/docs/TOKEN-ESTIMATE-CALIBRATION-LIVE-2026-07-09.md +102 -0
- package/docs/audit-2026-06-10-/347/254/254/344/272/214/350/275/256-/347/251/272/347/231/275/345/214/272/344/270/216/345/277/230/346/216/245/347/272/277.md +147 -0
- package/docs/audit-2026-06-10-/350/256/241/347/256/227bug/346/211/253/346/217/217.md +163 -0
- package/docs/audit-2026-06-11-/344/277/256/345/244/215/345/244/215/345/256/241/344/270/216/345/233/236/345/275/222/344/270/223/346/211/253.md +95 -0
- package/docs/audit-2026-06-12-design71-P1/346/275/234/344/274/217/351/235/242/350/243/201/345/206/263/344/270/216/345/220/236/351/224/231/345/256/241/350/256/241.md +45 -0
- package/docs/audit-2026-06-12-/345/205/254/345/274/200/346/227/213/351/222/256/346/264/273/346/200/247/344/270/216vendored/346/255/273/350/267/257.md +63 -0
- package/docs/audit-2026-06-15/ADDENDUM-second-pass.md +88 -0
- package/docs/audit-2026-06-15/ARCHITECTURE-AND-ROADMAP.md +187 -0
- package/docs/audit-2026-06-15/DOC-CORRECTIONS.md +105 -0
- package/docs/audit-2026-06-15/INDEX.md +49 -0
- package/docs/audit-2026-06-15/ORCHESTRATION-STATUS.md +98 -0
- package/docs/audit-2026-06-15/PRODUCTION-ISSUES.md +189 -0
- package/docs/audit-2026-06-15/REFERENCES-literature.md +139 -0
- package/docs/audit-2026-06-15/VENDOR-REFACTOR-PLAN.md +96 -0
- package/docs/cc-probe-198/README.md +72 -0
- package/docs/cc-probe-198/STABILITY-AUDIT.md +118 -0
- package/docs/cc-probe-198/live-schema-monitor-worktree-2026-07-09.json +56 -0
- package/docs/cc-probe-198/mount-variants.json +536 -0
- package/docs/cc-probe-198/plan-mode-run.json +1 -0
- package/docs/cc-probe-198/probe-bash-bg.json +224 -0
- package/docs/cc-probe-198/probe-edit-mismatch.json +120 -0
- package/docs/cc-probe-198/probe-read-missing.json +62 -0
- package/docs/cc-probe-198/probe-search-empty.json +127 -0
- package/docs/cc-probe-198/probe-task-family.json +227 -0
- package/docs/cc-probe-198/probes.status +6 -0
- package/docs/cc-probe-198/raw-capture-interactive.json +948 -0
- package/docs/cc-probe-198/raw-capture-print.json +787 -0
- package/docs/cc-probe-198/raw-capture2-interactive.json +948 -0
- package/docs/cc-probe-198/raw-capture2-print.json +787 -0
- package/docs/cc-probe-198/system-prompt.txt +135 -0
- package/docs/cc-probe-198/tools-array.json +962 -0
- package/docs/durability-boundary.md +63 -0
- package/docs/fix-2026-06-10-/350/256/241/347/256/227bug/344/277/256/345/244/215-search/346/211/271.md +75 -0
- package/docs/fix-2026-06-11-/347/254/254/344/272/214/350/275/256-/344/277/256/345/244/215-search/346/211/271.md +62 -0
- package/docs/parity-sweep/REPORT-DYNAMIC.md +97 -0
- package/docs/parity-sweep/REPORT-STATIC-GGB.md +127 -0
- package/docs/parity-sweep/REPORT-STATIC-RWE.md +133 -0
- package/docs/vendor-history.md +385 -0
- package/docs/vendored-upstream-diff-2026-07.md +83 -0
- package/package.json +70 -0
|
@@ -0,0 +1,1101 @@
|
|
|
1
|
+
import type { ReadEntry } from "../tools/fs/safety.js";
|
|
2
|
+
import type { RepairBundle } from "../agents/repair-loop.js";
|
|
3
|
+
import type { WorkspaceHandle } from "./remote-env.js";
|
|
4
|
+
import type { ConsolidationNote } from "./runner/memory-consolidation.js";
|
|
5
|
+
import type { TaskResult } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* design/45 — the **durable-checkpoint** primitive: cross-process / resumable `suspend`/`resume`.
|
|
8
|
+
*
|
|
9
|
+
* A {@link CheckpointStore} is the third pluggable durable seam (alongside `ToolResultStore` and
|
|
10
|
+
* `MemoryStore`): a token-addressable store of "enough state to resume a suspended task", with an
|
|
11
|
+
* **atomic CAS `resolve`** so a token is acted on **exactly once** even across replicas / double
|
|
12
|
+
* approvals. Two profiles share this one seam (design/43 原语 4, proven by two service instances):
|
|
13
|
+
*
|
|
14
|
+
* - **F4** (`gate.kind === "human"`) — a running task hit a tool-policy `ask` that no in-process
|
|
15
|
+
* approver can answer (headless / long / cross-replica), so it persists a checkpoint and returns
|
|
16
|
+
* `status:"suspended"`. Later `runner.resume(token, {gate:"policy_ask", decision})` continues it.
|
|
17
|
+
* This is the cross-process version of the synchronous `onAsk` gate (design/37).
|
|
18
|
+
* - **1C** (`gate.kind === "task_done"`) — design/38 Path A persists a background sub-task handle here
|
|
19
|
+
* so a caller can `get` its outcome across replicas. v1 stores the handle only; the parent does NOT
|
|
20
|
+
* mid-task suspend (Path A unchanged) — `runner.resume()` does NOT serve this gate in v1.
|
|
21
|
+
*
|
|
22
|
+
* **opt-in, default-off**: with no `CheckpointStore` wired (and no durable approval mode requested), a
|
|
23
|
+
* policy `ask` still resolves the 1.63 way (synchronous `onAsk` / headless auto-deny) — behavior
|
|
24
|
+
* unchanged. Default {@link InMemoryCheckpointStore} is process-only (single instance / tests); a
|
|
25
|
+
* durable backend (service's `tidb-approval-store` / `tidb-run-store`) makes it cross-replica.
|
|
26
|
+
*
|
|
27
|
+
* See `design/45-durable-checkpoint原语-suspend-resume.md`.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* A high-entropy, single-use checkpoint token. Branded so it can't be confused with a `sessionId` /
|
|
31
|
+
* `taskId` (council Question #2): the token doubles as the resume capability (token-as-auth, §6), so a
|
|
32
|
+
* mix-up would be a security bug, not just a type slip. Mint with {@link mintCheckpointToken}.
|
|
33
|
+
*/
|
|
34
|
+
export type CheckpointToken = string & {
|
|
35
|
+
readonly __brand: "CheckpointToken";
|
|
36
|
+
};
|
|
37
|
+
/** Mint a CSPRNG 128-bit checkpoint token (token-as-auth, §6/Q5): unguessable, never logged/in-URL. */
|
|
38
|
+
export declare function mintCheckpointToken(): CheckpointToken;
|
|
39
|
+
/**
|
|
40
|
+
* Who resumes a checkpoint, and how the resume `outcome` is interpreted. The `kind` is the discriminant
|
|
41
|
+
* that {@link ResumeOutcome} must match at the resume entry (council #3: prevents a `task_done` gate
|
|
42
|
+
* being resumed with a `policy_ask` outcome → type confusion / corruption).
|
|
43
|
+
*/
|
|
44
|
+
/** design/74: why a resource-slice suspend fired. `"budget"` covers cost OR tokens (both are checked by
|
|
45
|
+
* `overBudget`); `"walltime"` is the soft slice deadline; `"turns"` the slice turn cap.
|
|
46
|
+
* design/80 Seam #2: `"preempt"` is NOT a resource limit — it is an EXTERNAL scheduler yield (the scheduler
|
|
47
|
+
* raised `spec.preemptSignal` to free resources for a higher-priority task). It rides the SAME durable-suspend
|
|
48
|
+
* mechanism: the gate.kind stays `resource_limit` (the mechanism), so the resume path is byte-identical to a
|
|
49
|
+
* budget/turns/walltime resume (continue the work, no decision); `"preempt"` is only the CAUSE. */
|
|
50
|
+
export type ResourceLimitReason = "budget" | "walltime" | "turns" | "preempt";
|
|
51
|
+
/**
|
|
52
|
+
* design/80 D-2: which SAFETY MARK(s) on the tool caused an `ask` to mint an {@link CheckpointGate}
|
|
53
|
+
* `irreversible_ask`. Derived from the tool's STATIC spec marks (`ToolSpec.egress` / `ToolSpec.irreversibility`,
|
|
54
|
+
* round-1 council fix — NOT the per-call `decisionReason`, which missed a policy/hook pre-ask and was
|
|
55
|
+
* forgeable). Persisted on the gate so a network budget/escalation resolver reads WHY this is a safety ask FROM
|
|
56
|
+
* THE DURABLE RECORD (never re-derives risk from a model-controlled value — the model self-reports nothing
|
|
57
|
+
* here). Both can be true (a tool marked BOTH egress AND irreversible).
|
|
58
|
+
*/
|
|
59
|
+
export interface SafetyAxis {
|
|
60
|
+
/** design/70: the tool is egress-marked (`ToolSpec.egress` — an external write: push, open PR, send). */
|
|
61
|
+
egress?: boolean;
|
|
62
|
+
/** design/77 §4: the tool's irreversibility tier is `always` or `maybe` (`ToolSpec.irreversibility`). */
|
|
63
|
+
irreversible?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* design/80 §D-E: a DETERMINISTIC, REDACTED risk summary attached AT MINT to an escalation
|
|
67
|
+
* {@link CheckpointGate} (`human` / `irreversible_ask` — the tool-call approval escalations) so a supervisor
|
|
68
|
+
* INBOX can sort/triage by TRUE severity without re-deriving risk. **Display/triage metadata ONLY** — core
|
|
69
|
+
* NEVER reads it to gate / budget / suppress anything (structural ask strictly wins via `combinePolicies`;
|
|
70
|
+
* no mint suppression reads it). The profile/inbox READS it; core only ATTACHES it. Pure function of the
|
|
71
|
+
* call (no clock/random) — same call ⇒ identical descriptor.
|
|
72
|
+
*/
|
|
73
|
+
export interface RiskDescriptor {
|
|
74
|
+
/** ToolEmu-style severity tier 1..5 (5 = most severe). The inbox sorts DESC by this. Deterministic — the
|
|
75
|
+
* pure {@link riskSeverity} of {@link axes}. The ORDERING is what matters (the inbox's triage key). */
|
|
76
|
+
severity: 1 | 2 | 3 | 4 | 5;
|
|
77
|
+
/** Which safety axes tripped — for `irreversible_ask`, derived from the D-2 {@link SafetyAxis} (+ the
|
|
78
|
+
* shell-gate). `shell` marks a coarse shellGate tighten (a bash command gated only because the deployment
|
|
79
|
+
* set `shellGate`, with NO explicit per-tool egress/irreversible mark). Empty `{}` for a plain budgetable
|
|
80
|
+
* `human` ask. Self-contained so the inbox needn't cross-ref `safetyAxis`. */
|
|
81
|
+
axes: {
|
|
82
|
+
egress?: boolean;
|
|
83
|
+
irreversible?: boolean;
|
|
84
|
+
shell?: boolean;
|
|
85
|
+
};
|
|
86
|
+
/** The tool whose call is gated (mirrors the gate's `toolName`). */
|
|
87
|
+
toolName: string;
|
|
88
|
+
/** A REDACTED, length-capped ONE-LINE summary of the call (the command for a shell gate; a brief key-arg
|
|
89
|
+
* digest otherwise) for the inbox preview. NEUTRALIZED via {@link import("./untrusted-text.js").inlineUntrusted}
|
|
90
|
+
* + length-capped (it is persisted + shown to a human inbox, so a malicious tool arg carrying a
|
|
91
|
+
* `</system-reminder>` variant / newline / huge string must NOT inject into the render or bloat storage).
|
|
92
|
+
* NEVER raw secrets / full args / env. Deterministic. Optional (omitted when nothing safe to summarize). */
|
|
93
|
+
summary?: string;
|
|
94
|
+
/** Best-effort file paths the action touches (fs-tool `path` args; shell parsing is deliberately NOT
|
|
95
|
+
* attempted — over-reaching a shell parse risks a wrong/forgeable path). Each path `inlineUntrusted`-capped.
|
|
96
|
+
* Omitted when none derivable. */
|
|
97
|
+
touchedPaths?: string[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* design/80 §D-E: the DETERMINISTIC severity tier (1..5) for an escalation checkpoint, a PURE function of the
|
|
101
|
+
* tripped {@link RiskDescriptor.axes} (NO LLM, NO clock/random) so the inbox's sort order is stable and
|
|
102
|
+
* unit-testable in isolation. The ORDERING is the contract; the absolute numbers map to ToolEmu's 5 tiers:
|
|
103
|
+
* - irreversible AND egress → **5** (the most severe — an external, irreversible write)
|
|
104
|
+
* - irreversible only → **4**
|
|
105
|
+
* - egress only → **3**
|
|
106
|
+
* - shell-gated tighten → **3** (a coarse shellGate ask with no explicit egress/irreversible mark — the
|
|
107
|
+
* command MAY be benign, so it is not auto-graded as high as a marked tool)
|
|
108
|
+
* - plain `human` ask → **2** (no safety axis tripped — a budgetable approval)
|
|
109
|
+
* - (1 reserved — least-severe / informational; not expected from these gates.)
|
|
110
|
+
* `egress` dominates the shell coarse-grade (an explicitly egress-marked shell tighten is still ≥3). A future
|
|
111
|
+
* arm may refine this — but only with a stated reason, and the ORDERING must stay monotone in risk.
|
|
112
|
+
*/
|
|
113
|
+
export declare function riskSeverity(axes: {
|
|
114
|
+
egress?: boolean;
|
|
115
|
+
irreversible?: boolean;
|
|
116
|
+
shell?: boolean;
|
|
117
|
+
}): 1 | 2 | 3 | 4 | 5;
|
|
118
|
+
/** design S1e (service [204]): the char cap for the {@link CheckpointSummary.toolInput} BOUNDED raw preview of a
|
|
119
|
+
* `tool_approval` pendingAction's `args` (`JSON.stringify`-ed). Caps the `listByScope` payload size; over-cap
|
|
120
|
+
* is truncated with a trailing `…`. Bounded raw (NOT neutralized) — redaction is the consumer's job (echo-only). */
|
|
121
|
+
export declare const MAX_TOOL_INPUT_PREVIEW_CHARS = 512;
|
|
122
|
+
/**
|
|
123
|
+
* design/80 §D-E: build the DETERMINISTIC, REDACTED {@link RiskDescriptor} for an escalation checkpoint at
|
|
124
|
+
* MINT. Pure — a function ONLY of (`toolName`, `args`, the D-2 `safety` axis, the `shellGated` flag); it reads
|
|
125
|
+
* NO clock/random, so the SAME call ⇒ an IDENTICAL descriptor (pinned by a test).
|
|
126
|
+
*
|
|
127
|
+
* **Determinism contract = plain-DATA args** (the real flow: model-JSON / hook-rewritten plain objects). A
|
|
128
|
+
* Proxy whose `ownKeys` trap returns a DIFFERENT key set per call is OUT OF CONTRACT — JS cannot detect a Proxy
|
|
129
|
+
* (codex review Item 2), so its (display-only) digest may vary. This NEVER affects a security/budget/mint
|
|
130
|
+
* decision: `riskDescriptor` is INERT (no core path reads it to gate), so an out-of-contract input can at worst
|
|
131
|
+
* degrade an inbox preview, never a permission outcome.
|
|
132
|
+
*
|
|
133
|
+
* **Redaction is load-bearing** (the `summary`/`touchedPaths` are PERSISTED + surfaced to a human inbox):
|
|
134
|
+
* every model-controlled value goes through {@link inlineUntrusted} (folds CR/LF/Unicode separators to one
|
|
135
|
+
* space, defuses `</system-reminder>` variants + `<<<`/`>>>` fence sentinels) AND a length cap, so a
|
|
136
|
+
* malicious arg carrying a break-out tag / newline / huge string can neither inject into the inbox render nor
|
|
137
|
+
* bloat the durable row. NEVER dumps full args / env / secrets — only a bash command string or a short
|
|
138
|
+
* `name=value` digest of the SHOWN args.
|
|
139
|
+
*
|
|
140
|
+
* `summary` for a shell gate = the `command` string (capped 200 cp); otherwise a `name=value` digest of the
|
|
141
|
+
* call's top-level string/number/boolean args (each value capped), omitted when nothing safe to summarize.
|
|
142
|
+
* `touchedPaths` reads ONLY the obvious fs `path` arg (read_file/edit_file/write_file) — shell parsing is
|
|
143
|
+
* deliberately NOT attempted (over-reaching a shell parse risks a wrong/forgeable path, so OMIT for bash).
|
|
144
|
+
*/
|
|
145
|
+
export declare function buildRiskDescriptor(input: {
|
|
146
|
+
toolName: string;
|
|
147
|
+
args: unknown;
|
|
148
|
+
/** The D-2 {@link SafetyAxis} threaded to the mint (egress/irreversible), or `undefined` for a plain ask. */
|
|
149
|
+
safety?: SafetyAxis;
|
|
150
|
+
/** True ONLY when this is a `bash` call gated coarsely by `shellGate` (no explicit per-tool egress/irreversible
|
|
151
|
+
* mark) — drives the `shell` axis + severity-3 coarse grade. */
|
|
152
|
+
shellGated?: boolean;
|
|
153
|
+
}): RiskDescriptor;
|
|
154
|
+
export type CheckpointGate =
|
|
155
|
+
/** F4: a human (or any external authority) must allow/deny a pending tool call. design/80 §D-E:
|
|
156
|
+
* carries an OPTIONAL display-only {@link RiskDescriptor} (severity/axes/summary) for the supervisor
|
|
157
|
+
* inbox to triage by — INERT (core never reads it to gate/budget). */
|
|
158
|
+
{
|
|
159
|
+
kind: "human";
|
|
160
|
+
reason: string;
|
|
161
|
+
toolName: string;
|
|
162
|
+
riskDescriptor?: RiskDescriptor;
|
|
163
|
+
}
|
|
164
|
+
/** design/77 §4 (Gate 4) + design/80 D-2: a PRE-ACTION human approval before a SAFETY-tightened tool runs —
|
|
165
|
+
* an IRREVERSIBLE tool (send money/email, file a return) OR an EGRESS tool (push, open PR, send). Same
|
|
166
|
+
* approval family as `human` (a pending tool call to allow/deny → suspendRef → `status:"suspended"`, resumed
|
|
167
|
+
* with a `policy_ask` outcome). **design/80 D-2 (load-bearing):** minted whenever an `ask` is for a tool
|
|
168
|
+
* carrying the egress / irreversibility (`always`/`maybe`) SAFETY MARKS — regardless of how the ask arose
|
|
169
|
+
* (a gate tighten OR a policy/hook that already asked; round-1 council fix: keying on the per-call
|
|
170
|
+
* `decisionReason` missed the policy-ask case AND was forgeable) — **EVEN WHEN `durableApproval` is wired**
|
|
171
|
+
* (`durableApproval` supplies scope/ttl, NOT the kind). The DISJOINT-from-`human` kind is what a
|
|
172
|
+
* network budget resolver keys on to NEVER auto-approve a safety ask (a budget may only down-budget a plain
|
|
173
|
+
* `human` ask). {@link SafetyAxis} records which axis(es) tightened. NOT a dry-run review. */
|
|
174
|
+
| {
|
|
175
|
+
kind: "irreversible_ask";
|
|
176
|
+
reason: string;
|
|
177
|
+
toolName: string;
|
|
178
|
+
safetyAxis?: SafetyAxis;
|
|
179
|
+
riskDescriptor?: RiskDescriptor;
|
|
180
|
+
}
|
|
181
|
+
/** design/74: a resource slice limit (budget/walltime/turns) was reached — suspend (resumable) instead of
|
|
182
|
+
* fail. There is NO pending tool to adjudicate; resume just continues the run with the next slice's
|
|
183
|
+
* allowance (sized from {@link Checkpoint.resourceLedger}). The matching {@link ResumeOutcome} arm is
|
|
184
|
+
* `{ gate: "resource_limit"; decision: "continue" }`. */
|
|
185
|
+
| {
|
|
186
|
+
kind: "resource_limit";
|
|
187
|
+
reason: ResourceLimitReason;
|
|
188
|
+
}
|
|
189
|
+
/** design/76 §2.5 (dry-run / shadow): a POST-PREDICTION REVIEW pause. A profile's dry-run interception ran a
|
|
190
|
+
* predicted action and produced a buffered state-diff a human (or judge) must REVIEW before it is applied —
|
|
191
|
+
* so the task suspends to the durable `needs_review` TERMINAL (`TaskStatus:"needs_review"`) instead of
|
|
192
|
+
* finishing. **DISJOINT from the approval family** (`human`/`irreversible_ask`): those are PRE-ACTION
|
|
193
|
+
* *approvals* (suspendRef → `status:"suspended"`, resumed with a `policy_ask` outcome); this is a
|
|
194
|
+
* POST-prediction *review* (reviewRef → `status:"needs_review"`, resumed with a `dry_run_review` outcome).
|
|
195
|
+
* The split is load-bearing — reusing the approval family would make assemble-result report `"suspended"`
|
|
196
|
+
* and the `needs_review`/`review.pending` branch dead code (v4 MAJOR-A). It is ALSO disjoint from the
|
|
197
|
+
* `RepairTerminal.needs_human_oracle` (design/78) — a different type space; never cross-use the two.
|
|
198
|
+
* The state-diff itself is a PROFILE concern (a REF, not stored here — design/76 §9 / §2.5); core only
|
|
199
|
+
* owns the gate/status/discriminant plumbing. NOT a pre-action approval. */
|
|
200
|
+
| {
|
|
201
|
+
kind: "needs_review";
|
|
202
|
+
reason: string;
|
|
203
|
+
}
|
|
204
|
+
/** design/80 D-B (plan-gate): a PRE-ACTION human PLAN REVIEW. Before an agent acts on a high-blast-radius
|
|
205
|
+
* plan (a profile's plan-gate fires on shell⇒gate + an irreversible/egress/finance mark present + a
|
|
206
|
+
* blast-radius trigger — NOT every task), the run pauses so a human can **approve / edit / reject the
|
|
207
|
+
* proposed PLAN** before any step runs. It is its OWN gate kind (r2 ruling — do NOT reuse `needs_review`,
|
|
208
|
+
* whose gateMatch arm forces a `dry_run_review` outcome; reusing it would make a plan resume a
|
|
209
|
+
* type-confusion mismatch), but it shares the **review-pause** machinery: it routes to `reviewRef` +
|
|
210
|
+
* `status:"needs_review"` (a human-review pause), resumed with a `plan_review` outcome.
|
|
211
|
+
*
|
|
212
|
+
* **THREE-WAY SPLIT (load-bearing):**
|
|
213
|
+
* - the APPROVAL family (`human`/`irreversible_ask`) → PRE-ACTION *approvals* of a pending TOOL CALL
|
|
214
|
+
* (suspendRef → `status:"suspended"`, resumed with a `policy_ask` outcome bound to a tool call);
|
|
215
|
+
* - `needs_review` → a POST-prediction *review* of a buffered state-diff (reviewRef →
|
|
216
|
+
* `status:"needs_review"`, resumed with a `dry_run_review` outcome);
|
|
217
|
+
* - `plan_review` (this) → a PRE-ACTION *review* of a PLAN (reviewRef → `status:"needs_review"`, resumed
|
|
218
|
+
* with a `plan_review` outcome). It binds NO tool call — the human reviews the PLAN, not a pending arg —
|
|
219
|
+
* so it carries no `tool_approval` pendingAction (its pendingAction is `{kind:"plan_review"}`, with no
|
|
220
|
+
* tool fields) and the `policy_ask` decision-action binding machinery never touches it. The plan/diff
|
|
221
|
+
* artifact is a PROFILE concern (a REF, not stored here — design/76 §9); core owns the
|
|
222
|
+
* gate/status/discriminant plumbing only. NOT a pre-action approval, NOT a dry-run review. */
|
|
223
|
+
| {
|
|
224
|
+
kind: "plan_review";
|
|
225
|
+
reason: string;
|
|
226
|
+
}
|
|
227
|
+
/** 1C: the checkpoint tracks a background sub-task's completion (design/38 Path A). v1 = handle only. */
|
|
228
|
+
| {
|
|
229
|
+
kind: "task_done";
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* The outcome a caller supplies to `runner.resume(token, outcome)` — a **discriminated union** keyed by
|
|
233
|
+
* `gate`, validated against `checkpoint.gate.kind` at the entry (council #3). **v1 implements only the
|
|
234
|
+
* `policy_ask` arm**: `task_done` is a dead branch under 1C Path A (the caller orchestrates, never
|
|
235
|
+
* mid-task `resume()`), typed here for completeness and the v2 join-suspend option.
|
|
236
|
+
*/
|
|
237
|
+
export type ResumeOutcome = {
|
|
238
|
+
gate: "policy_ask";
|
|
239
|
+
/**
|
|
240
|
+
* design/80 D-1 (decision-action binding): the `toolCallId` the human actually saw/approved. The
|
|
241
|
+
* resume is REJECTED (`checkpoint.invalid_outcome`, fail-closed, pre-CAS) unless it matches the
|
|
242
|
+
* checkpoint's pending tool call (`pendingAction.toolCallId`) — this closes the TOCTOU re-suspend
|
|
243
|
+
* wrong-apply: a stale `yes` minted against pending call X must not resolve a DIFFERENT pending call
|
|
244
|
+
* Y (approve vendor-A $5k applied to vendor-B). The decision must name the action it bound to; the
|
|
245
|
+
* runner never trusts that the caller matched the correct pending call (design/77 doctrine —
|
|
246
|
+
* deterministic structural backstop, not a model self-report).
|
|
247
|
+
*
|
|
248
|
+
* The correct value is the resumed checkpoint's `pendingAction.toolCallId`; the caller has it via the
|
|
249
|
+
* `suspendRef` / pending record it is answering.
|
|
250
|
+
*/
|
|
251
|
+
boundCallId: string;
|
|
252
|
+
/**
|
|
253
|
+
* design/80 D-1 §2 (slice 1a.2): the **server-minted opaque** hash of the pending tool call's input
|
|
254
|
+
* that the human actually saw/approved (`PendingAction.tool_approval.boundInputHash`, computed by the
|
|
255
|
+
* engine at suspend-mint via {@link import("./canonical-json.js").boundInputHashOf} over the post-hook
|
|
256
|
+
* `args`). The caller echoes it VERBATIM — it is opaque; the SDK/service NEVER re-canonicalize args
|
|
257
|
+
* (red-team r3: a second runtime's serialization could diverge → false mismatch → fail-closed a
|
|
258
|
+
* legitimate approval). The resume verifies it by **string equality** against the checkpoint's
|
|
259
|
+
* persisted value (`checkpoint.invalid_outcome`, fail-closed, pre-CAS) — closing the TOCTOU "same call
|
|
260
|
+
* id, different input" variant that `boundCallId` alone misses (a re-mint that swapped the input under
|
|
261
|
+
* the same tool-call id). It binds the SHOWN input, NOT `updatedInput`: an `allow` edit is the same
|
|
262
|
+
* operator's authorized rewrite, applied AFTER this binding check (design/37,末位应用), so the echoed
|
|
263
|
+
* hash is always the pending record's value regardless of any edit. (Legacy pre-1a.2 checkpoints have
|
|
264
|
+
* no persisted hash → the resume skips this check, binding on `boundCallId` alone; new mints enforce.)
|
|
265
|
+
*/
|
|
266
|
+
boundInputHash: string;
|
|
267
|
+
/** `allow` → execute the pending tool call; `deny` → inject a denial result and continue. */
|
|
268
|
+
decision: "allow" | "deny";
|
|
269
|
+
/** A re-written arg payload (design/37 policy `allow` rewrite); re-validated on execute. */
|
|
270
|
+
updatedInput?: unknown;
|
|
271
|
+
/** Model-readable reason attached to a `deny` (else a default is used). */
|
|
272
|
+
reason?: string;
|
|
273
|
+
}
|
|
274
|
+
/** design/74: continue a resource-suspended run with the next slice's allowance. NO decision payload and
|
|
275
|
+
* NO budget figure — the allowance is computed from {@link Checkpoint.resourceLedger}, so money never
|
|
276
|
+
* reaches the caller or the model. Matches `CheckpointGate.kind === "resource_limit"`. */
|
|
277
|
+
| {
|
|
278
|
+
gate: "resource_limit";
|
|
279
|
+
decision: "continue";
|
|
280
|
+
}
|
|
281
|
+
/** design/76 §2.5 (dry-run / shadow): resolve a `needs_review` suspend after a human/judge reviewed the
|
|
282
|
+
* buffered predicted state-diff. `decision:"approve"` → the profile applies the buffered diff (atomically,
|
|
283
|
+
* invalidating `readFileState` on touched paths — design/76 §2.5; the apply itself is PROFILE, not core)
|
|
284
|
+
* then continues; `decision:"reject"` → the prediction is discarded and the run continues without it. Kept
|
|
285
|
+
* DISJOINT from `policy_ask` (the approval family) so the resume-side discriminant never confuses a
|
|
286
|
+
* post-prediction review with a pre-action approval (the third `needs_review`/`dry_run_review` gateMatch arm).
|
|
287
|
+
* No money/diff payload reaches the caller here — the diff lives in the profile's REF store (design/76 §9). */
|
|
288
|
+
| {
|
|
289
|
+
gate: "dry_run_review";
|
|
290
|
+
decision: "approve" | "reject";
|
|
291
|
+
reason?: string;
|
|
292
|
+
}
|
|
293
|
+
/** design/80 D-B (plan-gate): resolve a `plan_review` PRE-ACTION plan pause after a human reviewed the
|
|
294
|
+
* proposed PLAN. `decision:"approve"` → proceed with the plan as-is; `decision:"edit"` → proceed with the
|
|
295
|
+
* human's `editedPlan` (a TYPED sibling of the plan — NEVER a raw tool `updatedInput`; a plan is not a tool
|
|
296
|
+
* arg, so this binds NO action and never enters the `policy_ask` boundCallId/boundInputHash machinery);
|
|
297
|
+
* `decision:"reject"` → the model RE-PLANS (the rejected plan is discarded; a `reason` may steer the
|
|
298
|
+
* re-plan). Kept DISJOINT from `policy_ask` (approval) AND `dry_run_review` (post-prediction review) so the
|
|
299
|
+
* resume-side discriminant never confuses the three (the `plan_review`/`plan_review` gateMatch arm). Like
|
|
300
|
+
* the other non-`policy_ask` outcomes it **binds to no action** (winnerFromOutcome → undefined); the
|
|
301
|
+
* `resolvedOutcome`/binding machinery is for `policy_ask` only. No plan/diff payload (beyond the human's
|
|
302
|
+
* `editedPlan` text) reaches core — the plan artifact lives in the PROFILE's REF store (design/76 §9). */
|
|
303
|
+
| {
|
|
304
|
+
gate: "plan_review";
|
|
305
|
+
decision: "approve" | "edit" | "reject";
|
|
306
|
+
editedPlan?: string;
|
|
307
|
+
reason?: string;
|
|
308
|
+
} | {
|
|
309
|
+
gate: "task_done";
|
|
310
|
+
result: TaskResult;
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* The pending action a checkpoint suspends *before* — a **discriminated union** keyed by `kind`. Every
|
|
314
|
+
* consumer that reads the tool fields MUST branch on `kind` first: the `resource_limit` arm (design/74)
|
|
315
|
+
* has none (a resource slice suspend has no pending tool to resolve).
|
|
316
|
+
*
|
|
317
|
+
* `tool_approval` (§4): a tool call adjudicated `ask` in durable mode, captured with its **post-hook args**
|
|
318
|
+
* (the design/37 rewrite already applied) so resume executes the exact same call without re-running
|
|
319
|
+
* PreToolUse hooks (§11 M2). `batchToolCallIds` / `completedCallIds` capture the **mid-batch** position
|
|
320
|
+
* (§4.ter): one assistant turn can emit a batch of tool calls; if call #k hits `ask`, calls #1..k-1 already
|
|
321
|
+
* executed (in `completedCallIds`) and #k+1..N are still pending. ID-based (a `Set<toolCallId>`), not
|
|
322
|
+
* positional — immune to reordering / off-by-one (council Question #1), and it doubles as the reconcile
|
|
323
|
+
* suspended-batch discriminant (§15.2 net-add #7) so wake-reconcile never closes a suspended call.
|
|
324
|
+
*/
|
|
325
|
+
export type PendingAction = {
|
|
326
|
+
kind: "tool_approval";
|
|
327
|
+
toolCallId: string;
|
|
328
|
+
toolName: string;
|
|
329
|
+
/** Post-hook (design/37-rewritten) args to execute on `allow`. */
|
|
330
|
+
args: unknown;
|
|
331
|
+
/**
|
|
332
|
+
* design/80 D-1 §2 (slice 1a.2): the server-minted **opaque** boundInputHash of {@link args} — a
|
|
333
|
+
* SHA-256 (hex) via {@link import("./canonical-json.js").boundInputHashOf}, computed ONCE here at
|
|
334
|
+
* suspend-mint and persisted on the row. The operator sees it (surfaced on the pending record) and
|
|
335
|
+
* echoes it back as {@link ResumeOutcome} `boundInputHash`; the resume verifies opaque string equality
|
|
336
|
+
* against THIS value (never re-serializing the args — see the field's doc). Absent only on a legacy
|
|
337
|
+
* pre-1a.2 checkpoint (deserialized without it), in which case the resume skips the hash check.
|
|
338
|
+
*/
|
|
339
|
+
boundInputHash: string;
|
|
340
|
+
/** All tool-call ids in the suspending assistant message, in emission order. */
|
|
341
|
+
batchToolCallIds: string[];
|
|
342
|
+
/** Ids of calls already executed (results in the session) when the suspend fired — #1..k-1. */
|
|
343
|
+
completedCallIds: string[];
|
|
344
|
+
}
|
|
345
|
+
/** design/74: suspended at a resource slice boundary — there is NO pending tool to resolve. Consumers
|
|
346
|
+
* that read the tool-approval fields above MUST branch on `kind` first (this arm has none). */
|
|
347
|
+
| {
|
|
348
|
+
kind: "resource_limit";
|
|
349
|
+
reason: ResourceLimitReason;
|
|
350
|
+
}
|
|
351
|
+
/** design/80 D-B (r3 — an EXPLICIT arm, NOT a reused `resource_limit` placeholder): paused at a PRE-ACTION
|
|
352
|
+
* PLAN REVIEW (`CheckpointGate.kind === "plan_review"`). There is NO pending tool to resolve — the human
|
|
353
|
+
* reviews the PLAN, not a tool call — so this arm has no tool fields. Every consumer that reads the
|
|
354
|
+
* `tool_approval` fields above MUST branch on `kind` FIRST: a `plan_review` checkpoint must never flow into
|
|
355
|
+
* a `resource_limit`- or `tool_approval`-shaped continuation (a contract test pins this). The plan artifact
|
|
356
|
+
* is a PROFILE concern (a REF — design/76 §9); core stores no plan here. */
|
|
357
|
+
| {
|
|
358
|
+
kind: "plan_review";
|
|
359
|
+
};
|
|
360
|
+
/**
|
|
361
|
+
* The per-task correctness state a checkpoint must carry so a resumed task runs in the **same state
|
|
362
|
+
* space** it suspended in (§4.bis, the jury head must-fix). An **explicit whitelist** of serializable
|
|
363
|
+
* correctness fields — never a blind `JSON.stringify(Prepared)`, which would silently corrupt the 9+
|
|
364
|
+
* non-serializable runtime objects (`harness`/`session`/`abortController`…) it holds (round-2 BUG#1).
|
|
365
|
+
*
|
|
366
|
+
* Round-trip fidelity of every field is covered by tests; runtime objects are **forbidden** here.
|
|
367
|
+
* `cacheFingerprint` (design/31) is deliberately **excluded** — it is observation-only, so resume just
|
|
368
|
+
* suppresses cache-break detection on the first turn rather than persisting it as correctness state.
|
|
369
|
+
*/
|
|
370
|
+
export interface CheckpointState {
|
|
371
|
+
/** design/36: deferred-tool activation set — else resume re-discloses / diverges from history. */
|
|
372
|
+
activeTools: string[];
|
|
373
|
+
/** 1.41 submit_output: the validated structured output set pre-suspend, else it's lost on resume. */
|
|
374
|
+
outputRef?: {
|
|
375
|
+
value?: unknown;
|
|
376
|
+
set?: boolean;
|
|
377
|
+
};
|
|
378
|
+
/** design/38: nested sub-agent cumulative cost — else pre-suspend child cost evaporates (§4.bis/Q7). */
|
|
379
|
+
nestedStats: {
|
|
380
|
+
tokens: number;
|
|
381
|
+
turns: number;
|
|
382
|
+
tasks: number;
|
|
383
|
+
costUsd: number;
|
|
384
|
+
costMicroUsd: number;
|
|
385
|
+
};
|
|
386
|
+
/** design/41: consolidation notes collected pre-suspend — else the task-end pass loses them. */
|
|
387
|
+
consolidationNotes?: ConsolidationNote[];
|
|
388
|
+
/** design/44: the hand's read-file state (content hashes), serialized from the hands-toolkit closure
|
|
389
|
+
* (NOT part of Prepared — §15.2 net-add #8). Without it a resumed `edit_file` is rejected "not read". */
|
|
390
|
+
readFileState?: Array<[string, ReadEntry]>;
|
|
391
|
+
/**
|
|
392
|
+
* design/78 Slice-1: the SAFE-tier self-repair loop's durable state (`failureTrace`/`diagnostics`/
|
|
393
|
+
* `rejectedHypotheses`/`attemptCount`/`oracleTier` — all JSON/`structuredClone`-safe, no fn/Date). Set ONLY
|
|
394
|
+
* when an orthogonal durable suspend (resource/HITL) interleaves a `runRepairLoop` run — the happy path is
|
|
395
|
+
* in-memory only. On resume it re-seeds `RepairLoopConfig.resumeBundle` so `attemptCount` advances
|
|
396
|
+
* MONOTONICALLY (never reset). `baselinePassTests` is deliberately NOT carried here (grader-computed
|
|
397
|
+
* out-of-process — a worker must not be able to shrink the ratchet). Absent for a run with no repair loop.
|
|
398
|
+
*/
|
|
399
|
+
repairBundle?: RepairBundle;
|
|
400
|
+
/**
|
|
401
|
+
* design/49 v1.5: the remote workspace's serializable identity (E2B sandbox id / provider / mount path /
|
|
402
|
+
* snapshot id). Set ONLY when the suspended task ran with a remote, suspendable {@link WorkspaceHandle}
|
|
403
|
+
* (a per-task `executionEnvFactory` env that was `suspendVM()`-paused rather than destroyed). Resume
|
|
404
|
+
* rebuilds the env via the factory and `resumeVM(snapshotId)` so the restored workspace matches the
|
|
405
|
+
* `readFileState` above. All-string fields → JSON/`structuredClone` round-trips safely (consistent with
|
|
406
|
+
* this whitelist's "no runtime objects" rule). Absent for a process-local (non-remote) suspend.
|
|
407
|
+
*/
|
|
408
|
+
workspaceHandle?: WorkspaceHandle;
|
|
409
|
+
/**
|
|
410
|
+
* design/80 D-A: a durable mid-task STEER for a DURABLY-SUSPENDED task. Live `TaskStream.steer`
|
|
411
|
+
* (runtask.ts) is unreachable while the harness is idle (durably suspended), so a human supervisor's
|
|
412
|
+
* guidance is parked HERE via {@link CheckpointStore.setPendingSteer} and injected on resume (runtask.ts,
|
|
413
|
+
* after the resume-continuation prompt). It is GUIDANCE ONLY — never an approval channel (§3 inv #4) and
|
|
414
|
+
* never parsed into control state (§3 inv #5); a budget/autonomy/gate-threshold is CONFIG, not steer text.
|
|
415
|
+
*
|
|
416
|
+
* `trusted` is FROZEN at `setPendingSteer` from the SERVICE's verified-principal check (an operator-role
|
|
417
|
+
* check, NOT a client header — the service's job, out of scope here) and NEVER recomputed on resume
|
|
418
|
+
* (§3 inv #1). On resume a `trusted:false` steer reaches the model as a PLAIN user message with NO
|
|
419
|
+
* `<system-reminder>` wrapper (no authority laundering, §3 inv #3); a `trusted:true` steer MAY ride the
|
|
420
|
+
* reminder (`formatHookFeedback`, mirroring the live trusted branch). `text` containing `</system-reminder>`
|
|
421
|
+
* is REJECTED at `setPendingSteer` (typed `steering.invalid_content`) so a dirty steer never enters this
|
|
422
|
+
* state (§3 inv #2); the untrusted-injection path ALSO sanitizes the text as untrusted data, belt-and-braces.
|
|
423
|
+
* Absent when no steer is pending. All-string fields → JSON/`structuredClone` round-trips safely.
|
|
424
|
+
*
|
|
425
|
+
* **Delivery is BEST-EFFORT, at-most-meaningfully-once (review-council, by design):** a steer is GUIDANCE,
|
|
426
|
+
* not a correctness-critical message, so the delivery guarantee is intentionally loose:
|
|
427
|
+
* - It rides EVERY resume of THIS checkpoint that runs a turn — including a faithful `env_failed`/
|
|
428
|
+
* `tool_unavailable` reopen→re-resume, which re-shows the guidance (coherent with the reopen REPLAYING the
|
|
429
|
+
* leg; the model re-does the work, re-seeing the steer). It is NOT carried onto a NEW re-suspend checkpoint
|
|
430
|
+
* (serializeCheckpointState stamps `undefined`) — a supervisor steers the new checkpoint afresh.
|
|
431
|
+
* - It is DROPPED (never delivered) on a resume that runs no turn (an exhausted-budget resume) or that is
|
|
432
|
+
* set in the get→resolve race window of an in-flight resume — both rare; the run is ending or the steer
|
|
433
|
+
* just missed its train. A supervisor re-issues `setPendingSteer` if a steer didn't land.
|
|
434
|
+
* A precise exactly-once delivery would need clearing the steer from the persisted row on consume (a reopen
|
|
435
|
+
* clear + a get→resolve interlock); deferred as not worth the cross-backend complexity for guidance text.
|
|
436
|
+
*/
|
|
437
|
+
pendingSteer?: {
|
|
438
|
+
text: string;
|
|
439
|
+
trusted: boolean;
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* SR-7 (CC 2.1.198 orphaned-background-task notice: F6c pretty.js:698391-698398, resume leg
|
|
443
|
+
* :707384-707399 under the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` gate — the cloud-worker restart
|
|
444
|
+
* leg, exactly sema's durable-resume shape): the background tasks (pending/running, this run's
|
|
445
|
+
* owner triple) still ALIVE at suspend. Background processes never survive a suspend (design/103
|
|
446
|
+
* §3.7 unconditional dispose + 飞轮 [506]③ killed receipts), so on resume any snapshot entry NOT
|
|
447
|
+
* alive in the resume leg's registry is an ORPHAN — aggregated into ONE CC-verbatim "The container
|
|
448
|
+
* was restarted…" reminder appended to the resume continuation (single message: header +
|
|
449
|
+
* `- description (task id)` list + re-create instruction; never a per-task barrage). A survivor
|
|
450
|
+
* (session-resident shell / in-window monitor) is excluded — still reachable via TaskOutput/
|
|
451
|
+
* TaskStop, it needs no obituary. CC's per-orphan `Ku(task_id,"stopped")` status write (:707399)
|
|
452
|
+
* is N/A here: the suspend teardown already settled them killed with receipts. Absent for a run
|
|
453
|
+
* with no live background tasks at suspend, and for pre-1.262 checkpoints (deserialized without
|
|
454
|
+
* the field) — both resume silently, exactly like CC with an empty list.
|
|
455
|
+
*/
|
|
456
|
+
runningBackgroundTasks?: Array<{
|
|
457
|
+
id: string;
|
|
458
|
+
description?: string;
|
|
459
|
+
}>;
|
|
460
|
+
/**
|
|
461
|
+
* codex 终审 1.255 F2: the hands band's LOGICAL working directory at suspend (`handsCwdRef.current` —
|
|
462
|
+
* moved by `cd` and by EnterWorktree). Without it a resume silently reset the task cwd to the task root:
|
|
463
|
+
* relative Read/Edit/Write paths and Bash commands then operated somewhere else than the model believes.
|
|
464
|
+
* Absent when the task has no tracked cwd (no real shell / read-only hands). The directory itself is
|
|
465
|
+
* plain on-disk state that survives a process-local suspend (worktrees included — the tree stays on disk).
|
|
466
|
+
*/
|
|
467
|
+
handsCwd?: string;
|
|
468
|
+
/**
|
|
469
|
+
* codex 终审 1.255 F2: the ACTIVE EnterWorktree session at suspend (worktree.ts keeps it in a shared
|
|
470
|
+
* serializable ref, not a closure-only var, precisely so it lands here). Without it a resume LOST the
|
|
471
|
+
* session: ExitWorktree became a no-op (the unchanged worktree could never be removed), a second
|
|
472
|
+
* EnterWorktree was wrongly accepted, and `handsCwd` pointed into a worktree the tooling no longer
|
|
473
|
+
* owned. All-string fields; the worktree directory survives the suspend on disk (managed under the
|
|
474
|
+
* task root, `git worktree` metadata intact).
|
|
475
|
+
*/
|
|
476
|
+
activeWorktree?: {
|
|
477
|
+
worktreeDir: string;
|
|
478
|
+
originalCwd: string;
|
|
479
|
+
baseSha: string;
|
|
480
|
+
entered?: boolean;
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* {@link CheckpointState} with **every** field made required-PRESENT, while each value keeps its original
|
|
485
|
+
* type (so an absent optional field is still passed explicitly as `undefined`). The suspend-side
|
|
486
|
+
* serialization builds `state` as this type (design/45 P3 / design/51 §P3): adding a new per-task
|
|
487
|
+
* correctness field to {@link CheckpointState} is then a **compile error** at the serialization site until
|
|
488
|
+
* it is explicitly handled — it can never be silently omitted and lost on resume. (Keying off
|
|
489
|
+
* `keyof Required<…>` makes the mapped type non-homomorphic, so it forces presence of every key yet leaves
|
|
490
|
+
* each value's `| undefined` intact — `workspaceHandle: undefined` for a process-local suspend still
|
|
491
|
+
* type-checks.)
|
|
492
|
+
*/
|
|
493
|
+
export type SerializedCheckpointState = {
|
|
494
|
+
[K in keyof Required<CheckpointState>]: CheckpointState[K];
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* The current {@link Checkpoint} schema version a v1.5 suspend stamps, and the highest a resume here
|
|
498
|
+
* accepts (design/49 §3, code-ready council round-2). Bump together with `MAX_SUPPORTED_CHECKPOINT_VERSION`
|
|
499
|
+
* only when this worker can also *read* the new shape. A future v2 worker raises MAX to 2 and still reads a
|
|
500
|
+
* v1 checkpoint — forward-compatible by `<=`, never `=== `.
|
|
501
|
+
*/
|
|
502
|
+
export declare const CURRENT_CHECKPOINT_VERSION = 1;
|
|
503
|
+
/** design/74 R3-B: the schema version a `resource_limit` suspend stamps (v2 — it adds `resourceLedger` and a
|
|
504
|
+
* `resource_limit` `pendingAction`/`gate` an old worker can't handle). An old worker (`MAX_SUPPORTED`=1)
|
|
505
|
+
* rejects it pre-CAS (stays `pending`, retryable on a new worker). */
|
|
506
|
+
export declare const RESOURCE_CHECKPOINT_VERSION = 2;
|
|
507
|
+
/**
|
|
508
|
+
* design/80 D-1 (version-skew downgrade fix): the schema version a **binding-bearing** human/irreversible_ask
|
|
509
|
+
* `tool_approval` suspend stamps. These checkpoints carry the decision-action binding (`boundCallId` +
|
|
510
|
+
* `boundInputHash`) whose enforcement lives ENTIRELY in the resuming worker's resume path. A pre-D-1 worker
|
|
511
|
+
* (released 1.100.0: `MAX_SUPPORTED`=2, and its resume code has ZERO binding logic) would otherwise resume a
|
|
512
|
+
* D-1-minted v1 checkpoint and execute the pending tool with NO decision-action verification — the exact
|
|
513
|
+
* "approve vendor-A $5 → execute vendor-B $5000" bypass the binding exists to prevent (council BLOCKER #1).
|
|
514
|
+
* Stamping these at **v3 (> the old worker's MAX of 2)** forces a pre-D-1 worker to reject them PRE-CAS
|
|
515
|
+
* (`unsupported_version`, stays `pending`, retried on a binding-enforcing worker) instead of silently voiding
|
|
516
|
+
* the binding. A resource_limit suspend keeps stamping v2; a pre-binding (legacy 1.100.0) checkpoint is v1.
|
|
517
|
+
*/
|
|
518
|
+
export declare const BINDING_CHECKPOINT_VERSION = 3;
|
|
519
|
+
/** The highest {@link Checkpoint.version} `runner.resume` will act on; a higher one is rejected pre-CAS with
|
|
520
|
+
* {@link CheckpointError} `unsupported_version` (the checkpoint stays `pending`, retryable on a newer worker).
|
|
521
|
+
* Raised to 3 for design/80 D-1 binding checkpoints — this worker reads v1 (legacy human), v2 (resource),
|
|
522
|
+
* and v3 (binding human/irreversible_ask). */
|
|
523
|
+
export declare const MAX_SUPPORTED_CHECKPOINT_VERSION = 3;
|
|
524
|
+
/**
|
|
525
|
+
* Read a checkpoint's schema version, defaulting an absent field to **legacy `0`** (a 1.67-era checkpoint
|
|
526
|
+
* written before the field existed — it carries no `workspaceHandle`, so resuming it the v1 way is safe).
|
|
527
|
+
* Compare with `<= MAX_SUPPORTED_CHECKPOINT_VERSION`, never `=== CURRENT_CHECKPOINT_VERSION` (design/49 §3).
|
|
528
|
+
*/
|
|
529
|
+
export declare function checkpointVersionOf(cp: Pick<Checkpoint, "version">): number;
|
|
530
|
+
/**
|
|
531
|
+
* design/74 R3-B: cross-slice resource accounting carried by a `resource_limit` {@link Checkpoint}. The
|
|
532
|
+
* total budget is the human's allocation; `spent*` accumulate across the resume→re-suspend chain (debited
|
|
533
|
+
* at each suspend's `put`). A resumed slice's effective `maxCostUsd` = `min(window, totalBudgetMicroUsd -
|
|
534
|
+
* spentMicroUsd)`; the final {@link TaskResult} stats aggregate `spent* + this slice's stats` so a
|
|
535
|
+
* multi-slice run reports the whole, not just the last segment. Lives ON the checkpoint row so one
|
|
536
|
+
* `resolve`/`put` CAS covers status + ledger atomically (no cross-store split).
|
|
537
|
+
*/
|
|
538
|
+
export interface ResourceLedger {
|
|
539
|
+
/** The human's total $ allocation in micro-USD; `undefined` = no $ ceiling (only window/walltime bound). */
|
|
540
|
+
totalBudgetMicroUsd?: number;
|
|
541
|
+
/** The human's total wall-clock allocation in seconds; `undefined` = no time ceiling. */
|
|
542
|
+
totalWalltimeSec?: number;
|
|
543
|
+
/** Cumulative cost across all slices so far (micro-USD), debited at each suspend's `put`. */
|
|
544
|
+
spentMicroUsd: number;
|
|
545
|
+
/** Cumulative tokens across all slices so far. */
|
|
546
|
+
spentTokens: number;
|
|
547
|
+
/** Cumulative turns across all slices so far. */
|
|
548
|
+
spentTurns: number;
|
|
549
|
+
/** How many slices have run so far (the resource chain's suspend count). */
|
|
550
|
+
sliceCount: number;
|
|
551
|
+
}
|
|
552
|
+
/** design/74 Slice 4: accumulate ONE slice's spend into the ledger — called when a `resource_limit` suspend
|
|
553
|
+
* commits its checkpoint (debit-at-`put`, so the persisted ledger always reflects everything spent up to and
|
|
554
|
+
* including the slice being suspended). Pure. The FIRST slice (no prior ledger) seeds the human totals from
|
|
555
|
+
* `total`; every later slice keeps the ledger's own totals (authoritative — a resumed slice must not be able
|
|
556
|
+
* to silently raise its own ceiling). Negative slice figures are clamped to 0 (a misreported usage can never
|
|
557
|
+
* REFUND the cumulative spend and reopen budget). */
|
|
558
|
+
export declare function debitLedger(prior: ResourceLedger | undefined, slice: {
|
|
559
|
+
costMicroUsd: number;
|
|
560
|
+
tokens: number;
|
|
561
|
+
turns: number;
|
|
562
|
+
}, total?: {
|
|
563
|
+
totalBudgetMicroUsd?: number;
|
|
564
|
+
totalWalltimeSec?: number;
|
|
565
|
+
}, opts?: {
|
|
566
|
+
countSlice?: boolean;
|
|
567
|
+
}): ResourceLedger;
|
|
568
|
+
/** design/74 Slice 4: the $ budget (micro-USD) the NEXT slice may still spend = `totalBudgetMicroUsd -
|
|
569
|
+
* spentMicroUsd`, never negative. `undefined` when no total $ ceiling is set (the run is bounded only by the
|
|
570
|
+
* per-slice window / walltime). A resumed slice's effective `maxCostUsd` is `min(window, this)`. NB: `0` is a
|
|
571
|
+
* VALID, exhausted ceiling — NOT "unlimited" (only `undefined` is unlimited). Any spend then immediately trips
|
|
572
|
+
* `overBudget`, and the run loop fails an exhausted resume fast (runtask). Never falsy-test this value (a
|
|
573
|
+
* `if (remaining)` would skip a legitimate 0 ceiling and silently bypass the budget). */
|
|
574
|
+
export declare function remainingBudgetMicroUsd(ledger: ResourceLedger | undefined): number | undefined;
|
|
575
|
+
/**
|
|
576
|
+
* design/80 D-1 (reopen-by-reason + persist-winner): the WINNING resume binding, recorded ON the
|
|
577
|
+
* checkpoint row the moment a {@link CheckpointStore.resolve} CAS wins (pending → resolved). It is the
|
|
578
|
+
* durable record of "which decision was approved against which pending action" so a later reopen→re-resume
|
|
579
|
+
* can be validated against it. Only a `policy_ask` resolve records a winner (it is the only outcome bound
|
|
580
|
+
* to a specific pending tool call); a `resource_limit` / `dry_run_review` / `task_done` resolve records
|
|
581
|
+
* none (there is no action to bind). `boundInputHash` (binding the exact executed bytes) is a SEPARATE
|
|
582
|
+
* later D-1 slice (1a.2) and is deliberately NOT part of this winner.
|
|
583
|
+
*/
|
|
584
|
+
export interface ResolvedOutcome {
|
|
585
|
+
/** The pending tool call this decision was bound to (design/80 D-1 slice 1a). */
|
|
586
|
+
boundCallId: string;
|
|
587
|
+
/** The adjudication the operator made. */
|
|
588
|
+
decision: "allow" | "deny";
|
|
589
|
+
/** A re-written arg payload, if the `allow` rewrote the call (design/37). Carried so an `env_failed`
|
|
590
|
+
* re-resume (a system retry of the SAME approved action) must replay the identical `updatedInput`. */
|
|
591
|
+
updatedInput?: unknown;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* design/80 D-1: why a consumed checkpoint was {@link CheckpointStore.reopen | reopened} (resolved →
|
|
595
|
+
* pending). The reason drives re-resume validation (§3 invariant #1): an `env_failed` reopen is a SYSTEM
|
|
596
|
+
* RETRY of the ALREADY-APPROVED action — the re-resume MUST replay the persisted {@link ResolvedOutcome}
|
|
597
|
+
* winner, never a new vote — while a `tool_unavailable` reopen (the action could not run, may now be
|
|
598
|
+
* invalid — P-7) lets a human RE-DECIDE with the tool present, so a fresh operator decision IS allowed.
|
|
599
|
+
*/
|
|
600
|
+
export type ReopenReason = "env_failed" | "tool_unavailable";
|
|
601
|
+
/**
|
|
602
|
+
* design/80 D-1 (atomicity fix): the optimistic-concurrency precondition a {@link CheckpointStore.resolve}
|
|
603
|
+
* caller passes so its CAS is atomic with the validation it did against an earlier `get()` snapshot. The
|
|
604
|
+
* resume-side decision-action guards (boundCallId/boundInputHash) bind to per-token-IMMUTABLE fields, but the
|
|
605
|
+
* **reopen-by-reason** guard reads `reopenReason` + `resolvedOutcome` — which a concurrent
|
|
606
|
+
* {@link CheckpointStore.reopen}/{@link CheckpointStore.resolve} cycle mutates. Passing the monotonic
|
|
607
|
+
* {@link Checkpoint.rev} the caller observed makes `resolve` additionally require the LIVE row's `rev` to still
|
|
608
|
+
* equal it; ANY intervening resolve/reopen bumps `rev`, so a cycle in the get→resolve window loses the CAS
|
|
609
|
+
* (fail-closed), forcing a re-`get` + re-validate.
|
|
610
|
+
*
|
|
611
|
+
* **Why a counter, not the reopenReason value (round-2 BLOCKER fix):** `reopenReason` is a 2-valued enum, so a
|
|
612
|
+
* full `env_failed`→`tool_unavailable`→`env_failed` cycle (the `tool_unavailable` arm permits a fresh P-7
|
|
613
|
+
* re-decision) returns `reopenReason` to the SAME value while `resolvedOutcome` silently changed to a different
|
|
614
|
+
* (e.g. RETRACTED) winner — a classic ABA on the OCC key. A monotonic `rev` bumped on every resolve/reopen is
|
|
615
|
+
* ABA-proof: a returned-to-the-same-value `reopenReason` still has a strictly higher `rev`. Omit `expect`
|
|
616
|
+
* (legacy callers / direct store tests) → no OCC.
|
|
617
|
+
*/
|
|
618
|
+
export interface ResolveExpectation {
|
|
619
|
+
/** The monotonic {@link Checkpoint.rev} the caller observed at `get()` (absent rev ⇒ legacy `0`). */
|
|
620
|
+
rev: number;
|
|
621
|
+
}
|
|
622
|
+
/** A persisted suspension point: enough to resume a task on any replica. `status` drives the 3-state
|
|
623
|
+
* machine (pending → resolved | expired) that makes resume idempotent (§5). */
|
|
624
|
+
export interface Checkpoint {
|
|
625
|
+
token: CheckpointToken;
|
|
626
|
+
/**
|
|
627
|
+
* Schema version of this checkpoint (design/49 v1.5). A v1.5 suspend stamps {@link CURRENT_CHECKPOINT_VERSION};
|
|
628
|
+
* absent ⇒ legacy `0` (1.67-era, no `state.workspaceHandle`). Resume rejects `> MAX_SUPPORTED_CHECKPOINT_VERSION`
|
|
629
|
+
* pre-CAS so an old worker can't silently ignore fields a newer format relies on (forward-compatible by `<=`).
|
|
630
|
+
* Read via {@link checkpointVersionOf}.
|
|
631
|
+
*/
|
|
632
|
+
version?: number;
|
|
633
|
+
/** Multi-tenant isolation key (forced through `resolve`/`reap` WHERE, §2.1 service [4]). */
|
|
634
|
+
scope: string;
|
|
635
|
+
/** The session to resume (via the SessionStore). */
|
|
636
|
+
sessionId: string;
|
|
637
|
+
/** The session leaf the suspend happened at — the resume point (CAS write base, §5). */
|
|
638
|
+
leafId: string;
|
|
639
|
+
gate: CheckpointGate;
|
|
640
|
+
pendingAction: PendingAction;
|
|
641
|
+
state: CheckpointState;
|
|
642
|
+
/** design/74 R3-B: cross-slice resource accounting. Present for a `resource_limit` gate (debited at the
|
|
643
|
+
* suspend's `put`; read on resume to size the next slice + aggregate the final stats). **design/80 D-E-core
|
|
644
|
+
* (A3):** ALSO attached to a human/irreversible_ask APPROVAL suspend — debited with that leg's spend — so a
|
|
645
|
+
* STATELESS policy can read durable cumulative spend across the resume chain via {@link ToolCallRequest.budget}
|
|
646
|
+
* (a fresh in-memory counter would reset every leg). On the approval path it is READ-CONTEXT ONLY: the final
|
|
647
|
+
* -stats aggregate fold (runtask) is gated to the `resource_limit` gate kind, so an approval resume is never
|
|
648
|
+
* double-counted. Absent for `task_done`. See {@link ResourceLedger}. */
|
|
649
|
+
resourceLedger?: ResourceLedger;
|
|
650
|
+
/**
|
|
651
|
+
* Absolute epoch-ms deadline for an awaiting-human checkpoint; past it, `reap` expires it (§6).
|
|
652
|
+
*
|
|
653
|
+
* **design/80 §D-D semantic contract (the DURABLE FIELD a reaper-loop consumes — read it on
|
|
654
|
+
* {@link CheckpointStore} too):** for an APPROVAL gate (`gate.kind` ∈ {`human`, `irreversible_ask`}) the
|
|
655
|
+
* deployment's reaper-loop treats this as an **SLA resolve-deny** time (FACET A — its fast path: at deadline
|
|
656
|
+
* it `resolve`s the checkpoint as a `deny` so the run ends cleanly), with a LATER `terminalAt` abandonment
|
|
657
|
+
* backstop the loop ALSO honors (crash-safe if the SLA timer never fired). For an UNATTENDED-TTL gate
|
|
658
|
+
* (`gate.kind` ∈ {`resource_limit`, `needs_review`, `plan_review`} — the resource + review-pause family) this
|
|
659
|
+
* is an **abandonment-TTL** → `expire`/{@link reap} ONLY, NEVER a resolve-deny (FACET B — those kinds resume
|
|
660
|
+
* only with their OWN outcome, so a `policy_ask` resolve-deny hits no `gateMatch` arm → `gate_mismatch`). The
|
|
661
|
+
* reaper-loop + the gate.kind policy + minting `terminalAt` are the DEPLOYMENT's job
|
|
662
|
+
* (its store impl + loop — owned service-side, channel [135]/[136]); CORE only guarantees this `deadline`
|
|
663
|
+
* field (for `human`/`irreversible_ask`) + the persisted {@link gate}.kind survive the round-trip so any
|
|
664
|
+
* reaper consumer (the service's TiDB loop OR a non-service Pg deployment) implements the SAME contract.
|
|
665
|
+
*/
|
|
666
|
+
deadline?: number;
|
|
667
|
+
status: "pending" | "resolved" | "expired";
|
|
668
|
+
createdAt: number;
|
|
669
|
+
/**
|
|
670
|
+
* How many times THIS task has suspended, counting this checkpoint (1 = first suspend; design/72
|
|
671
|
+
* §2.2 (B)). Carried forward across resume→re-suspend (each new checkpoint = the prior count + 1), so
|
|
672
|
+
* a restart-prone model that keeps re-issuing the gated/egress call — re-suspending every resume —
|
|
673
|
+
* is capped: past `maxSuspends` the run fails (`suspend.loop`) instead of minting another checkpoint
|
|
674
|
+
* and looping forever. Absent ⇒ legacy `0` (pre-§2.2 checkpoints; treated as "no prior suspends").
|
|
675
|
+
*/
|
|
676
|
+
suspendCount?: number;
|
|
677
|
+
/**
|
|
678
|
+
* design/91 — the wall-clock instant (epoch ms, from {@link import("./types.js").RunnerDeps.now}) this task
|
|
679
|
+
* suspended at a HUMAN-REVIEW gate. Resume derives the human-review latency for this leg as
|
|
680
|
+
* `now() − suspendedAt` and folds it into `TaskResult.stats.humanReview` (the design/89 §2.4 C2 burden axis).
|
|
681
|
+
* The human-review family is the APPROVAL gates (`gate.kind` ∈ {`human`, `irreversible_ask`}) — core stamps
|
|
682
|
+
* this automatically on the approval-suspend mint — AND the REVIEW-PAUSE gates (`needs_review` = a dry-run
|
|
683
|
+
* diff review, `plan_review` = a pre-action PLAN review). Review-pause checkpoints are minted by a PROFILE
|
|
684
|
+
* (core owns only the routing/resume discriminants), so a profile that wants the C2 wait counted MUST stamp
|
|
685
|
+
* `suspendedAt = deps.now()` at mint — the same injectable clock the resume reads, so a test pins the latency.
|
|
686
|
+
* Absent on a `resource_limit` suspend (a machine backstop, not a human wait), on a review-pause checkpoint
|
|
687
|
+
* whose profile did not opt in, and on a legacy pre-design/91 checkpoint (⇒ resume skips the durable latency
|
|
688
|
+
* for that leg — no undercount surprise, just no entry).
|
|
689
|
+
*/
|
|
690
|
+
suspendedAt?: number;
|
|
691
|
+
/**
|
|
692
|
+
* design/91 — the accumulated {@link import("./types.js").TaskResult.stats}`.humanReview` from all PRIOR legs,
|
|
693
|
+
* carried forward across resume→re-suspend (like {@link suspendCount} / {@link resourceLedger}) so a
|
|
694
|
+
* multi-leg suspend/resume chain reports the WHOLE human-review burden, not just the last leg's. It holds
|
|
695
|
+
* the gates resolved up to and including the suspend BEFORE this one — the latency for THIS suspend is added
|
|
696
|
+
* by the resume that wakes it (`now() − suspendedAt`). Absent ⇒ no prior human-review time (a first suspend
|
|
697
|
+
* with no earlier synchronous asks). Budget-EXCLUDED side observable — never a cost/gate input.
|
|
698
|
+
*/
|
|
699
|
+
humanReview?: {
|
|
700
|
+
count: number;
|
|
701
|
+
totalWaitMs: number;
|
|
702
|
+
gates: Array<{
|
|
703
|
+
kind: string;
|
|
704
|
+
waitMs: number;
|
|
705
|
+
decision?: string;
|
|
706
|
+
}>;
|
|
707
|
+
};
|
|
708
|
+
/**
|
|
709
|
+
* design/80 D-1 (persist-winner): the winning resume binding, recorded by {@link CheckpointStore.resolve}
|
|
710
|
+
* when its CAS wins (pending → resolved) — present ONLY after a `policy_ask` resolve, absent on a freshly
|
|
711
|
+
* minted pending checkpoint and on non-`policy_ask` resolves. PRESERVED (never cleared) across a
|
|
712
|
+
* {@link CheckpointStore.reopen} so an `env_failed` re-resume can be validated against it. See
|
|
713
|
+
* {@link ResolvedOutcome}.
|
|
714
|
+
*/
|
|
715
|
+
resolvedOutcome?: ResolvedOutcome;
|
|
716
|
+
/**
|
|
717
|
+
* design/80 D-1 (reopen-by-reason): why this checkpoint was last reopened (resolved → pending), recorded
|
|
718
|
+
* by {@link CheckpointStore.reopen}. Drives re-resume validation (§3 invariant #1): `env_failed` ⇒ the
|
|
719
|
+
* re-resume must replay the persisted {@link resolvedOutcome} winner (a system retry of the approved
|
|
720
|
+
* action); `tool_unavailable` ⇒ a fresh operator decision is allowed (P-7 re-decide with the tool
|
|
721
|
+
* present). Absent on a never-reopened checkpoint (a first resume is unconstrained by reason).
|
|
722
|
+
*/
|
|
723
|
+
reopenReason?: ReopenReason;
|
|
724
|
+
/**
|
|
725
|
+
* design/80 D-1 (atomicity fix, round-2 BLOCKER): a **monotonic revision counter** bumped by EVERY
|
|
726
|
+
* {@link CheckpointStore.resolve} (won) and {@link CheckpointStore.reopen}. It is the optimistic-concurrency
|
|
727
|
+
* key ({@link ResolveExpectation}): a resume reads it at `get()` and `resolve` requires the live `rev` to
|
|
728
|
+
* still equal it, so any resolve/reopen cycle landing in the get→resolve window loses the CAS (fail-closed).
|
|
729
|
+
* Unlike the 2-valued `reopenReason`, it cannot ABA back to a prior value. Absent ⇒ legacy `0` (a checkpoint
|
|
730
|
+
* minted before this field; treated as never mutated).
|
|
731
|
+
*/
|
|
732
|
+
rev?: number;
|
|
733
|
+
/**
|
|
734
|
+
* design S1d (source-tag persistence, service [198]/[199]): the issuing task's session id, stamped at the
|
|
735
|
+
* APPROVAL suspend mint so a supervisor inbox can attribute a paused/awaiting checkpoint to the worker that
|
|
736
|
+
* raised it (the durable analog of {@link import("./tool-policy.js").AskRequest}.sourceTaskId — the durable
|
|
737
|
+
* suspend path does NOT invoke `onAsk`, so the synchronous source identity is captured here instead). It is
|
|
738
|
+
* the SAME value the synchronous ask carries: `= sessionId` at the mint.
|
|
739
|
+
*
|
|
740
|
+
* **Security invariant (carried verbatim from the 1.113.0 ask-bubbling contract):** for a Runner-created
|
|
741
|
+
* DELEGATED subagent this is **worker-unforgeable** (a child never sets its own sessionId — the Runner mints
|
|
742
|
+
* it); a top-level caller MAY continue its own session id via {@link import("./types.js").TaskSpec.sessionId},
|
|
743
|
+
* so this is NOT a global "never forgeable" run id — aggregation only aggregates delegated workers, where it
|
|
744
|
+
* holds. **ECHO-ONLY triage metadata, NEVER a gate input:** no gate / CAS / winner / resume-validation path
|
|
745
|
+
* reads it (a contract-test pins this). Absent ⇒ no source task id (a non-ask gate, or a legacy checkpoint).
|
|
746
|
+
*/
|
|
747
|
+
sourceTaskId?: string;
|
|
748
|
+
/**
|
|
749
|
+
* design S1d (source-tag persistence): the issuing task's authenticated end-user {@link
|
|
750
|
+
* import("./types.js").TaskSpec.principal} (design/62), stamped at the APPROVAL suspend mint so an aggregating
|
|
751
|
+
* inbox can attribute a paused checkpoint per-user — the durable analog of {@link
|
|
752
|
+
* import("./tool-policy.js").AskRequest}.principal. Caller-set (never a tool/worker arg), and like
|
|
753
|
+
* {@link sourceTaskId} it is **ECHO-ONLY triage metadata, NEVER a gate input** (no gate/CAS/winner/resume path
|
|
754
|
+
* reads it). Absent ⇒ no principal (a non-ask gate, an unauthenticated task, or a legacy checkpoint).
|
|
755
|
+
*/
|
|
756
|
+
principal?: string;
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* design/80 assistant-scheduler seam #1 (channel [148]/[149]): a LIGHTWEIGHT projection of one PENDING
|
|
760
|
+
* checkpoint, returned in bulk by {@link CheckpointStore.listByScope} so a supervisor scheduler can list a
|
|
761
|
+
* scope's suspended/awaiting tasks in ONE call (no N+1 `get`s, no full-{@link Checkpoint} payloads). It is a
|
|
762
|
+
* read-only DISPLAY/triage summary — every field is DERIVED from the persisted {@link Checkpoint}; nothing
|
|
763
|
+
* here is a new source of truth or a gate input.
|
|
764
|
+
*/
|
|
765
|
+
export interface CheckpointSummary {
|
|
766
|
+
/** The resume capability token ({@link Checkpoint.token}). */
|
|
767
|
+
token: CheckpointToken;
|
|
768
|
+
/** The suspended task / session id ({@link Checkpoint.sessionId}). */
|
|
769
|
+
sessionId: string;
|
|
770
|
+
/** The multi-tenant scope this checkpoint lives in ({@link Checkpoint.scope}) — always equal to the query's. */
|
|
771
|
+
scope: string;
|
|
772
|
+
/** The gate's discriminant ({@link CheckpointGate}.kind): which kind of pause this is. */
|
|
773
|
+
gateKind: CheckpointGate["kind"];
|
|
774
|
+
/** The deterministic risk tier (1..5) when the gate carries a {@link RiskDescriptor} (the `human` /
|
|
775
|
+
* `irreversible_ask` approval escalations), derived via {@link riskSeverity} from the descriptor's axes —
|
|
776
|
+
* the SAME value as `gate.riskDescriptor.severity`, recomputed from the single source helper rather than
|
|
777
|
+
* re-stored. `undefined` for a gate with no descriptor (resource_limit / needs_review / plan_review / a
|
|
778
|
+
* legacy human ask minted before D-E). The inbox sorts DESC by this. */
|
|
779
|
+
severity?: 1 | 2 | 3 | 4 | 5;
|
|
780
|
+
/** Cumulative spend debited to this suspend chain ({@link ResourceLedger.spentMicroUsd}) in micro-USD —
|
|
781
|
+
* present whenever the checkpoint carries a {@link Checkpoint.resourceLedger} (every resource_limit suspend,
|
|
782
|
+
* and every approval suspend on the D-E-core budget-read path); `undefined` when no ledger is attached. */
|
|
783
|
+
spentMicroUsd?: number;
|
|
784
|
+
/** The awaiting-human SLA / abandonment deadline ({@link Checkpoint.deadline}, epoch ms) when present. */
|
|
785
|
+
deadline?: number;
|
|
786
|
+
/** design S1d (source-tag): the issuing worker's session id ({@link Checkpoint.sourceTaskId}) — projected so
|
|
787
|
+
* a supervisor inbox attributes each pending checkpoint to its worker in ONE `listByScope` call (no N+1
|
|
788
|
+
* `getCheckpoint`). ECHO-ONLY display/triage; absent on a non-ask gate / legacy checkpoint. */
|
|
789
|
+
sourceTaskId?: string;
|
|
790
|
+
/** design S1d (source-tag): the issuing task's end-user principal ({@link Checkpoint.principal}) for per-user
|
|
791
|
+
* inbox attribution. ECHO-ONLY display/triage; absent when the checkpoint carries no principal. */
|
|
792
|
+
principal?: string;
|
|
793
|
+
/** The pending tool call's id ({@link PendingAction} `tool_approval.toolCallId`) when this is an approval
|
|
794
|
+
* suspend — projected so the inbox shows WHICH call awaits a decision without an N+1 `getCheckpoint`.
|
|
795
|
+
* `undefined` for a non-`tool_approval` pendingAction (resource_limit / plan_review / task_done). */
|
|
796
|
+
toolCallId?: string;
|
|
797
|
+
/** The pending tool's name ({@link PendingAction} `tool_approval.toolName`) when this is an approval suspend.
|
|
798
|
+
* `undefined` for a non-`tool_approval` pendingAction. */
|
|
799
|
+
toolName?: string;
|
|
800
|
+
/** design/99 MF-14 (design-review DoR): the DERIVED content-gate classification — `"content_ask"` when this
|
|
801
|
+
* `tool_approval` gates the reserved AskUserQuestion tool (a question TO the user, not a side-effecting tool).
|
|
802
|
+
* A TYPED discriminant so a shell renders the question UI without sniffing `toolName` or parsing the bounded
|
|
803
|
+
* `toolInput` preview. The full typed questions ride the drilled-in Checkpoint's `pendingAction.args` (kept off
|
|
804
|
+
* this lightweight `listByScope` projection). Deliberately NOT a new `content_ask` checkpoint gate kind (that
|
|
805
|
+
* would cross the durable-checkpoint once-only-winner / reaper-deadline / batch invariants — the DoR). */
|
|
806
|
+
contentKind?: "content_ask";
|
|
807
|
+
/** design S1e (service [204]): when the checkpoint was created ({@link Checkpoint.createdAt}, epoch ms) —
|
|
808
|
+
* projected so a supervisor inbox can sort/age pending entries (oldest-first triage) in ONE `listByScope`
|
|
809
|
+
* call, no N+1 `getCheckpoint`. ECHO-ONLY display/triage; always present (a Checkpoint always has a
|
|
810
|
+
* `createdAt`). */
|
|
811
|
+
createdAt?: number;
|
|
812
|
+
/**
|
|
813
|
+
* design S1e (service [204]): a **BOUNDED, UNREDACTED** raw preview of the pending tool call's input
|
|
814
|
+
* ({@link PendingAction} `tool_approval.args` `JSON.stringify`-ed, truncated to {@link
|
|
815
|
+
* MAX_TOOL_INPUT_PREVIEW_CHARS} chars with a `…` marker when over) — projected so a supervisor inbox shows
|
|
816
|
+
* WHAT a paused tool call will do without an N+1 `getCheckpoint`. `undefined` for a non-`tool_approval`
|
|
817
|
+
* pendingAction (resource_limit / plan_review / task_done — no args to preview).
|
|
818
|
+
*
|
|
819
|
+
* **Contract (load-bearing):**
|
|
820
|
+
* - **bounded raw preview** — length-capped to {@link MAX_TOOL_INPUT_PREVIEW_CHARS} so it cannot bloat the
|
|
821
|
+
* `listByScope` payload, but the chars within the cap are the RAW serialized args (no folding/escaping).
|
|
822
|
+
* - **redaction is the CONSUMER's responsibility** — core gives the inbox the unredacted bounded raw; the
|
|
823
|
+
* service/inbox decides what (if anything) to mask before showing a human. (Contrast {@link
|
|
824
|
+
* RiskDescriptor.summary}, which is the NEUTRALIZED+capped descriptor that DOES ride into a render —
|
|
825
|
+
* `toolInput` is the raw-data sibling for a consumer that wants the actual args.)
|
|
826
|
+
* - **same data as the full {@link Checkpoint}** — it is a projection of `pendingAction.args`, which the
|
|
827
|
+
* caller could already read via `get`; this adds NO new exposure, it only saves the round-trip.
|
|
828
|
+
* - **ECHO-ONLY, like {@link sourceTaskId}** — NO gate / CAS / resume / {@link winnerFromOutcome} path reads
|
|
829
|
+
* it (a contract test pins this); it is pure display/triage metadata, never a control input.
|
|
830
|
+
*/
|
|
831
|
+
toolInput?: string;
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* design/80 assistant-scheduler seam #1: project a single PENDING {@link Checkpoint} to its lightweight
|
|
835
|
+
* {@link CheckpointSummary}. Shared by every {@link CheckpointStore} impl so the projection is IDENTICAL
|
|
836
|
+
* across the in-memory, file, and durable backends (the anti-drift guard) — `severity` always derives from the
|
|
837
|
+
* gate's {@link RiskDescriptor} via the single {@link riskSeverity} helper, `spentMicroUsd` always reads
|
|
838
|
+
* {@link ResourceLedger.spentMicroUsd}. Pure; reads no clock/random.
|
|
839
|
+
*/
|
|
840
|
+
export declare function summarizeCheckpoint(cp: Checkpoint): CheckpointSummary;
|
|
841
|
+
/** A typed checkpoint-store error so callers branch on `code` (mirrors `SessionError`). */
|
|
842
|
+
export declare class CheckpointError extends Error {
|
|
843
|
+
readonly code: "checkpoint.already_exists" | "checkpoint.already_resolved" | "checkpoint.not_found"
|
|
844
|
+
/** `runner.resume` was handed an {@link ResumeOutcome} whose `gate` arm does not match the
|
|
845
|
+
* persisted {@link CheckpointGate} `kind` (council #3 — type confusion guard), or a gate v1
|
|
846
|
+
* resume does not serve (`task_done`). */
|
|
847
|
+
| "checkpoint.gate_mismatch"
|
|
848
|
+
/** `runner.resume` was handed an outcome whose payload is unsafe to apply — e.g. a deny `reason`
|
|
849
|
+
* carrying a `</system-reminder>` tag that would escape the model-facing wrapper (round-2 #1). */
|
|
850
|
+
| "checkpoint.invalid_outcome"
|
|
851
|
+
/** The checkpoint's {@link Checkpoint.version} is newer than this worker supports
|
|
852
|
+
* (`> MAX_SUPPORTED_CHECKPOINT_VERSION`), or it carries a remote `workspaceHandle` but no
|
|
853
|
+
* `executionEnvFactory` is wired to rebuild the env — either way this worker cannot safely resume it.
|
|
854
|
+
* Rejected pre-CAS so the checkpoint stays `pending` and a capable worker can still resume it
|
|
855
|
+
* (design/49 §2/§3, code-ready council round-2). */
|
|
856
|
+
| "checkpoint.unsupported_version"
|
|
857
|
+
/** design/80 D-1 (reopen-by-reason): a re-resume of an `env_failed`-reopened checkpoint supplied an
|
|
858
|
+
* outcome that does NOT equal the persisted {@link ResolvedOutcome} winner. An `env_failed` reopen is
|
|
859
|
+
* a SYSTEM RETRY of the already-approved action (the infra failed, not the decision) — it must replay
|
|
860
|
+
* the exact winning binding, never a new vote. Rejected pre-CAS, fail-closed, so the checkpoint stays
|
|
861
|
+
* `pending` for the correctly-replayed retry. (A `tool_unavailable` reopen — P-7 — is exempt: it lets
|
|
862
|
+
* a human re-decide with the tool present, so a fresh decision is permitted there.) */
|
|
863
|
+
| "checkpoint.reopen_revote"
|
|
864
|
+
/** design/80 D-1 (atomicity fix): the resume validated its decision-action / reopen-by-reason guards
|
|
865
|
+
* against a `get()` snapshot, but a concurrent {@link CheckpointStore.resolve}/{@link CheckpointStore.reopen}
|
|
866
|
+
* cycle advanced the monotonic {@link Checkpoint.rev} in the get→resolve window, so the
|
|
867
|
+
* {@link CheckpointStore.resolve} CAS's optimistic-concurrency check lost (the validation is stale). The
|
|
868
|
+
* row is still `pending` — fail-closed; the caller must re-`get` and re-validate against the CURRENT state
|
|
869
|
+
* (a fresh resume), never blindly retry. */
|
|
870
|
+
| "checkpoint.reopened_concurrently"
|
|
871
|
+
/** design/80 D-A: {@link CheckpointStore.setPendingSteer} was handed `text` containing a
|
|
872
|
+
* `</system-reminder>` close tag — it would escape the model-facing `<system-reminder>` wrapper a
|
|
873
|
+
* trusted steer rides on resume. Rejected fail-closed so a dirty steer NEVER enters {@link CheckpointState}
|
|
874
|
+
* (§3 inv #2). Mirrors the trusted-steer reject at runtask.ts (`steering.invalid_content`). */
|
|
875
|
+
| "steering.invalid_content";
|
|
876
|
+
constructor(code: "checkpoint.already_exists" | "checkpoint.already_resolved" | "checkpoint.not_found"
|
|
877
|
+
/** `runner.resume` was handed an {@link ResumeOutcome} whose `gate` arm does not match the
|
|
878
|
+
* persisted {@link CheckpointGate} `kind` (council #3 — type confusion guard), or a gate v1
|
|
879
|
+
* resume does not serve (`task_done`). */
|
|
880
|
+
| "checkpoint.gate_mismatch"
|
|
881
|
+
/** `runner.resume` was handed an outcome whose payload is unsafe to apply — e.g. a deny `reason`
|
|
882
|
+
* carrying a `</system-reminder>` tag that would escape the model-facing wrapper (round-2 #1). */
|
|
883
|
+
| "checkpoint.invalid_outcome"
|
|
884
|
+
/** The checkpoint's {@link Checkpoint.version} is newer than this worker supports
|
|
885
|
+
* (`> MAX_SUPPORTED_CHECKPOINT_VERSION`), or it carries a remote `workspaceHandle` but no
|
|
886
|
+
* `executionEnvFactory` is wired to rebuild the env — either way this worker cannot safely resume it.
|
|
887
|
+
* Rejected pre-CAS so the checkpoint stays `pending` and a capable worker can still resume it
|
|
888
|
+
* (design/49 §2/§3, code-ready council round-2). */
|
|
889
|
+
| "checkpoint.unsupported_version"
|
|
890
|
+
/** design/80 D-1 (reopen-by-reason): a re-resume of an `env_failed`-reopened checkpoint supplied an
|
|
891
|
+
* outcome that does NOT equal the persisted {@link ResolvedOutcome} winner. An `env_failed` reopen is
|
|
892
|
+
* a SYSTEM RETRY of the already-approved action (the infra failed, not the decision) — it must replay
|
|
893
|
+
* the exact winning binding, never a new vote. Rejected pre-CAS, fail-closed, so the checkpoint stays
|
|
894
|
+
* `pending` for the correctly-replayed retry. (A `tool_unavailable` reopen — P-7 — is exempt: it lets
|
|
895
|
+
* a human re-decide with the tool present, so a fresh decision is permitted there.) */
|
|
896
|
+
| "checkpoint.reopen_revote"
|
|
897
|
+
/** design/80 D-1 (atomicity fix): the resume validated its decision-action / reopen-by-reason guards
|
|
898
|
+
* against a `get()` snapshot, but a concurrent {@link CheckpointStore.resolve}/{@link CheckpointStore.reopen}
|
|
899
|
+
* cycle advanced the monotonic {@link Checkpoint.rev} in the get→resolve window, so the
|
|
900
|
+
* {@link CheckpointStore.resolve} CAS's optimistic-concurrency check lost (the validation is stale). The
|
|
901
|
+
* row is still `pending` — fail-closed; the caller must re-`get` and re-validate against the CURRENT state
|
|
902
|
+
* (a fresh resume), never blindly retry. */
|
|
903
|
+
| "checkpoint.reopened_concurrently"
|
|
904
|
+
/** design/80 D-A: {@link CheckpointStore.setPendingSteer} was handed `text` containing a
|
|
905
|
+
* `</system-reminder>` close tag — it would escape the model-facing `<system-reminder>` wrapper a
|
|
906
|
+
* trusted steer rides on resume. Rejected fail-closed so a dirty steer NEVER enters {@link CheckpointState}
|
|
907
|
+
* (§3 inv #2). Mirrors the trusted-steer reject at runtask.ts (`steering.invalid_content`). */
|
|
908
|
+
| "steering.invalid_content", message: string);
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* The pluggable durable seam (design/45 §2.1). Symmetric with `ToolResultStore`/`MemoryStore`:
|
|
912
|
+
* create-once `put`, `get`, an **atomic CAS `resolve`** (the once-only foundation), and a `reap` for TTL
|
|
913
|
+
* expiry. A durable backend (TiDB) makes resume cross-replica; the default in-memory impl is single
|
|
914
|
+
* instance / tests only.
|
|
915
|
+
*
|
|
916
|
+
* **Load-bearing contract (§2.1, service [4]):** `resolve` is the once-only gate. The store guarantees
|
|
917
|
+
* *exactly one* `resolve(token, ...)` wins the CAS (pending → resolved); the **runner** must treat
|
|
918
|
+
* "won the CAS" as the *sole* trigger to execute the pending action — that is what makes a pending tool
|
|
919
|
+
* call run exactly once across retries / double approvals / multiple replicas.
|
|
920
|
+
*
|
|
921
|
+
* **design/80 §D-D expiry semantic contract (gate.kind-aware reap + `terminalAt` backstop):** the
|
|
922
|
+
* reaper-LOOP that calls {@link reap}/{@link expire} is the DEPLOYMENT's (its store impl + loop — OWNED
|
|
923
|
+
* service-side, channel [135]/[136]); core's D-D job is ONLY to keep writing the durable FIELDS the loop
|
|
924
|
+
* reads ({@link Checkpoint.deadline} for an approval gate + the persisted {@link Checkpoint.gate}.kind) and
|
|
925
|
+
* to DOCUMENT the contract here so ANY reaper consumer (the service's TiDB loop, or a non-service Pg
|
|
926
|
+
* deployment) implements it IDENTICALLY:
|
|
927
|
+
* - **FACET A — APPROVAL gates** (`gate.kind` ∈ {`human`, `irreversible_ask`}): the loop's FAST PATH at
|
|
928
|
+
* `deadline` is an SLA **resolve-deny** (`resolve(token, {gate:"policy_ask", decision:"deny"}, …)` so the
|
|
929
|
+
* suspended run ends cleanly), with a LATER `terminalAt` **abandonment backstop** the loop ALSO honors
|
|
930
|
+
* (crash-safe if the SLA timer never fired — then {@link reap}/{@link expire} flips it `expired`).
|
|
931
|
+
* - **FACET B — UNATTENDED-TTL gates** (`gate.kind` ∈ {`resource_limit`, `needs_review`, `plan_review`} — the
|
|
932
|
+
* resource slice + the review-pause family): `deadline` is an abandonment-TTL → {@link expire}/{@link reap}
|
|
933
|
+
* ONLY, **NEVER** a resolve-deny (a resolve-deny on these kinds hits NO `gateMatch` arm → `gate_mismatch`;
|
|
934
|
+
* their resume outcome is `resource_limit`/`dry_run_review`/`plan_review` respectively, not `policy_ask`).
|
|
935
|
+
* NO core-minted `terminalAt`, NO core reaper, NO change to {@link reap} logic — minting `terminalAt` and
|
|
936
|
+
* running the gate.kind-aware loop are the deployment's, by design.
|
|
937
|
+
*/
|
|
938
|
+
export interface CheckpointStore {
|
|
939
|
+
/** Create-once. Throws {@link CheckpointError} `already_exists` on a token collision (never a silent
|
|
940
|
+
* overwrite — a reused token would clobber a live suspension). */
|
|
941
|
+
put(token: CheckpointToken, cp: Checkpoint): Promise<void>;
|
|
942
|
+
get(token: CheckpointToken): Promise<Checkpoint | null>;
|
|
943
|
+
/**
|
|
944
|
+
* Atomic CAS: `UPDATE … SET status='resolved' WHERE token=? AND scope=? AND status='pending'`.
|
|
945
|
+
* Returns `true` for the single winner (was pending → now resolved), `false` if already resolved/
|
|
946
|
+
* expired (`AlreadyResolved` — the caller treats it as a no-op, never re-executes). `scope` is in the
|
|
947
|
+
* WHERE for multi-tenant isolation (a wrong-scope resolve must not win).
|
|
948
|
+
*
|
|
949
|
+
* `outcome` is supplied so a **durable** backend persists it atomically with the status flip (design/45
|
|
950
|
+
* v2 resumable-resume hook). **design/80 D-1 (persist-winner):** when the CAS wins on a `policy_ask`
|
|
951
|
+
* outcome, the store ALSO records the winning binding (`{boundCallId, decision, updatedInput?}`) as
|
|
952
|
+
* {@link Checkpoint.resolvedOutcome} on the row — so a later {@link reopen} → re-resume can be validated
|
|
953
|
+
* against the approved decision (an `env_failed` reopen must replay the same winner; design/80 §3 inv #1).
|
|
954
|
+
* Non-`policy_ask` outcomes (`resource_limit` / `dry_run_review` / `task_done`) bind to no action and
|
|
955
|
+
* record no winner. (The crash-recovery semantics of *acting* on a won CAS are runner contract — see
|
|
956
|
+
* {@link Runner.resume}; the store only owns the atomic once-only flip + the durable winner.)
|
|
957
|
+
*/
|
|
958
|
+
resolve(token: CheckpointToken, scope: string, outcome: ResumeOutcome, expect?: ResolveExpectation): Promise<boolean>;
|
|
959
|
+
/**
|
|
960
|
+
* Inverse of {@link resolve}: CAS `resolved → pending` (`UPDATE … SET status='pending' WHERE token=?
|
|
961
|
+
* AND scope=? AND status='resolved'`). Returns the CAS winner (`true` = was resolved → now pending again).
|
|
962
|
+
*
|
|
963
|
+
* **Compensation for a post-CAS env-restore failure (design/45/49).** `Runner.resumeStream` wins the
|
|
964
|
+
* `resolve` CAS *before* the workspace `resumeVM` runs; if that restore then fails (`resume.env_failed`)
|
|
965
|
+
* the pending action never executed yet the checkpoint is consumed — without this the suspended work is
|
|
966
|
+
* lost to a forced "re-initiate" (fine for a short approval, ruinous for a long autonomous task).
|
|
967
|
+
* Reopening lets a retry re-resume the SAME work. Optional: a store that omits it keeps the prior (lossy)
|
|
968
|
+
* behavior, and the runner degrades gracefully. Safe by the `status='resolved'` guard — only the run that
|
|
969
|
+
* consumed the checkpoint (and then failed to restore) can reopen it, and only while it is still `resolved`.
|
|
970
|
+
*
|
|
971
|
+
* **design/80 D-1 (reopen-by-reason):** the `reason` distinguishes the two reopen triggers (both shipped at
|
|
972
|
+
* runtask.ts) so re-resume can validate per reason (§3 inv #1): `env_failed` (the action is still valid,
|
|
973
|
+
* only infra failed → re-resume MUST replay the persisted {@link Checkpoint.resolvedOutcome} winner) vs
|
|
974
|
+
* `tool_unavailable` (P-7: the approved tool vanished, the action may now be invalid → a human re-decides,
|
|
975
|
+
* so a FRESH decision is allowed). The store RECORDS the reason on the row as {@link Checkpoint.reopenReason}
|
|
976
|
+
* and PRESERVES the persisted winner across the reopen (never clears it).
|
|
977
|
+
*/
|
|
978
|
+
reopen?(token: CheckpointToken, scope: string, reason: ReopenReason): Promise<boolean>;
|
|
979
|
+
/**
|
|
980
|
+
* design/80 D-A: park a durable mid-task STEER on a DURABLY-SUSPENDED task's checkpoint. CAS-style update
|
|
981
|
+
* `SET state.pendingSteer=? WHERE token=? AND scope=? AND status='pending'`: returns `true` iff the
|
|
982
|
+
* checkpoint is still `pending` (a resolved/expired checkpoint can't be steered → `false`, a no-op). Scope
|
|
983
|
+
* is in the WHERE for multi-tenant isolation, exactly like {@link resolve}/{@link expire}. Idempotent-safe:
|
|
984
|
+
* a later `setPendingSteer` overwrites the parked steer (last-writer-wins) on a still-pending checkpoint.
|
|
985
|
+
*
|
|
986
|
+
* **Trust is FROZEN here** — `steer.trusted` is whatever the SERVICE computed from the verified principal
|
|
987
|
+
* at this call (an operator-role check, NOT a client header — the service's job); the core stores it
|
|
988
|
+
* VERBATIM and NEVER recomputes it on resume (§3 inv #1).
|
|
989
|
+
*
|
|
990
|
+
* **Validation (load-bearing, §3 inv #2):** `steer.text` containing a `</system-reminder>` close tag is
|
|
991
|
+
* REJECTED with a typed {@link CheckpointError} `steering.invalid_content` (mirroring runtask.ts's trusted-
|
|
992
|
+
* steer reject) — a dirty steer NEVER enters {@link CheckpointState}, so the persisted state stays clean
|
|
993
|
+
* regardless of `trusted`. (The untrusted RESUME-injection path ALSO sanitizes the text as untrusted data;
|
|
994
|
+
* this persist-time reject is the belt that keeps a forged close tag out of the durable record on BOTH
|
|
995
|
+
* paths.) NOT an approval channel: this only writes `state.pendingSteer`, never touches status / the
|
|
996
|
+
* resolve path / any decision (§3 inv #4).
|
|
997
|
+
*/
|
|
998
|
+
setPendingSteer(token: CheckpointToken, scope: string, steer: {
|
|
999
|
+
text: string;
|
|
1000
|
+
trusted: boolean;
|
|
1001
|
+
}): Promise<boolean>;
|
|
1002
|
+
/**
|
|
1003
|
+
* CAS-expire a **single** `pending` checkpoint by token: `UPDATE … SET status='expired' WHERE token=?
|
|
1004
|
+
* AND scope=? AND status='pending'`. Returns the CAS winner (`true` = was pending → now expired; `false`
|
|
1005
|
+
* = already resolved/expired). The same UPDATE as {@link reap} but keyed by **token**, not by deadline.
|
|
1006
|
+
*
|
|
1007
|
+
* **Load-bearing contract (design/51 §2/§4):** `expire` and {@link resolve} race the **same `pending`
|
|
1008
|
+
* row**, so the store serializes them — exactly one wins. This is what makes {@link TaskStream.destroy}
|
|
1009
|
+
* a correct *fence-then-reap*: `destroy` calls `expire` FIRST to fence any concurrent `resume` (which
|
|
1010
|
+
* goes through `resolve`); only the `expire` winner then destroys the paused env, so the same checkpoint
|
|
1011
|
+
* is **never both reaped and resumed**. `scope` is in the WHERE for multi-tenant isolation, like
|
|
1012
|
+
* `resolve`/`reap`.
|
|
1013
|
+
*/
|
|
1014
|
+
expire(token: CheckpointToken, scope: string): Promise<boolean>;
|
|
1015
|
+
/**
|
|
1016
|
+
* CAS-expire `pending` checkpoints in `scope` whose `deadline` has passed (`deadline <= cutoff`):
|
|
1017
|
+
* `pending → expired`. Returns the count expired (for metrics). Idempotent across replicas (DB
|
|
1018
|
+
* serializes; only the first wins each row) — no leader election needed (§6).
|
|
1019
|
+
*
|
|
1020
|
+
* **Does NOT unpin the sessions of the checkpoints it expires (council finding #2).** A suspend pinned
|
|
1021
|
+
* its session against idle eviction; reaping the checkpoint here leaves that pin in place. The reaper
|
|
1022
|
+
* that calls `reap` owns releasing the pin. For a **durable** session store this is a no-op anyway
|
|
1023
|
+
* (`pin`/`unpin` are no-ops; it never idle-GCs), so reap-without-unpin is harmless — the only store with
|
|
1024
|
+
* a real pin is the in-memory `TtlSessionStore` (single-instance / tests), where an un-released pin
|
|
1025
|
+
* keeps an abandoned suspended session in the cache until process exit. v1 leaves the runner without an
|
|
1026
|
+
* auto-reaper (the service owns the TTL worker); a reaper over the in-memory store should track and
|
|
1027
|
+
* `unpin` the expired sessions itself if that leak matters for its deployment.
|
|
1028
|
+
*/
|
|
1029
|
+
reap(scope: string, cutoff: number): Promise<number>;
|
|
1030
|
+
/**
|
|
1031
|
+
* design/80 assistant-scheduler seam #1 (channel [148]/[149]): list a lightweight {@link CheckpointSummary}
|
|
1032
|
+
* for EVERY **pending** checkpoint in `scope` (the suspended / awaiting-human tasks — NOT resolved/expired) in
|
|
1033
|
+
* ONE call, so a supervisor scheduler can enumerate a scope's open suspensions without N+1 `get`s or hauling
|
|
1034
|
+
* full {@link Checkpoint} payloads. Read-only — it never mutates a row, takes no CAS, and has ZERO effect on
|
|
1035
|
+
* the once-only resolve. The PENDING predicate is byte-for-byte the {@link resolve} CAS's (`scope === scope &&
|
|
1036
|
+
* status === 'pending'`), so the list reflects exactly the rows that are still resumable. Order is unspecified
|
|
1037
|
+
* (the inbox sorts by `severity`/`deadline` itself). An empty scope returns `[]`.
|
|
1038
|
+
*
|
|
1039
|
+
* **OPTIONAL** for backward-compat with external {@link CheckpointStore} impls (a caller probes
|
|
1040
|
+
* `store.listByScope?.(scope) ?? []`); ALL THREE first-party impls (in-memory, file, Pg) provide it.
|
|
1041
|
+
*/
|
|
1042
|
+
listByScope?(scope: string): Promise<CheckpointSummary[]>;
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* design/80 D-1 (persist-winner): derive the durable {@link ResolvedOutcome} winner from a resume
|
|
1046
|
+
* `outcome`, or `undefined` when the outcome binds to no pending action. Only a `policy_ask` resume names
|
|
1047
|
+
* a specific tool call (`boundCallId`) + decision worth recording; `resource_limit` / `dry_run_review` /
|
|
1048
|
+
* `task_done` have nothing to bind, so they record no winner. Shared by every {@link CheckpointStore} impl
|
|
1049
|
+
* so the persisted winner is identical across the in-memory and durable backends.
|
|
1050
|
+
*/
|
|
1051
|
+
export declare function winnerFromOutcome(outcome: ResumeOutcome): ResolvedOutcome | undefined;
|
|
1052
|
+
/**
|
|
1053
|
+
* design/80 D-A: the persist-time validation every {@link CheckpointStore.setPendingSteer} impl runs so the
|
|
1054
|
+
* reject is IDENTICAL across the in-memory and durable backends. A `steer.text` carrying a `</system-reminder>`
|
|
1055
|
+
* close tag would escape the model-facing `<system-reminder>` wrapper a trusted steer rides on resume — reject
|
|
1056
|
+
* fail-closed (`steering.invalid_content`) so a dirty steer NEVER enters {@link CheckpointState} (§3 inv #2).
|
|
1057
|
+
* Applied for BOTH `trusted` values: the durable record must be clean on either path (the untrusted resume
|
|
1058
|
+
* path ALSO sanitizes as untrusted data, but the close tag must never reach the persisted state at all).
|
|
1059
|
+
* Returns a frozen-trust copy (`{ text, trusted }` only) so no extra caller field leaks into the row.
|
|
1060
|
+
*/
|
|
1061
|
+
export declare function validatePendingSteer(steer: {
|
|
1062
|
+
text: string;
|
|
1063
|
+
trusted: boolean;
|
|
1064
|
+
}): {
|
|
1065
|
+
text: string;
|
|
1066
|
+
trusted: boolean;
|
|
1067
|
+
};
|
|
1068
|
+
/** Fault-injection mode for {@link InMemoryCheckpointStore.testInjectFault} (council #5). One-shot. */
|
|
1069
|
+
export type CheckpointFaultMode =
|
|
1070
|
+
/** `resolve` commits the CAS (status → resolved) then throws — simulates a crash *after* the commit
|
|
1071
|
+
* but before the caller is acked, so a retry must see `resolved` and NOT re-execute (idempotency). */
|
|
1072
|
+
"resolve-after-commit"
|
|
1073
|
+
/** `resolve` throws *before* the CAS — simulates a crash before the commit; the row stays `pending`
|
|
1074
|
+
* so a retry can still win it. */
|
|
1075
|
+
| "resolve-before-commit";
|
|
1076
|
+
/**
|
|
1077
|
+
* Default in-process {@link CheckpointStore}. Single-instance / tests only — it does NOT survive a
|
|
1078
|
+
* restart or span replicas, so it cannot deliver the cross-process guarantee a durable backend does.
|
|
1079
|
+
* Single-threaded JS already serializes `resolve`, so the CAS is trivially atomic here;
|
|
1080
|
+
* {@link testInjectFault} simulates the crash-recovery races a real backend must survive.
|
|
1081
|
+
*/
|
|
1082
|
+
export declare class InMemoryCheckpointStore implements CheckpointStore {
|
|
1083
|
+
private cps;
|
|
1084
|
+
private fault;
|
|
1085
|
+
put(token: CheckpointToken, cp: Checkpoint): Promise<void>;
|
|
1086
|
+
get(token: CheckpointToken): Promise<Checkpoint | null>;
|
|
1087
|
+
resolve(token: CheckpointToken, scope: string, outcome: ResumeOutcome, expect?: ResolveExpectation): Promise<boolean>;
|
|
1088
|
+
reopen(token: CheckpointToken, scope: string, reason: ReopenReason): Promise<boolean>;
|
|
1089
|
+
setPendingSteer(token: CheckpointToken, scope: string, steer: {
|
|
1090
|
+
text: string;
|
|
1091
|
+
trusted: boolean;
|
|
1092
|
+
}): Promise<boolean>;
|
|
1093
|
+
expire(token: CheckpointToken, scope: string): Promise<boolean>;
|
|
1094
|
+
reap(scope: string, cutoff: number): Promise<number>;
|
|
1095
|
+
listByScope(scope: string): Promise<CheckpointSummary[]>;
|
|
1096
|
+
/** Arm a one-shot fault on the next `resolve` (council #5: makes crash-recovery unit-testable). */
|
|
1097
|
+
testInjectFault(mode: CheckpointFaultMode | null): void;
|
|
1098
|
+
/** Test/inspection helper: number of stored checkpoints. */
|
|
1099
|
+
get size(): number;
|
|
1100
|
+
}
|
|
1101
|
+
//# sourceMappingURL=checkpoint-store.d.ts.map
|