open-multi-agent-kit 1.2.0 → 1.2.3
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 +54 -0
- package/README.md +2 -2
- package/dist/approval-api.d.ts +5 -0
- package/dist/approval-api.d.ts.map +1 -0
- package/dist/approval-api.js +5 -0
- package/dist/approval-api.js.map +1 -0
- package/dist/cli/session-picker.d.ts +2 -2
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/commands/verified-run-cli.d.ts.map +1 -1
- package/dist/commands/verified-run-cli.js +69 -22
- package/dist/commands/verified-run-cli.js.map +1 -1
- package/dist/commands/verified-run-signal.d.ts +3 -0
- package/dist/commands/verified-run-signal.d.ts.map +1 -0
- package/dist/commands/verified-run-signal.js +15 -0
- package/dist/commands/verified-run-signal.js.map +1 -0
- package/dist/coordination/broker.d.ts.map +1 -1
- package/dist/coordination/broker.js +13 -6
- package/dist/coordination/broker.js.map +1 -1
- package/dist/coordination/operation.d.ts +1 -0
- package/dist/coordination/operation.d.ts.map +1 -1
- package/dist/coordination/operation.js +55 -3
- package/dist/coordination/operation.js.map +1 -1
- package/dist/coordination/resource.d.ts +1 -1
- package/dist/coordination/resource.d.ts.map +1 -1
- package/dist/coordination/resource.js +10 -4
- package/dist/coordination/resource.js.map +1 -1
- package/dist/coordination/types.d.ts.map +1 -1
- package/dist/coordination/types.js +1 -1
- package/dist/coordination/types.js.map +1 -1
- package/dist/core/adaptorch-bridge.d.ts +1 -1
- package/dist/core/adaptorch-bridge.d.ts.map +1 -1
- package/dist/core/adaptorch-bridge.js +1 -1
- package/dist/core/adaptorch-bridge.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +16 -16
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +32 -33
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/canonical-json.d.ts +3 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +20 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +7 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +14 -29
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/fallback.d.ts +16 -5
- package/dist/core/compaction/fallback.d.ts.map +1 -1
- package/dist/core/compaction/fallback.js +4 -3
- package/dist/core/compaction/fallback.js.map +1 -1
- package/dist/core/compaction/model-failover.d.ts +21 -0
- package/dist/core/compaction/model-failover.d.ts.map +1 -0
- package/dist/core/compaction/model-failover.js +46 -0
- package/dist/core/compaction/model-failover.js.map +1 -0
- package/dist/core/compaction/session-summary.d.ts +21 -0
- package/dist/core/compaction/session-summary.d.ts.map +1 -0
- package/dist/core/compaction/session-summary.js +27 -0
- package/dist/core/compaction/session-summary.js.map +1 -0
- package/dist/core/export-html/template.js +14 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/session-lifecycle-types.d.ts +14 -0
- package/dist/core/extensions/session-lifecycle-types.d.ts.map +1 -0
- package/dist/core/extensions/session-lifecycle-types.js +2 -0
- package/dist/core/extensions/session-lifecycle-types.js.map +1 -0
- package/dist/core/extensions/types.d.ts +4 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +10 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +3 -6
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/legacy-resource-policy.d.ts +7 -0
- package/dist/core/legacy-resource-policy.d.ts.map +1 -0
- package/dist/core/legacy-resource-policy.js +9 -0
- package/dist/core/legacy-resource-policy.js.map +1 -0
- package/dist/core/mcp/config.d.ts.map +1 -1
- package/dist/core/mcp/config.js +17 -3
- package/dist/core/mcp/config.js.map +1 -1
- package/dist/core/mcp/connection-queue.d.ts +12 -0
- package/dist/core/mcp/connection-queue.d.ts.map +1 -0
- package/dist/core/mcp/connection-queue.js +46 -0
- package/dist/core/mcp/connection-queue.js.map +1 -0
- package/dist/core/mcp/manager-runtime.d.ts +55 -0
- package/dist/core/mcp/manager-runtime.d.ts.map +1 -0
- package/dist/core/mcp/manager-runtime.js +66 -0
- package/dist/core/mcp/manager-runtime.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +12 -68
- package/dist/core/mcp/manager.d.ts.map +1 -1
- package/dist/core/mcp/manager.js +33 -113
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/protocol.d.ts.map +1 -1
- package/dist/core/mcp/protocol.js +70 -40
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +59 -129
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-resource-patterns.d.ts +7 -0
- package/dist/core/package-resource-patterns.d.ts.map +1 -0
- package/dist/core/package-resource-patterns.js +99 -0
- package/dist/core/package-resource-patterns.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +9 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +15 -0
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts +5 -2
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +4 -8
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/run-execution-api.d.ts +8 -1
- package/dist/core/run-execution-api.d.ts.map +1 -1
- package/dist/core/run-execution-api.js +4 -0
- package/dist/core/run-execution-api.js.map +1 -1
- package/dist/core/run-journal.d.ts +1 -2
- package/dist/core/run-journal.d.ts.map +1 -1
- package/dist/core/run-journal.js +2 -19
- package/dist/core/run-journal.js.map +1 -1
- package/dist/core/session-listing.d.ts +51 -0
- package/dist/core/session-listing.d.ts.map +1 -0
- package/dist/core/session-listing.js +111 -0
- package/dist/core/session-listing.js.map +1 -0
- package/dist/core/session-manager.d.ts +12 -37
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +12 -118
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-message-text.d.ts +5 -0
- package/dist/core/session-message-text.d.ts.map +1 -0
- package/dist/core/session-message-text.js +9 -0
- package/dist/core/session-message-text.js.map +1 -0
- package/dist/core/skills-catalog-cache.d.ts +2 -0
- package/dist/core/skills-catalog-cache.d.ts.map +1 -1
- package/dist/core/skills-catalog-cache.js +71 -17
- package/dist/core/skills-catalog-cache.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/verified-run/authority-clock.d.ts +3 -0
- package/dist/core/verified-run/authority-clock.d.ts.map +1 -0
- package/dist/core/verified-run/authority-clock.js +25 -0
- package/dist/core/verified-run/authority-clock.js.map +1 -0
- package/dist/core/verified-run/authority-errors.d.ts +10 -0
- package/dist/core/verified-run/authority-errors.d.ts.map +1 -0
- package/dist/core/verified-run/authority-errors.js +17 -0
- package/dist/core/verified-run/authority-errors.js.map +1 -0
- package/dist/core/verified-run/authority-events.d.ts +126 -0
- package/dist/core/verified-run/authority-events.d.ts.map +1 -0
- package/dist/core/verified-run/authority-events.js +482 -0
- package/dist/core/verified-run/authority-events.js.map +1 -0
- package/dist/core/verified-run/authority-journal.d.ts +27 -0
- package/dist/core/verified-run/authority-journal.d.ts.map +1 -0
- package/dist/core/verified-run/authority-journal.js +83 -0
- package/dist/core/verified-run/authority-journal.js.map +1 -0
- package/dist/core/verified-run/authority-meaning.d.ts +13 -0
- package/dist/core/verified-run/authority-meaning.d.ts.map +1 -0
- package/dist/core/verified-run/authority-meaning.js +40 -0
- package/dist/core/verified-run/authority-meaning.js.map +1 -0
- package/dist/core/verified-run/authority-runtime.d.ts +82 -0
- package/dist/core/verified-run/authority-runtime.d.ts.map +1 -0
- package/dist/core/verified-run/authority-runtime.js +169 -0
- package/dist/core/verified-run/authority-runtime.js.map +1 -0
- package/dist/core/verified-run/authority-store.d.ts +204 -0
- package/dist/core/verified-run/authority-store.d.ts.map +1 -0
- package/dist/core/verified-run/authority-store.js +852 -0
- package/dist/core/verified-run/authority-store.js.map +1 -0
- package/dist/core/verified-run/broker.d.ts +8 -1
- package/dist/core/verified-run/broker.d.ts.map +1 -1
- package/dist/core/verified-run/broker.js +94 -90
- package/dist/core/verified-run/broker.js.map +1 -1
- package/dist/core/verified-run/candidate-policy.d.ts +10 -0
- package/dist/core/verified-run/candidate-policy.d.ts.map +1 -0
- package/dist/core/verified-run/candidate-policy.js +33 -0
- package/dist/core/verified-run/candidate-policy.js.map +1 -0
- package/dist/core/verified-run/candidate.d.ts.map +1 -1
- package/dist/core/verified-run/candidate.js +5 -10
- package/dist/core/verified-run/candidate.js.map +1 -1
- package/dist/core/verified-run/coordinator.d.ts +35 -17
- package/dist/core/verified-run/coordinator.d.ts.map +1 -1
- package/dist/core/verified-run/coordinator.js +111 -57
- package/dist/core/verified-run/coordinator.js.map +1 -1
- package/dist/core/verified-run/dag-phase.d.ts.map +1 -1
- package/dist/core/verified-run/dag-phase.js +1 -1
- package/dist/core/verified-run/dag-phase.js.map +1 -1
- package/dist/core/verified-run/dag-recovery.d.ts +5 -1
- package/dist/core/verified-run/dag-recovery.d.ts.map +1 -1
- package/dist/core/verified-run/dag-recovery.js +10 -4
- package/dist/core/verified-run/dag-recovery.js.map +1 -1
- package/dist/core/verified-run/event-parser.d.ts.map +1 -1
- package/dist/core/verified-run/event-parser.js +33 -0
- package/dist/core/verified-run/event-parser.js.map +1 -1
- package/dist/core/verified-run/evidence-read-projection.d.ts +4 -0
- package/dist/core/verified-run/evidence-read-projection.d.ts.map +1 -0
- package/dist/core/verified-run/evidence-read-projection.js +27 -0
- package/dist/core/verified-run/evidence-read-projection.js.map +1 -0
- package/dist/core/verified-run/evidence.d.ts +12 -1
- package/dist/core/verified-run/evidence.d.ts.map +1 -1
- package/dist/core/verified-run/evidence.js +51 -2
- package/dist/core/verified-run/evidence.js.map +1 -1
- package/dist/core/verified-run/git-candidate-preflight.d.ts +4 -0
- package/dist/core/verified-run/git-candidate-preflight.d.ts.map +1 -0
- package/dist/core/verified-run/git-candidate-preflight.js +34 -0
- package/dist/core/verified-run/git-candidate-preflight.js.map +1 -0
- package/dist/core/verified-run/git-effect-supervisor.d.ts +24 -0
- package/dist/core/verified-run/git-effect-supervisor.d.ts.map +1 -0
- package/dist/core/verified-run/git-effect-supervisor.js +174 -0
- package/dist/core/verified-run/git-effect-supervisor.js.map +1 -0
- package/dist/core/verified-run/git-execution.d.ts +27 -0
- package/dist/core/verified-run/git-execution.d.ts.map +1 -0
- package/dist/core/verified-run/git-execution.js +118 -0
- package/dist/core/verified-run/git-execution.js.map +1 -0
- package/dist/core/verified-run/git-plumbing.d.ts +37 -0
- package/dist/core/verified-run/git-plumbing.d.ts.map +1 -0
- package/dist/core/verified-run/git-plumbing.js +171 -0
- package/dist/core/verified-run/git-plumbing.js.map +1 -0
- package/dist/core/verified-run/git-publication-worker.d.ts +2 -0
- package/dist/core/verified-run/git-publication-worker.d.ts.map +1 -0
- package/dist/core/verified-run/git-publication-worker.js +54 -0
- package/dist/core/verified-run/git-publication-worker.js.map +1 -0
- package/dist/core/verified-run/git-sandbox-layout.d.ts +4 -0
- package/dist/core/verified-run/git-sandbox-layout.d.ts.map +1 -0
- package/dist/core/verified-run/git-sandbox-layout.js +29 -0
- package/dist/core/verified-run/git-sandbox-layout.js.map +1 -0
- package/dist/core/verified-run/git-worker-protocol.d.ts +19 -0
- package/dist/core/verified-run/git-worker-protocol.d.ts.map +1 -0
- package/dist/core/verified-run/git-worker-protocol.js +109 -0
- package/dist/core/verified-run/git-worker-protocol.js.map +1 -0
- package/dist/core/verified-run/git-worker-runtime.d.ts +19 -0
- package/dist/core/verified-run/git-worker-runtime.d.ts.map +1 -0
- package/dist/core/verified-run/git-worker-runtime.js +74 -0
- package/dist/core/verified-run/git-worker-runtime.js.map +1 -0
- package/dist/core/verified-run/journal.d.ts +2 -3
- package/dist/core/verified-run/journal.d.ts.map +1 -1
- package/dist/core/verified-run/journal.js.map +1 -1
- package/dist/core/verified-run/namespace-identity.d.ts.map +1 -1
- package/dist/core/verified-run/namespace-identity.js +1 -1
- package/dist/core/verified-run/namespace-identity.js.map +1 -1
- package/dist/core/verified-run/owned-execution.d.ts +10 -1
- package/dist/core/verified-run/owned-execution.d.ts.map +1 -1
- package/dist/core/verified-run/owned-execution.js +124 -31
- package/dist/core/verified-run/owned-execution.js.map +1 -1
- package/dist/core/verified-run/phase-context.d.ts +2 -0
- package/dist/core/verified-run/phase-context.d.ts.map +1 -1
- package/dist/core/verified-run/phase-context.js.map +1 -1
- package/dist/core/verified-run/projection.d.ts.map +1 -1
- package/dist/core/verified-run/projection.js +51 -1
- package/dist/core/verified-run/projection.js.map +1 -1
- package/dist/core/verified-run/publish-preflight.d.ts +12 -0
- package/dist/core/verified-run/publish-preflight.d.ts.map +1 -0
- package/dist/core/verified-run/publish-preflight.js +38 -0
- package/dist/core/verified-run/publish-preflight.js.map +1 -0
- package/dist/core/verified-run/publish-start.d.ts +5 -0
- package/dist/core/verified-run/publish-start.d.ts.map +1 -0
- package/dist/core/verified-run/publish-start.js +7 -0
- package/dist/core/verified-run/publish-start.js.map +1 -0
- package/dist/core/verified-run/recovery-projection.d.ts.map +1 -1
- package/dist/core/verified-run/recovery-projection.js +5 -0
- package/dist/core/verified-run/recovery-projection.js.map +1 -1
- package/dist/core/verified-run/recovery.d.ts +5 -1
- package/dist/core/verified-run/recovery.d.ts.map +1 -1
- package/dist/core/verified-run/recovery.js +10 -4
- package/dist/core/verified-run/recovery.js.map +1 -1
- package/dist/core/verified-run/run-plan.d.ts +17 -0
- package/dist/core/verified-run/run-plan.d.ts.map +1 -0
- package/dist/core/verified-run/run-plan.js +18 -0
- package/dist/core/verified-run/run-plan.js.map +1 -0
- package/dist/core/verified-run/run-publish-owned.d.ts +6 -0
- package/dist/core/verified-run/run-publish-owned.d.ts.map +1 -0
- package/dist/core/verified-run/run-publish-owned.js +199 -0
- package/dist/core/verified-run/run-publish-owned.js.map +1 -0
- package/dist/core/verified-run/run-publish.d.ts +19 -0
- package/dist/core/verified-run/run-publish.d.ts.map +1 -0
- package/dist/core/verified-run/run-publish.js +210 -0
- package/dist/core/verified-run/run-publish.js.map +1 -0
- package/dist/core/verified-run/run-status-owned.d.ts +4 -0
- package/dist/core/verified-run/run-status-owned.d.ts.map +1 -0
- package/dist/core/verified-run/run-status-owned.js +14 -0
- package/dist/core/verified-run/run-status-owned.js.map +1 -0
- package/dist/core/verified-run/run-status.d.ts +133 -0
- package/dist/core/verified-run/run-status.d.ts.map +1 -0
- package/dist/core/verified-run/run-status.js +193 -0
- package/dist/core/verified-run/run-status.js.map +1 -0
- package/dist/core/verified-run/run-types.d.ts +31 -0
- package/dist/core/verified-run/run-types.d.ts.map +1 -1
- package/dist/core/verified-run/run-types.js.map +1 -1
- package/dist/core/verified-run/storage.d.ts.map +1 -1
- package/dist/core/verified-run/storage.js +1 -1
- package/dist/core/verified-run/storage.js.map +1 -1
- package/dist/core/verified-run/supervisor-adapter.d.ts +81 -0
- package/dist/core/verified-run/supervisor-adapter.d.ts.map +1 -0
- package/dist/core/verified-run/supervisor-adapter.js +168 -0
- package/dist/core/verified-run/supervisor-adapter.js.map +1 -0
- package/dist/core/verified-run/verification-phase.d.ts.map +1 -1
- package/dist/core/verified-run/verification-phase.js +1 -1
- package/dist/core/verified-run/verification-phase.js.map +1 -1
- package/dist/core/verified-run/writer-phase.d.ts.map +1 -1
- package/dist/core/verified-run/writer-phase.js +1 -0
- package/dist/core/verified-run/writer-phase.js.map +1 -1
- package/dist/core/verified-run/writer-recovery.d.ts +2 -0
- package/dist/core/verified-run/writer-recovery.d.ts.map +1 -1
- package/dist/core/verified-run/writer-recovery.js +1 -0
- package/dist/core/verified-run/writer-recovery.js.map +1 -1
- package/dist/core/workload-shard-execution-types.d.ts +4 -1
- package/dist/core/workload-shard-execution-types.d.ts.map +1 -1
- package/dist/core/workload-shard-execution-types.js.map +1 -1
- package/dist/core/workload-shard-executor.d.ts +2 -2
- package/dist/core/workload-shard-executor.d.ts.map +1 -1
- package/dist/core/workload-shard-executor.js +16 -37
- package/dist/core/workload-shard-executor.js.map +1 -1
- package/dist/core/workload-shard-frontier.d.ts +5 -0
- package/dist/core/workload-shard-frontier.d.ts.map +1 -0
- package/dist/core/workload-shard-frontier.js +47 -0
- package/dist/core/workload-shard-frontier.js.map +1 -0
- package/dist/core/workload-shard-runner.d.ts.map +1 -1
- package/dist/core/workload-shard-runner.js +28 -17
- package/dist/core/workload-shard-runner.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -1
- package/dist/main.js.map +1 -1
- package/dist/metacognition/bridge-result.d.ts +148 -0
- package/dist/metacognition/bridge-result.d.ts.map +1 -0
- package/dist/metacognition/bridge-result.js +46 -0
- package/dist/metacognition/bridge-result.js.map +1 -0
- package/dist/metacognition/calibration-selective.d.ts.map +1 -1
- package/dist/metacognition/calibration-selective.js +8 -2
- package/dist/metacognition/calibration-selective.js.map +1 -1
- package/dist/metacognition/index.d.ts +1 -0
- package/dist/metacognition/index.d.ts.map +1 -1
- package/dist/metacognition/index.js +1 -0
- package/dist/metacognition/index.js.map +1 -1
- package/dist/metacognition/risk.d.ts.map +1 -1
- package/dist/metacognition/risk.js +28 -14
- package/dist/metacognition/risk.js.map +1 -1
- package/dist/metacognition/runtime-bridge.d.ts +41 -14
- package/dist/metacognition/runtime-bridge.d.ts.map +1 -1
- package/dist/metacognition/runtime-bridge.js +357 -39
- package/dist/metacognition/runtime-bridge.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +2 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +42 -26
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-container.d.ts +7 -0
- package/dist/modes/interactive/components/chat-container.d.ts.map +1 -0
- package/dist/modes/interactive/components/chat-container.js +14 -0
- package/dist/modes/interactive/components/chat-container.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +4 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +0 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-async-search.d.ts +33 -0
- package/dist/modes/interactive/components/session-selector-async-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-async-search.js +109 -0
- package/dist/modes/interactive/components/session-selector-async-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-loaders.d.ts +6 -0
- package/dist/modes/interactive/components/session-selector-loaders.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-loaders.js +9 -0
- package/dist/modes/interactive/components/session-selector-loaders.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-tree.d.ts +16 -0
- package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-tree.js +46 -0
- package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +6 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +36 -76
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution-images.d.ts +32 -0
- package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution-images.js +144 -0
- package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +3 -4
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +22 -71
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -9
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tui-diagnostics.d.ts +8 -4
- package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -1
- package/dist/modes/interactive/tui-diagnostics.js +35 -1
- package/dist/modes/interactive/tui-diagnostics.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +14 -17
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-response.d.ts +5 -0
- package/dist/modes/rpc/rpc-response.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-response.js +17 -0
- package/dist/modes/rpc/rpc-response.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +3 -5
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/adaptorch-preview-spec.md +7 -7
- package/docs/atomic-commit-planning.md +69 -0
- package/docs/compaction.md +26 -1
- package/docs/extensions.md +14 -0
- package/docs/mcp.md +22 -0
- package/docs/metacognition.md +79 -0
- package/docs/model-catalog-refresh.md +159 -1
- package/docs/models.md +1 -1
- package/docs/runtime-algorithms.md +49 -4
- package/docs/session-format.md +8 -0
- package/docs/sessions.md +19 -0
- package/docs/skills.md +19 -0
- package/docs/terminal-setup.md +15 -0
- package/docs/tui.md +41 -0
- package/docs/verified-run-safety.md +75 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +6 -8
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { renameSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { fsyncDirectorySync } from "../durable-file-io.js";
|
|
4
|
+
import { preflightGitCandidate } from "./git-candidate-preflight.js";
|
|
5
|
+
import { digestObject, publishObject, readJson, VerifiedRunError } from "./storage.js";
|
|
6
|
+
function object(value) {
|
|
7
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
8
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function text(value, pattern) {
|
|
12
|
+
if (typeof value !== "string" || !pattern.test(value))
|
|
13
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
const DIGEST = /^[a-f0-9]{64}$/;
|
|
17
|
+
const OID = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;
|
|
18
|
+
export function writeGitControl(path, value) {
|
|
19
|
+
const temporary = `${path}.tmp`;
|
|
20
|
+
publishObject(temporary, value);
|
|
21
|
+
renameSync(temporary, path);
|
|
22
|
+
fsyncDirectorySync(dirname(path));
|
|
23
|
+
}
|
|
24
|
+
export function serializeGitRequest(request) {
|
|
25
|
+
return {
|
|
26
|
+
version: 1,
|
|
27
|
+
...request.input,
|
|
28
|
+
contents: [...request.input.contents].map(([digest, bytes]) => ({ digest, bytes: bytes.toString("base64") })),
|
|
29
|
+
timeoutMs: request.timeoutMs,
|
|
30
|
+
deadlineNs: request.deadlineNs,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function readGitRequest(path) {
|
|
34
|
+
const raw = object(readJson(path, 128 * 1024 * 1024));
|
|
35
|
+
if (raw.version !== 1 ||
|
|
36
|
+
typeof raw.timeoutMs !== "number" ||
|
|
37
|
+
!Number.isSafeInteger(raw.timeoutMs) ||
|
|
38
|
+
raw.timeoutMs <= 0 ||
|
|
39
|
+
raw.timeoutMs > 60_000)
|
|
40
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
41
|
+
const manifest = object(raw.manifest);
|
|
42
|
+
if (manifest.version !== 1 ||
|
|
43
|
+
!Array.isArray(manifest.files) ||
|
|
44
|
+
!Array.isArray(manifest.directories) ||
|
|
45
|
+
!Array.isArray(raw.contents))
|
|
46
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
47
|
+
const directories = manifest.directories.map((entry) => text(entry, /^.{1,4096}$/u));
|
|
48
|
+
const files = manifest.files.map((entry) => {
|
|
49
|
+
const file = object(entry);
|
|
50
|
+
if (typeof file.mode !== "number" || typeof file.size !== "number")
|
|
51
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
52
|
+
return {
|
|
53
|
+
path: text(file.path, /^.{1,4096}$/u),
|
|
54
|
+
mode: file.mode,
|
|
55
|
+
size: file.size,
|
|
56
|
+
digest: text(file.digest, DIGEST),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
const contents = new Map();
|
|
60
|
+
for (const entry of raw.contents) {
|
|
61
|
+
const blob = object(entry);
|
|
62
|
+
const digest = text(blob.digest, DIGEST);
|
|
63
|
+
if (typeof blob.bytes !== "string" || contents.has(digest))
|
|
64
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
65
|
+
contents.set(digest, Buffer.from(blob.bytes, "base64"));
|
|
66
|
+
}
|
|
67
|
+
const candidate = { version: 1, directories, files };
|
|
68
|
+
preflightGitCandidate(candidate, contents);
|
|
69
|
+
const candidateDigest = text(raw.candidateDigest, DIGEST);
|
|
70
|
+
if (digestObject(candidate) !== candidateDigest)
|
|
71
|
+
throw new VerifiedRunError("integrity");
|
|
72
|
+
const parentOid = text(raw.parentOid, OID);
|
|
73
|
+
const zeroOid = text(raw.zeroOid, /^(?:0{40}|0{64})$/);
|
|
74
|
+
if (parentOid.length !== zeroOid.length)
|
|
75
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
76
|
+
return {
|
|
77
|
+
timeoutMs: raw.timeoutMs,
|
|
78
|
+
deadlineNs: text(raw.deadlineNs, /^\d{1,24}$/),
|
|
79
|
+
input: {
|
|
80
|
+
manifest: candidate,
|
|
81
|
+
contents,
|
|
82
|
+
candidateDigest,
|
|
83
|
+
parentOid,
|
|
84
|
+
zeroOid,
|
|
85
|
+
runId: text(raw.runId, /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/),
|
|
86
|
+
receiptDigest: text(raw.receiptDigest, DIGEST),
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function readGitStartGate(path) {
|
|
91
|
+
const raw = object(readJson(path, 4096));
|
|
92
|
+
if (raw.kind !== "prepared" ||
|
|
93
|
+
typeof raw.authorizationDeadline !== "number" ||
|
|
94
|
+
!Number.isSafeInteger(raw.authorizationDeadline) ||
|
|
95
|
+
Date.now() >= raw.authorizationDeadline)
|
|
96
|
+
throw new VerifiedRunError("authority");
|
|
97
|
+
return {
|
|
98
|
+
kind: "prepared",
|
|
99
|
+
candidateOid: text(raw.candidateOid, OID),
|
|
100
|
+
authorizationDeadline: raw.authorizationDeadline,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export function readGitNotice(path) {
|
|
104
|
+
const raw = object(readJson(path, 4096));
|
|
105
|
+
if (raw.kind !== "prepared" && raw.kind !== "committed" && raw.kind !== "ref-rejected")
|
|
106
|
+
throw new VerifiedRunError("git_worker_protocol");
|
|
107
|
+
return { kind: raw.kind, candidateOid: text(raw.candidateOid, OID) };
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=git-worker-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-worker-protocol.js","sourceRoot":"","sources":["../../../src/core/verified-run/git-worker-protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { renameSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { fsyncDirectorySync } from \"../durable-file-io.ts\";\nimport type { CandidateFile, CandidateManifest } from \"./candidate.ts\";\nimport { preflightGitCandidate } from \"./git-candidate-preflight.ts\";\nimport type { SealCandidateInput } from \"./git-plumbing.ts\";\nimport { digestObject, publishObject, readJson, VerifiedRunError } from \"./storage.ts\";\n\nexport interface GitWorkerRequest {\n\treadonly input: SealCandidateInput;\n\treadonly timeoutMs: number;\n\t/** Linux CLOCK_MONOTONIC deadline, shared across the host and its PID namespace. */\n\treadonly deadlineNs: string;\n}\nexport interface GitWorkerNotice {\n\treadonly kind: \"prepared\" | \"committed\" | \"ref-rejected\";\n\treadonly candidateOid: string;\n}\n\nfunction object(value: unknown): Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw new VerifiedRunError(\"git_worker_protocol\");\n\treturn value as Record<string, unknown>;\n}\nfunction text(value: unknown, pattern: RegExp): string {\n\tif (typeof value !== \"string\" || !pattern.test(value)) throw new VerifiedRunError(\"git_worker_protocol\");\n\treturn value;\n}\nconst DIGEST = /^[a-f0-9]{64}$/;\nconst OID = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;\n\nexport function writeGitControl(path: string, value: unknown): void {\n\tconst temporary = `${path}.tmp`;\n\tpublishObject(temporary, value);\n\trenameSync(temporary, path);\n\tfsyncDirectorySync(dirname(path));\n}\n\nexport function serializeGitRequest(request: GitWorkerRequest): unknown {\n\treturn {\n\t\tversion: 1,\n\t\t...request.input,\n\t\tcontents: [...request.input.contents].map(([digest, bytes]) => ({ digest, bytes: bytes.toString(\"base64\") })),\n\t\ttimeoutMs: request.timeoutMs,\n\t\tdeadlineNs: request.deadlineNs,\n\t};\n}\n\nexport function readGitRequest(path: string): GitWorkerRequest {\n\tconst raw = object(readJson(path, 128 * 1024 * 1024));\n\tif (\n\t\traw.version !== 1 ||\n\t\ttypeof raw.timeoutMs !== \"number\" ||\n\t\t!Number.isSafeInteger(raw.timeoutMs) ||\n\t\traw.timeoutMs <= 0 ||\n\t\traw.timeoutMs > 60_000\n\t)\n\t\tthrow new VerifiedRunError(\"git_worker_protocol\");\n\tconst manifest = object(raw.manifest);\n\tif (\n\t\tmanifest.version !== 1 ||\n\t\t!Array.isArray(manifest.files) ||\n\t\t!Array.isArray(manifest.directories) ||\n\t\t!Array.isArray(raw.contents)\n\t)\n\t\tthrow new VerifiedRunError(\"git_worker_protocol\");\n\tconst directories = manifest.directories.map((entry: unknown) => text(entry, /^.{1,4096}$/u));\n\tconst files: CandidateFile[] = manifest.files.map((entry: unknown) => {\n\t\tconst file = object(entry);\n\t\tif (typeof file.mode !== \"number\" || typeof file.size !== \"number\")\n\t\t\tthrow new VerifiedRunError(\"git_worker_protocol\");\n\t\treturn {\n\t\t\tpath: text(file.path, /^.{1,4096}$/u),\n\t\t\tmode: file.mode,\n\t\t\tsize: file.size,\n\t\t\tdigest: text(file.digest, DIGEST),\n\t\t};\n\t});\n\tconst contents = new Map<string, Buffer>();\n\tfor (const entry of raw.contents) {\n\t\tconst blob = object(entry);\n\t\tconst digest = text(blob.digest, DIGEST);\n\t\tif (typeof blob.bytes !== \"string\" || contents.has(digest)) throw new VerifiedRunError(\"git_worker_protocol\");\n\t\tcontents.set(digest, Buffer.from(blob.bytes, \"base64\"));\n\t}\n\tconst candidate: CandidateManifest = { version: 1, directories, files };\n\tpreflightGitCandidate(candidate, contents);\n\tconst candidateDigest = text(raw.candidateDigest, DIGEST);\n\tif (digestObject(candidate) !== candidateDigest) throw new VerifiedRunError(\"integrity\");\n\tconst parentOid = text(raw.parentOid, OID);\n\tconst zeroOid = text(raw.zeroOid, /^(?:0{40}|0{64})$/);\n\tif (parentOid.length !== zeroOid.length) throw new VerifiedRunError(\"git_worker_protocol\");\n\treturn {\n\t\ttimeoutMs: raw.timeoutMs,\n\t\tdeadlineNs: text(raw.deadlineNs, /^\\d{1,24}$/),\n\t\tinput: {\n\t\t\tmanifest: candidate,\n\t\t\tcontents,\n\t\t\tcandidateDigest,\n\t\t\tparentOid,\n\t\t\tzeroOid,\n\t\t\trunId: text(raw.runId, /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/),\n\t\t\treceiptDigest: text(raw.receiptDigest, DIGEST),\n\t\t},\n\t};\n}\n\nexport function readGitStartGate(path: string): GitWorkerNotice & { readonly authorizationDeadline: number } {\n\tconst raw = object(readJson(path, 4096));\n\tif (\n\t\traw.kind !== \"prepared\" ||\n\t\ttypeof raw.authorizationDeadline !== \"number\" ||\n\t\t!Number.isSafeInteger(raw.authorizationDeadline) ||\n\t\tDate.now() >= raw.authorizationDeadline\n\t)\n\t\tthrow new VerifiedRunError(\"authority\");\n\treturn {\n\t\tkind: \"prepared\",\n\t\tcandidateOid: text(raw.candidateOid, OID),\n\t\tauthorizationDeadline: raw.authorizationDeadline,\n\t};\n}\n\nexport function readGitNotice(path: string): GitWorkerNotice {\n\tconst raw = object(readJson(path, 4096));\n\tif (raw.kind !== \"prepared\" && raw.kind !== \"committed\" && raw.kind !== \"ref-rejected\")\n\t\tthrow new VerifiedRunError(\"git_worker_protocol\");\n\treturn { kind: raw.kind, candidateOid: text(raw.candidateOid, OID) };\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type GitWorkerRequest } from "./git-worker-protocol.ts";
|
|
2
|
+
export interface GitWorkerRuntime {
|
|
3
|
+
readonly files: readonly {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly bytes: Buffer;
|
|
6
|
+
}[];
|
|
7
|
+
readonly extension: "ts" | "js";
|
|
8
|
+
readonly digest: string;
|
|
9
|
+
}
|
|
10
|
+
/** Read only installed trusted modules. Model output cannot select a loader or module path. */
|
|
11
|
+
export declare function loadGitWorkerRuntime(): GitWorkerRuntime;
|
|
12
|
+
export interface GitWorkerStage {
|
|
13
|
+
readonly root: string;
|
|
14
|
+
readonly worker: string;
|
|
15
|
+
readonly request: string;
|
|
16
|
+
readonly dispatchId: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function prepareGitWorker(workspace: string, runtime: GitWorkerRuntime, request: GitWorkerRequest): GitWorkerStage;
|
|
19
|
+
//# sourceMappingURL=git-worker-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-worker-runtime.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/git-worker-runtime.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,gBAAgB,EAAwC,MAAM,0BAA0B,CAAC;AAgBvG,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7E,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,+FAA+F;AAC/F,wBAAgB,oBAAoB,IAAI,gBAAgB,CAuBvD;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AACD,wBAAgB,gBAAgB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gBAAgB,GACvB,cAAc,CAwBhB","sourcesContent":["import { mkdirSync, mkdtempSync, realpathSync, rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { writeExclusiveFileDurablySync } from \"../durable-file-io.ts\";\nimport { ownedGitDirectory } from \"./git-sandbox-layout.ts\";\nimport { type GitWorkerRequest, serializeGitRequest, writeGitControl } from \"./git-worker-protocol.ts\";\nimport { digestBytes, digestObject, readRegularFile, VerifiedRunError } from \"./storage.ts\";\n\nconst MODULES = [\n\t\"canonical-json\",\n\t\"durable-file-directory\",\n\t\"durable-file-io\",\n\t\"durable-file-mode\",\n\t\"verified-run/storage\",\n\t\"verified-run/candidate-policy\",\n\t\"verified-run/git-candidate-preflight\",\n\t\"verified-run/git-execution\",\n\t\"verified-run/git-plumbing\",\n\t\"verified-run/git-worker-protocol\",\n\t\"verified-run/git-publication-worker\",\n] as const;\nexport interface GitWorkerRuntime {\n\treadonly files: readonly { readonly path: string; readonly bytes: Buffer }[];\n\treadonly extension: \"ts\" | \"js\";\n\treadonly digest: string;\n}\n\n/** Read only installed trusted modules. Model output cannot select a loader or module path. */\nexport function loadGitWorkerRuntime(): GitWorkerRuntime {\n\tif (process.release.name !== \"node\" || \"bun\" in process.versions || !import.meta.url.startsWith(\"file:\"))\n\t\tthrow new VerifiedRunError(\"unsupported_git_runtime\");\n\tconst extension = import.meta.url.endsWith(\".ts\") ? \"ts\" : \"js\";\n\tconst core = fileURLToPath(new URL(\"../\", import.meta.url));\n\ttry {\n\t\tconst files = MODULES.map((name) => ({\n\t\t\tpath: `core/${name}.${extension}`,\n\t\t\tbytes: readRegularFile(join(core, `${name}.${extension}`), 1_048_576),\n\t\t}));\n\t\tconst nodeDigest = digestBytes(readRegularFile(realpathSync(process.execPath), 256 * 1024 * 1024));\n\t\treturn {\n\t\t\tfiles,\n\t\t\textension,\n\t\t\tdigest: digestObject({\n\t\t\t\tversion: \"owned-git-v1\",\n\t\t\t\tnodeDigest,\n\t\t\t\tfiles: files.map(({ path, bytes }) => ({ path, digest: digestBytes(bytes) })),\n\t\t\t}),\n\t\t};\n\t} catch {\n\t\tthrow new VerifiedRunError(\"unsupported_git_runtime\");\n\t}\n}\n\nexport interface GitWorkerStage {\n\treadonly root: string;\n\treadonly worker: string;\n\treadonly request: string;\n\treadonly dispatchId: string;\n}\nexport function prepareGitWorker(\n\tworkspace: string,\n\truntime: GitWorkerRuntime,\n\trequest: GitWorkerRequest,\n): GitWorkerStage {\n\tconst git = ownedGitDirectory(workspace);\n\tconst root = mkdtempSync(join(git, \"omk-publish-\"));\n\ttry {\n\t\tconst payload = serializeGitRequest(request);\n\t\tif (Buffer.byteLength(JSON.stringify(payload)) > 128 * 1024 * 1024) throw new VerifiedRunError(\"storage_limit\");\n\t\tfor (const file of runtime.files) {\n\t\t\tconst target = join(root, \"runtime\", file.path);\n\t\t\tmkdirSync(dirname(target), { recursive: true, mode: 0o700 });\n\t\t\twriteExclusiveFileDurablySync(target, file.bytes);\n\t\t}\n\t\twriteExclusiveFileDurablySync(join(root, \"runtime\", \"package.json\"), Buffer.from('{\"type\":\"module\"}\\n'));\n\t\twriteGitControl(join(root, \"request.json\"), payload);\n\t\tconst dispatchId = root.slice(git.length + 1);\n\t\treturn {\n\t\t\troot,\n\t\t\tdispatchId,\n\t\t\tworker: `/workspace/.git/${dispatchId}/runtime/core/verified-run/git-publication-worker.${runtime.extension}`,\n\t\t\trequest: `/workspace/.git/${dispatchId}/request.json`,\n\t\t};\n\t} catch (error) {\n\t\trmSync(root, { recursive: true, force: true });\n\t\tthrow error;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, realpathSync, rmSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { writeExclusiveFileDurablySync } from "../durable-file-io.js";
|
|
5
|
+
import { ownedGitDirectory } from "./git-sandbox-layout.js";
|
|
6
|
+
import { serializeGitRequest, writeGitControl } from "./git-worker-protocol.js";
|
|
7
|
+
import { digestBytes, digestObject, readRegularFile, VerifiedRunError } from "./storage.js";
|
|
8
|
+
const MODULES = [
|
|
9
|
+
"canonical-json",
|
|
10
|
+
"durable-file-directory",
|
|
11
|
+
"durable-file-io",
|
|
12
|
+
"durable-file-mode",
|
|
13
|
+
"verified-run/storage",
|
|
14
|
+
"verified-run/candidate-policy",
|
|
15
|
+
"verified-run/git-candidate-preflight",
|
|
16
|
+
"verified-run/git-execution",
|
|
17
|
+
"verified-run/git-plumbing",
|
|
18
|
+
"verified-run/git-worker-protocol",
|
|
19
|
+
"verified-run/git-publication-worker",
|
|
20
|
+
];
|
|
21
|
+
/** Read only installed trusted modules. Model output cannot select a loader or module path. */
|
|
22
|
+
export function loadGitWorkerRuntime() {
|
|
23
|
+
if (process.release.name !== "node" || "bun" in process.versions || !import.meta.url.startsWith("file:"))
|
|
24
|
+
throw new VerifiedRunError("unsupported_git_runtime");
|
|
25
|
+
const extension = import.meta.url.endsWith(".ts") ? "ts" : "js";
|
|
26
|
+
const core = fileURLToPath(new URL("../", import.meta.url));
|
|
27
|
+
try {
|
|
28
|
+
const files = MODULES.map((name) => ({
|
|
29
|
+
path: `core/${name}.${extension}`,
|
|
30
|
+
bytes: readRegularFile(join(core, `${name}.${extension}`), 1_048_576),
|
|
31
|
+
}));
|
|
32
|
+
const nodeDigest = digestBytes(readRegularFile(realpathSync(process.execPath), 256 * 1024 * 1024));
|
|
33
|
+
return {
|
|
34
|
+
files,
|
|
35
|
+
extension,
|
|
36
|
+
digest: digestObject({
|
|
37
|
+
version: "owned-git-v1",
|
|
38
|
+
nodeDigest,
|
|
39
|
+
files: files.map(({ path, bytes }) => ({ path, digest: digestBytes(bytes) })),
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new VerifiedRunError("unsupported_git_runtime");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function prepareGitWorker(workspace, runtime, request) {
|
|
48
|
+
const git = ownedGitDirectory(workspace);
|
|
49
|
+
const root = mkdtempSync(join(git, "omk-publish-"));
|
|
50
|
+
try {
|
|
51
|
+
const payload = serializeGitRequest(request);
|
|
52
|
+
if (Buffer.byteLength(JSON.stringify(payload)) > 128 * 1024 * 1024)
|
|
53
|
+
throw new VerifiedRunError("storage_limit");
|
|
54
|
+
for (const file of runtime.files) {
|
|
55
|
+
const target = join(root, "runtime", file.path);
|
|
56
|
+
mkdirSync(dirname(target), { recursive: true, mode: 0o700 });
|
|
57
|
+
writeExclusiveFileDurablySync(target, file.bytes);
|
|
58
|
+
}
|
|
59
|
+
writeExclusiveFileDurablySync(join(root, "runtime", "package.json"), Buffer.from('{"type":"module"}\n'));
|
|
60
|
+
writeGitControl(join(root, "request.json"), payload);
|
|
61
|
+
const dispatchId = root.slice(git.length + 1);
|
|
62
|
+
return {
|
|
63
|
+
root,
|
|
64
|
+
dispatchId,
|
|
65
|
+
worker: `/workspace/.git/${dispatchId}/runtime/core/verified-run/git-publication-worker.${runtime.extension}`,
|
|
66
|
+
request: `/workspace/.git/${dispatchId}/request.json`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
rmSync(root, { recursive: true, force: true });
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=git-worker-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-worker-runtime.js","sourceRoot":"","sources":["../../../src/core/verified-run/git-worker-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdirSync, mkdtempSync, realpathSync, rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { writeExclusiveFileDurablySync } from \"../durable-file-io.ts\";\nimport { ownedGitDirectory } from \"./git-sandbox-layout.ts\";\nimport { type GitWorkerRequest, serializeGitRequest, writeGitControl } from \"./git-worker-protocol.ts\";\nimport { digestBytes, digestObject, readRegularFile, VerifiedRunError } from \"./storage.ts\";\n\nconst MODULES = [\n\t\"canonical-json\",\n\t\"durable-file-directory\",\n\t\"durable-file-io\",\n\t\"durable-file-mode\",\n\t\"verified-run/storage\",\n\t\"verified-run/candidate-policy\",\n\t\"verified-run/git-candidate-preflight\",\n\t\"verified-run/git-execution\",\n\t\"verified-run/git-plumbing\",\n\t\"verified-run/git-worker-protocol\",\n\t\"verified-run/git-publication-worker\",\n] as const;\nexport interface GitWorkerRuntime {\n\treadonly files: readonly { readonly path: string; readonly bytes: Buffer }[];\n\treadonly extension: \"ts\" | \"js\";\n\treadonly digest: string;\n}\n\n/** Read only installed trusted modules. Model output cannot select a loader or module path. */\nexport function loadGitWorkerRuntime(): GitWorkerRuntime {\n\tif (process.release.name !== \"node\" || \"bun\" in process.versions || !import.meta.url.startsWith(\"file:\"))\n\t\tthrow new VerifiedRunError(\"unsupported_git_runtime\");\n\tconst extension = import.meta.url.endsWith(\".ts\") ? \"ts\" : \"js\";\n\tconst core = fileURLToPath(new URL(\"../\", import.meta.url));\n\ttry {\n\t\tconst files = MODULES.map((name) => ({\n\t\t\tpath: `core/${name}.${extension}`,\n\t\t\tbytes: readRegularFile(join(core, `${name}.${extension}`), 1_048_576),\n\t\t}));\n\t\tconst nodeDigest = digestBytes(readRegularFile(realpathSync(process.execPath), 256 * 1024 * 1024));\n\t\treturn {\n\t\t\tfiles,\n\t\t\textension,\n\t\t\tdigest: digestObject({\n\t\t\t\tversion: \"owned-git-v1\",\n\t\t\t\tnodeDigest,\n\t\t\t\tfiles: files.map(({ path, bytes }) => ({ path, digest: digestBytes(bytes) })),\n\t\t\t}),\n\t\t};\n\t} catch {\n\t\tthrow new VerifiedRunError(\"unsupported_git_runtime\");\n\t}\n}\n\nexport interface GitWorkerStage {\n\treadonly root: string;\n\treadonly worker: string;\n\treadonly request: string;\n\treadonly dispatchId: string;\n}\nexport function prepareGitWorker(\n\tworkspace: string,\n\truntime: GitWorkerRuntime,\n\trequest: GitWorkerRequest,\n): GitWorkerStage {\n\tconst git = ownedGitDirectory(workspace);\n\tconst root = mkdtempSync(join(git, \"omk-publish-\"));\n\ttry {\n\t\tconst payload = serializeGitRequest(request);\n\t\tif (Buffer.byteLength(JSON.stringify(payload)) > 128 * 1024 * 1024) throw new VerifiedRunError(\"storage_limit\");\n\t\tfor (const file of runtime.files) {\n\t\t\tconst target = join(root, \"runtime\", file.path);\n\t\t\tmkdirSync(dirname(target), { recursive: true, mode: 0o700 });\n\t\t\twriteExclusiveFileDurablySync(target, file.bytes);\n\t\t}\n\t\twriteExclusiveFileDurablySync(join(root, \"runtime\", \"package.json\"), Buffer.from('{\"type\":\"module\"}\\n'));\n\t\twriteGitControl(join(root, \"request.json\"), payload);\n\t\tconst dispatchId = root.slice(git.length + 1);\n\t\treturn {\n\t\t\troot,\n\t\t\tdispatchId,\n\t\t\tworker: `/workspace/.git/${dispatchId}/runtime/core/verified-run/git-publication-worker.${runtime.extension}`,\n\t\t\trequest: `/workspace/.git/${dispatchId}/request.json`,\n\t\t};\n\t} catch (error) {\n\t\trmSync(root, { recursive: true, force: true });\n\t\tthrow error;\n\t}\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { appendFileDurablySync } from "../durable-file-io.ts";
|
|
2
2
|
import type { SessionOwnerLease } from "../session-owner-lease.ts";
|
|
3
3
|
import { type RunEvent, type RunProjection } from "./events.ts";
|
|
4
|
-
interface
|
|
4
|
+
export interface RunJournalRecord {
|
|
5
5
|
readonly version: 2;
|
|
6
6
|
readonly seq: number;
|
|
7
7
|
readonly generation: number;
|
|
@@ -10,7 +10,7 @@ interface RecordV2 {
|
|
|
10
10
|
readonly hash: string;
|
|
11
11
|
}
|
|
12
12
|
export interface JournalSnapshot {
|
|
13
|
-
readonly records: readonly
|
|
13
|
+
readonly records: readonly RunJournalRecord[];
|
|
14
14
|
readonly state: RunProjection;
|
|
15
15
|
readonly bytesDigest: string;
|
|
16
16
|
}
|
|
@@ -28,5 +28,4 @@ export declare class VerifiedRunJournal {
|
|
|
28
28
|
get state(): RunProjection;
|
|
29
29
|
append(event: RunEvent): RunProjection;
|
|
30
30
|
}
|
|
31
|
-
export {};
|
|
32
31
|
//# sourceMappingURL=journal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/journal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAA6B,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3F,
|
|
1
|
+
{"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/journal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAA6B,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3F,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AACD,eAAO,MAAM,WAAW,6BAAiE,CAAC;AAE1F,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA+BtE;AAED,yFAAyF;AACzF,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAEpE,YAAY,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,+BAAwB,EAKrF;IAED,IAAI,KAAK,IAAI,aAAa,CAGzB;IAED,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,aAAa,CA+BrC;CACD","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { acquireDurableFileMutationLockSync } from \"../durable-file-identity.ts\";\nimport { appendFileDurablySync } from \"../durable-file-io.ts\";\nimport { canonicalJson } from \"../run-journal.ts\";\nimport type { SessionOwnerLease } from \"../session-owner-lease.ts\";\nimport { parseRunEvent, projectRun, type RunEvent, type RunProjection } from \"./events.ts\";\nimport { digestBytes, digestObject, readRegularFile, VerifiedRunError } from \"./storage.ts\";\n\nexport interface RunJournalRecord {\n\treadonly version: 2;\n\treadonly seq: number;\n\treadonly generation: number;\n\treadonly previous: string;\n\treadonly event: RunEvent;\n\treadonly hash: string;\n}\nexport interface JournalSnapshot {\n\treadonly records: readonly RunJournalRecord[];\n\treadonly state: RunProjection;\n\treadonly bytesDigest: string;\n}\nexport const journalPath = (runPath: string): string => join(runPath, \"journal.v2.jsonl\");\n\n/** Read-only: no implicit recovery, tail truncation, mode changes, or model calls. */\nexport function readRunJournal(runPath: string): JournalSnapshot | null {\n\tconst path = journalPath(runPath);\n\tif (!existsSync(path)) return null;\n\tconst bytes = readRegularFile(path, 8388608);\n\tif (!bytes.length || bytes.at(-1) !== 10) throw new VerifiedRunError(\"journal_truncated\");\n\tconst lines = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes).slice(0, -1).split(\"\\n\");\n\tconst records: RunJournalRecord[] = [];\n\tlet previous = \"0\".repeat(64);\n\tlet generation = 1;\n\tfor (const [index, line] of lines.entries()) {\n\t\tlet raw: unknown;\n\t\ttry {\n\t\t\traw = JSON.parse(line);\n\t\t} catch {\n\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t}\n\t\tif (typeof raw !== \"object\" || raw === null || !(\"event\" in raw)) throw new VerifiedRunError(\"integrity\");\n\t\tconst event = parseRunEvent(raw.event);\n\t\tif (event.kind === \"resumed\" || event.kind === \"writer_restarted\" || event.kind === \"tasks_retried\")\n\t\t\tgeneration += 1;\n\t\tconst material = { version: 2 as const, seq: index + 1, generation, previous, event };\n\t\tconst record = Object.freeze({ ...material, hash: digestObject(material) });\n\t\tif (canonicalJson(raw) !== canonicalJson(record)) throw new VerifiedRunError(\"integrity\");\n\t\trecords.push(record);\n\t\tprevious = record.hash;\n\t}\n\treturn {\n\t\trecords: Object.freeze(records),\n\t\tstate: projectRun(records.map((record) => record.event)),\n\t\tbytesDigest: digestBytes(bytes),\n\t};\n}\n\n/** v2 event store reuses the v1 durable append and mutation/owner locking primitives. */\nexport class VerifiedRunJournal {\n\tprivate head: JournalSnapshot | null;\n\tprivate poisoned = false;\n\tprivate readonly runPath: string;\n\tprivate readonly owner: SessionOwnerLease;\n\tprivate readonly persist: (path: string, bytes: Uint8Array) => void;\n\n\tconstructor(runPath: string, owner: SessionOwnerLease, persist = appendFileDurablySync) {\n\t\tthis.runPath = runPath;\n\t\tthis.owner = owner;\n\t\tthis.persist = persist;\n\t\tthis.head = readRunJournal(runPath);\n\t}\n\n\tget state(): RunProjection {\n\t\tif (!this.head) throw new VerifiedRunError(\"missing_run\");\n\t\treturn this.head.state;\n\t}\n\n\tappend(event: RunEvent): RunProjection {\n\t\tconst path = journalPath(this.runPath);\n\t\tif (this.poisoned || !this.owner.owns(path)) throw new VerifiedRunError(\"stale_owner\");\n\t\tconst lock = acquireDurableFileMutationLockSync(path);\n\t\ttry {\n\t\t\tconst current = readRunJournal(this.runPath);\n\t\t\tif (current?.bytesDigest !== this.head?.bytesDigest) throw new VerifiedRunError(\"stale_revision\");\n\t\t\tconst records = current?.records ?? [];\n\t\t\tconst candidate = projectRun([...records.map((record) => record.event), event]);\n\t\t\tconst material = {\n\t\t\t\tversion: 2 as const,\n\t\t\t\tseq: records.length + 1,\n\t\t\t\tgeneration: candidate.generation,\n\t\t\t\tprevious: records.at(-1)?.hash ?? \"0\".repeat(64),\n\t\t\t\tevent,\n\t\t\t};\n\t\t\tconst record: RunJournalRecord = { ...material, hash: digestObject(material) };\n\t\t\ttry {\n\t\t\t\tthis.persist(path, Buffer.from(`${canonicalJson(record)}\\n`));\n\t\t\t\tconst next = readRunJournal(this.runPath);\n\t\t\t\tif (!next || next.records.at(-1)?.hash !== record.hash) throw new VerifiedRunError(\"integrity\");\n\t\t\t\tthis.owner.refresh(true);\n\t\t\t\tthis.head = next;\n\t\t\t} catch (error) {\n\t\t\t\tthis.poisoned = true;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn this.state;\n\t\t} finally {\n\t\t\tlock.release();\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../../src/core/verified-run/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAqC,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAe5F,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;AAE1F,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,OAAe,EAA0B;IACvE,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;QAAE,MAAM,IAAI,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/F,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../../src/core/verified-run/journal.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { acquireDurableFileMutationLockSync } from \"../durable-file-identity.ts\";\nimport { appendFileDurablySync } from \"../durable-file-io.ts\";\nimport { canonicalJson } from \"../run-journal.ts\";\nimport type { SessionOwnerLease } from \"../session-owner-lease.ts\";\nimport { parseRunEvent, projectRun, type RunEvent, type RunProjection } from \"./events.ts\";\nimport { digestBytes, digestObject, readRegularFile, VerifiedRunError } from \"./storage.ts\";\n\nexport interface RunJournalRecord {\n\treadonly version: 2;\n\treadonly seq: number;\n\treadonly generation: number;\n\treadonly previous: string;\n\treadonly event: RunEvent;\n\treadonly hash: string;\n}\nexport interface JournalSnapshot {\n\treadonly records: readonly RunJournalRecord[];\n\treadonly state: RunProjection;\n\treadonly bytesDigest: string;\n}\nexport const journalPath = (runPath: string): string => join(runPath, \"journal.v2.jsonl\");\n\n/** Read-only: no implicit recovery, tail truncation, mode changes, or model calls. */\nexport function readRunJournal(runPath: string): JournalSnapshot | null {\n\tconst path = journalPath(runPath);\n\tif (!existsSync(path)) return null;\n\tconst bytes = readRegularFile(path, 8388608);\n\tif (!bytes.length || bytes.at(-1) !== 10) throw new VerifiedRunError(\"journal_truncated\");\n\tconst lines = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes).slice(0, -1).split(\"\\n\");\n\tconst records: RunJournalRecord[] = [];\n\tlet previous = \"0\".repeat(64);\n\tlet generation = 1;\n\tfor (const [index, line] of lines.entries()) {\n\t\tlet raw: unknown;\n\t\ttry {\n\t\t\traw = JSON.parse(line);\n\t\t} catch {\n\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t}\n\t\tif (typeof raw !== \"object\" || raw === null || !(\"event\" in raw)) throw new VerifiedRunError(\"integrity\");\n\t\tconst event = parseRunEvent(raw.event);\n\t\tif (event.kind === \"resumed\" || event.kind === \"writer_restarted\" || event.kind === \"tasks_retried\")\n\t\t\tgeneration += 1;\n\t\tconst material = { version: 2 as const, seq: index + 1, generation, previous, event };\n\t\tconst record = Object.freeze({ ...material, hash: digestObject(material) });\n\t\tif (canonicalJson(raw) !== canonicalJson(record)) throw new VerifiedRunError(\"integrity\");\n\t\trecords.push(record);\n\t\tprevious = record.hash;\n\t}\n\treturn {\n\t\trecords: Object.freeze(records),\n\t\tstate: projectRun(records.map((record) => record.event)),\n\t\tbytesDigest: digestBytes(bytes),\n\t};\n}\n\n/** v2 event store reuses the v1 durable append and mutation/owner locking primitives. */\nexport class VerifiedRunJournal {\n\tprivate head: JournalSnapshot | null;\n\tprivate poisoned = false;\n\tprivate readonly runPath: string;\n\tprivate readonly owner: SessionOwnerLease;\n\tprivate readonly persist: (path: string, bytes: Uint8Array) => void;\n\n\tconstructor(runPath: string, owner: SessionOwnerLease, persist = appendFileDurablySync) {\n\t\tthis.runPath = runPath;\n\t\tthis.owner = owner;\n\t\tthis.persist = persist;\n\t\tthis.head = readRunJournal(runPath);\n\t}\n\n\tget state(): RunProjection {\n\t\tif (!this.head) throw new VerifiedRunError(\"missing_run\");\n\t\treturn this.head.state;\n\t}\n\n\tappend(event: RunEvent): RunProjection {\n\t\tconst path = journalPath(this.runPath);\n\t\tif (this.poisoned || !this.owner.owns(path)) throw new VerifiedRunError(\"stale_owner\");\n\t\tconst lock = acquireDurableFileMutationLockSync(path);\n\t\ttry {\n\t\t\tconst current = readRunJournal(this.runPath);\n\t\t\tif (current?.bytesDigest !== this.head?.bytesDigest) throw new VerifiedRunError(\"stale_revision\");\n\t\t\tconst records = current?.records ?? [];\n\t\t\tconst candidate = projectRun([...records.map((record) => record.event), event]);\n\t\t\tconst material = {\n\t\t\t\tversion: 2 as const,\n\t\t\t\tseq: records.length + 1,\n\t\t\t\tgeneration: candidate.generation,\n\t\t\t\tprevious: records.at(-1)?.hash ?? \"0\".repeat(64),\n\t\t\t\tevent,\n\t\t\t};\n\t\t\tconst record: RunJournalRecord = { ...material, hash: digestObject(material) };\n\t\t\ttry {\n\t\t\t\tthis.persist(path, Buffer.from(`${canonicalJson(record)}\\n`));\n\t\t\t\tconst next = readRunJournal(this.runPath);\n\t\t\t\tif (!next || next.records.at(-1)?.hash !== record.hash) throw new VerifiedRunError(\"integrity\");\n\t\t\t\tthis.owner.refresh(true);\n\t\t\t\tthis.head = next;\n\t\t\t} catch (error) {\n\t\t\t\tthis.poisoned = true;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn this.state;\n\t\t} finally {\n\t\t\tlock.release();\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace-identity.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/namespace-identity.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAqBtE;AAcD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAevE;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBxF","sourcesContent":["import { readFileSync, readlinkSync } from \"node:fs\";\nimport { readRunClock } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport interface NamespaceIdentity {\n\treadonly pid: number;\n\treadonly startTicks: string;\n\treadonly namespace: string;\n\treadonly bootId: string;\n}\n\nexport function parseNamespaceIdentity(raw: unknown): NamespaceIdentity {\n\tif (\n\t\ttypeof raw !== \"object\" ||\n\t\traw === null ||\n\t\t!(\"pid\" in raw) ||\n\t\ttypeof raw.pid !== \"number\" ||\n\t\t!Number.isSafeInteger(raw.pid) ||\n\t\traw.pid <= 0 ||\n\t\t!(\"startTicks\" in raw) ||\n\t\ttypeof raw.startTicks !== \"string\" ||\n\t\t!/^\\d+$/.test(raw.startTicks) ||\n\t\traw.startTicks.length > 32 ||\n\t\t!(\"namespace\" in raw) ||\n\t\ttypeof raw.namespace !== \"string\" ||\n\t\t!/^pid:\\[\\d+\\]$/.test(raw.namespace) ||\n\t\t!(\"bootId\" in raw) ||\n\t\ttypeof raw.bootId !== \"string\" ||\n\t\t!/^[a-f0-9-]{36}$/.test(raw.bootId)\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\treturn Object.freeze({ pid: raw.pid, startTicks: raw.startTicks, namespace: raw.namespace, bootId: raw.bootId });\n}\n\nfunction processStat(pid: number): { readonly startTicks: string; readonly state: string } {\n\tconst stat = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n\tconst fields = stat\n\t\t.slice(stat.lastIndexOf(\")\") + 2)\n\t\t.trim()\n\t\t.split(/\\s+/);\n\tconst startTicks = fields[19];\n\tconst state = fields[0];\n\tif (!startTicks || !/^\\d+$/.test(startTicks) || !state) throw new VerifiedRunError(\"process_identity\");\n\treturn { startTicks, state };\n}\n\nexport function captureNamespaceIdentity(pid: number): NamespaceIdentity {\n\tif (!Number.isSafeInteger(pid) || pid <= 0) throw new VerifiedRunError(\"process_identity\");\n\tconst before = processStat(pid);\n\tconst status = readFileSync(`/proc/${pid}/status`, \"utf8\");\n\tconst namespacePids = status\n\t\t.match(/^NSpid:\\s+(.+)$/m)?.[1]\n\t\t?.trim()\n\t\t.split(/\\s+/);\n\tif (!namespacePids || namespacePids.length < 2 || namespacePids.at(-1) !== \"1\")\n\t\tthrow new VerifiedRunError(\"process_identity\");\n\tconst namespace = readlinkSync(`/proc/${pid}/ns/pid`);\n\tconst after = processStat(pid);\n\tif (before.startTicks !== after.startTicks || before.state === \"Z\" || after.state === \"Z\")\n\t\tthrow new VerifiedRunError(\"process_identity\");\n\treturn parseNamespaceIdentity({ pid, startTicks: before.startTicks, namespace, bootId: readRunClock().bootId });\n}\n\n/** Read only. Never signal a PID that may have been reused by another process. */\nexport function probeNamespace(identity: NamespaceIdentity): \"alive\" | \"gone\" | \"unknown\" {\n\ttry {\n\t\tif (readRunClock().bootId !== identity.bootId) return \"unknown\";\n\t} catch {\n\t\treturn \"unknown\";\n\t}\n\ttry {\n\t\tconst current = processStat(identity.pid);\n\t\tif (current.startTicks !== identity.startTicks) return \"
|
|
1
|
+
{"version":3,"file":"namespace-identity.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/namespace-identity.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAqBtE;AAcD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAevE;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBxF","sourcesContent":["import { readFileSync, readlinkSync } from \"node:fs\";\nimport { readRunClock } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport interface NamespaceIdentity {\n\treadonly pid: number;\n\treadonly startTicks: string;\n\treadonly namespace: string;\n\treadonly bootId: string;\n}\n\nexport function parseNamespaceIdentity(raw: unknown): NamespaceIdentity {\n\tif (\n\t\ttypeof raw !== \"object\" ||\n\t\traw === null ||\n\t\t!(\"pid\" in raw) ||\n\t\ttypeof raw.pid !== \"number\" ||\n\t\t!Number.isSafeInteger(raw.pid) ||\n\t\traw.pid <= 0 ||\n\t\t!(\"startTicks\" in raw) ||\n\t\ttypeof raw.startTicks !== \"string\" ||\n\t\t!/^\\d+$/.test(raw.startTicks) ||\n\t\traw.startTicks.length > 32 ||\n\t\t!(\"namespace\" in raw) ||\n\t\ttypeof raw.namespace !== \"string\" ||\n\t\t!/^pid:\\[\\d+\\]$/.test(raw.namespace) ||\n\t\t!(\"bootId\" in raw) ||\n\t\ttypeof raw.bootId !== \"string\" ||\n\t\t!/^[a-f0-9-]{36}$/.test(raw.bootId)\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\treturn Object.freeze({ pid: raw.pid, startTicks: raw.startTicks, namespace: raw.namespace, bootId: raw.bootId });\n}\n\nfunction processStat(pid: number): { readonly startTicks: string; readonly state: string } {\n\tconst stat = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n\tconst fields = stat\n\t\t.slice(stat.lastIndexOf(\")\") + 2)\n\t\t.trim()\n\t\t.split(/\\s+/);\n\tconst startTicks = fields[19];\n\tconst state = fields[0];\n\tif (!startTicks || !/^\\d+$/.test(startTicks) || !state) throw new VerifiedRunError(\"process_identity\");\n\treturn { startTicks, state };\n}\n\nexport function captureNamespaceIdentity(pid: number): NamespaceIdentity {\n\tif (!Number.isSafeInteger(pid) || pid <= 0) throw new VerifiedRunError(\"process_identity\");\n\tconst before = processStat(pid);\n\tconst status = readFileSync(`/proc/${pid}/status`, \"utf8\");\n\tconst namespacePids = status\n\t\t.match(/^NSpid:\\s+(.+)$/m)?.[1]\n\t\t?.trim()\n\t\t.split(/\\s+/);\n\tif (!namespacePids || namespacePids.length < 2 || namespacePids.at(-1) !== \"1\")\n\t\tthrow new VerifiedRunError(\"process_identity\");\n\tconst namespace = readlinkSync(`/proc/${pid}/ns/pid`);\n\tconst after = processStat(pid);\n\tif (before.startTicks !== after.startTicks || before.state === \"Z\" || after.state === \"Z\")\n\t\tthrow new VerifiedRunError(\"process_identity\");\n\treturn parseNamespaceIdentity({ pid, startTicks: before.startTicks, namespace, bootId: readRunClock().bootId });\n}\n\n/** Read only. Never signal a PID that may have been reused by another process. */\nexport function probeNamespace(identity: NamespaceIdentity): \"alive\" | \"gone\" | \"unknown\" {\n\ttry {\n\t\tif (readRunClock().bootId !== identity.bootId) return \"unknown\";\n\t} catch {\n\t\treturn \"unknown\";\n\t}\n\ttry {\n\t\tconst current = processStat(identity.pid);\n\t\tif (current.startTicks !== identity.startTicks) return \"unknown\";\n\t\t// Linux finishes PID namespace teardown before its init becomes a zombie.\n\t\tif (current.state === \"Z\" || current.state === \"X\") return \"gone\";\n\t\treturn readlinkSync(`/proc/${identity.pid}/ns/pid`) === identity.namespace ? \"alive\" : \"unknown\";\n\t} catch (error) {\n\t\tif (error instanceof Error && \"code\" in error && (error.code === \"ENOENT\" || error.code === \"ESRCH\"))\n\t\t\treturn \"gone\";\n\t\treturn \"unknown\";\n\t}\n}\n"]}
|
|
@@ -62,7 +62,7 @@ export function probeNamespace(identity) {
|
|
|
62
62
|
try {
|
|
63
63
|
const current = processStat(identity.pid);
|
|
64
64
|
if (current.startTicks !== identity.startTicks)
|
|
65
|
-
return "
|
|
65
|
+
return "unknown";
|
|
66
66
|
// Linux finishes PID namespace teardown before its init becomes a zombie.
|
|
67
67
|
if (current.state === "Z" || current.state === "X")
|
|
68
68
|
return "gone";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace-identity.js","sourceRoot":"","sources":["../../../src/core/verified-run/namespace-identity.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"namespace-identity.js","sourceRoot":"","sources":["../../../src/core/verified-run/namespace-identity.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, readlinkSync } from \"node:fs\";\nimport { readRunClock } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport interface NamespaceIdentity {\n\treadonly pid: number;\n\treadonly startTicks: string;\n\treadonly namespace: string;\n\treadonly bootId: string;\n}\n\nexport function parseNamespaceIdentity(raw: unknown): NamespaceIdentity {\n\tif (\n\t\ttypeof raw !== \"object\" ||\n\t\traw === null ||\n\t\t!(\"pid\" in raw) ||\n\t\ttypeof raw.pid !== \"number\" ||\n\t\t!Number.isSafeInteger(raw.pid) ||\n\t\traw.pid <= 0 ||\n\t\t!(\"startTicks\" in raw) ||\n\t\ttypeof raw.startTicks !== \"string\" ||\n\t\t!/^\\d+$/.test(raw.startTicks) ||\n\t\traw.startTicks.length > 32 ||\n\t\t!(\"namespace\" in raw) ||\n\t\ttypeof raw.namespace !== \"string\" ||\n\t\t!/^pid:\\[\\d+\\]$/.test(raw.namespace) ||\n\t\t!(\"bootId\" in raw) ||\n\t\ttypeof raw.bootId !== \"string\" ||\n\t\t!/^[a-f0-9-]{36}$/.test(raw.bootId)\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\treturn Object.freeze({ pid: raw.pid, startTicks: raw.startTicks, namespace: raw.namespace, bootId: raw.bootId });\n}\n\nfunction processStat(pid: number): { readonly startTicks: string; readonly state: string } {\n\tconst stat = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n\tconst fields = stat\n\t\t.slice(stat.lastIndexOf(\")\") + 2)\n\t\t.trim()\n\t\t.split(/\\s+/);\n\tconst startTicks = fields[19];\n\tconst state = fields[0];\n\tif (!startTicks || !/^\\d+$/.test(startTicks) || !state) throw new VerifiedRunError(\"process_identity\");\n\treturn { startTicks, state };\n}\n\nexport function captureNamespaceIdentity(pid: number): NamespaceIdentity {\n\tif (!Number.isSafeInteger(pid) || pid <= 0) throw new VerifiedRunError(\"process_identity\");\n\tconst before = processStat(pid);\n\tconst status = readFileSync(`/proc/${pid}/status`, \"utf8\");\n\tconst namespacePids = status\n\t\t.match(/^NSpid:\\s+(.+)$/m)?.[1]\n\t\t?.trim()\n\t\t.split(/\\s+/);\n\tif (!namespacePids || namespacePids.length < 2 || namespacePids.at(-1) !== \"1\")\n\t\tthrow new VerifiedRunError(\"process_identity\");\n\tconst namespace = readlinkSync(`/proc/${pid}/ns/pid`);\n\tconst after = processStat(pid);\n\tif (before.startTicks !== after.startTicks || before.state === \"Z\" || after.state === \"Z\")\n\t\tthrow new VerifiedRunError(\"process_identity\");\n\treturn parseNamespaceIdentity({ pid, startTicks: before.startTicks, namespace, bootId: readRunClock().bootId });\n}\n\n/** Read only. Never signal a PID that may have been reused by another process. */\nexport function probeNamespace(identity: NamespaceIdentity): \"alive\" | \"gone\" | \"unknown\" {\n\ttry {\n\t\tif (readRunClock().bootId !== identity.bootId) return \"unknown\";\n\t} catch {\n\t\treturn \"unknown\";\n\t}\n\ttry {\n\t\tconst current = processStat(identity.pid);\n\t\tif (current.startTicks !== identity.startTicks) return \"unknown\";\n\t\t// Linux finishes PID namespace teardown before its init becomes a zombie.\n\t\tif (current.state === \"Z\" || current.state === \"X\") return \"gone\";\n\t\treturn readlinkSync(`/proc/${identity.pid}/ns/pid`) === identity.namespace ? \"alive\" : \"unknown\";\n\t} catch (error) {\n\t\tif (error instanceof Error && \"code\" in error && (error.code === \"ENOENT\" || error.code === \"ESRCH\"))\n\t\t\treturn \"gone\";\n\t\treturn \"unknown\";\n\t}\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RunAuthority } from "./authority-runtime.ts";
|
|
1
2
|
import { type SandboxOutcome } from "./broker.ts";
|
|
2
3
|
import type { VerifiedRunJournal } from "./journal.ts";
|
|
3
4
|
export interface OwnedRunCommand {
|
|
@@ -13,10 +14,18 @@ export interface OwnedRunResult {
|
|
|
13
14
|
readonly result: SandboxOutcome;
|
|
14
15
|
readonly timeoutMs: number;
|
|
15
16
|
}
|
|
16
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Mandatory durable dispatch intent, shared by command and AgentSession
|
|
19
|
+
* writers. There is no ungated execution lane: a journal without an anchored
|
|
20
|
+
* budget cannot commit a process identity, so the supervisor boundary would
|
|
21
|
+
* be unprovable and must refuse dispatch. Every dispatch now also crosses the
|
|
22
|
+
* durable authority boundary — grant → intent → start → termination witness
|
|
23
|
+
* — so a restart can reconcile effects the journal alone cannot settle.
|
|
24
|
+
*/
|
|
17
25
|
export declare function executeRunCommand(journal: VerifiedRunJournal, request: OwnedRunCommand, policy: {
|
|
18
26
|
readonly cleanupMs: number;
|
|
19
27
|
readonly maxOutputBytes: number;
|
|
28
|
+
readonly authority: RunAuthority;
|
|
20
29
|
readonly signal?: AbortSignal;
|
|
21
30
|
}): Promise<OwnedRunResult>;
|
|
22
31
|
//# sourceMappingURL=owned-execution.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"owned-execution.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/owned-execution.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"owned-execution.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/owned-execution.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAkCD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE;IACP,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B,GACC,OAAO,CAAC,cAAc,CAAC,CA2FzB","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { realpathSync } from \"node:fs\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ResourceClaimInput } from \"../../coordination/resource.ts\";\nimport type { GrantToken } from \"../../coordination/types.ts\";\nimport type { RunAuthority } from \"./authority-runtime.ts\";\nimport { executeSandbox, type SandboxOutcome } from \"./broker.ts\";\nimport type { VerifiedRunJournal } from \"./journal.ts\";\nimport type { NamespaceIdentity } from \"./namespace-identity.ts\";\nimport { digestObject, VerifiedRunError } from \"./storage.ts\";\n\nexport interface OwnedRunCommand {\n\treadonly role: \"writer\" | \"verifier\";\n\treadonly argv: readonly string[];\n\treadonly workspace: string;\n\treadonly deadline: number;\n\treadonly claimId: string | null;\n\treadonly taskId?: string;\n}\nexport interface OwnedRunResult {\n\treadonly executionId: string;\n\treadonly result: SandboxOutcome;\n\treadonly timeoutMs: number;\n}\n\n/**\n * The filesystem claim a dispatched process is authorized for: exactly the\n * workspace bind it receives inside the namespace — nothing wider. Keys are\n * the resolved absolute path minus the leading slash so prefix containment\n * matches real tree containment; `realpathSync` keeps two spellings of the\n * same directory one claim.\n */\nfunction workspaceClaim(\n\tworkspace: string,\n\taccess: \"read\" | \"write\",\n\tgeneration: number,\n): readonly ResourceClaimInput[] {\n\tlet root: string;\n\ttry {\n\t\troot = realpathSync(workspace);\n\t} catch {\n\t\tthrow new VerifiedRunError(\"authority_claim\");\n\t}\n\treturn Object.freeze([\n\t\t{\n\t\t\tnamespace: \"filesystem\",\n\t\t\tinstanceId: \"verified-run\",\n\t\t\tcanonicalKey: root.replace(/^\\/+/, \"\"),\n\t\t\taccess,\n\t\t\tgeneration: String(generation),\n\t\t},\n\t]);\n}\n\n/** Rejection codes that can only be produced before the supervisor spawned. */\nconst NEVER_SPAWNED = new Set([\"cancelled\", \"deadline\", \"unsupported_boundary\"]);\n\n/**\n * Mandatory durable dispatch intent, shared by command and AgentSession\n * writers. There is no ungated execution lane: a journal without an anchored\n * budget cannot commit a process identity, so the supervisor boundary would\n * be unprovable and must refuse dispatch. Every dispatch now also crosses the\n * durable authority boundary — grant → intent → start → termination witness\n * — so a restart can reconcile effects the journal alone cannot settle.\n */\nexport async function executeRunCommand(\n\tjournal: VerifiedRunJournal,\n\trequest: OwnedRunCommand,\n\tpolicy: {\n\t\treadonly cleanupMs: number;\n\t\treadonly maxOutputBytes: number;\n\t\treadonly authority: RunAuthority;\n\t\treadonly signal?: AbortSignal;\n\t},\n): Promise<OwnedRunResult> {\n\tif (Math.floor(request.deadline - performance.now()) <= 0) throw new VerifiedRunError(\"deadline\");\n\tif (policy.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t// The supervisor boundary only exists once a budget (and therefore the\n\t// gated driver) is anchored. Dispatching without it would run code whose\n\t// termination cannot be witnessed — refuse rather than degrade.\n\tif (!journal.state.budget) throw new VerifiedRunError(\"unsupported_boundary\");\n\tconst authority = policy.authority;\n\tconst generation = journal.state.generation;\n\tconst executionId = randomUUID();\n\tconst claims = workspaceClaim(request.workspace, request.role === \"writer\" ? \"write\" : \"read\", generation);\n\tconst timeoutMs = Math.floor(request.deadline - performance.now());\n\tconst admission = authority.store.acquire({\n\t\tsessionId: authority.sessionId,\n\t\tincarnation: authority.incarnation,\n\t\tcommandId: executionId,\n\t\tintentDigest: digestObject({ argv: request.argv, claims, role: request.role }),\n\t\tclaims,\n\t\tnow: Date.now(),\n\t\tttl: timeoutMs + policy.cleanupMs + 30000,\n\t});\n\tif (admission.status !== \"granted\") {\n\t\t// A fresh executionId can only collide with a conflicting or wedged\n\t\t// claim — quarantined effects hold theirs until witnessed (fail closed).\n\t\tthrow new VerifiedRunError(\"authority_blocked\");\n\t}\n\tconst token: GrantToken = admission.token;\n\tlet supervisorInvoked = false;\n\tlet readyObserved = false;\n\tlet result: SandboxOutcome;\n\ttry {\n\t\tjournal.append({\n\t\t\tkind: \"dispatch\",\n\t\t\texecutionId,\n\t\t\trole: request.role,\n\t\t\tclaimId: request.claimId,\n\t\t\t...(request.taskId === undefined ? {} : { taskId: request.taskId }),\n\t\t});\n\t\tif (timeoutMs <= 0 || policy.signal?.aborted) {\n\t\t\tconst failure = policy.signal?.aborted ? \"cancelled\" : \"deadline\";\n\t\t\t// Provably pre-spawn: the intent never reached the adapter, so the grant\n\t\t\t// settles immediately instead of wedging as an unwitnessed live effect.\n\t\t\tauthority.store.cancel(token);\n\t\t\tauthority.store.confirmTerminated(token);\n\t\t\tjournal.append({ kind: \"exited\", executionId, failure });\n\t\t\tthrow new VerifiedRunError(failure);\n\t\t}\n\t\t// The intent commits before the adapter is invoked: from this record on,\n\t\t// the effect may be live and a crash must quarantine it, never assume\n\t\t// it did not run.\n\t\tif (!authority.store.dispatchIntent(token, executionId)) throw new VerifiedRunError(\"authority\");\n\t\tsupervisorInvoked = true;\n\t\tresult = await executeSandbox({\n\t\t\tworkspace: request.workspace,\n\t\t\targv: request.argv,\n\t\t\twritable: request.role === \"writer\",\n\t\t\ttimeoutMs: Math.floor(request.deadline - performance.now()),\n\t\t\tcleanupMs: policy.cleanupMs,\n\t\t\tmaxOutputBytes: policy.maxOutputBytes,\n\t\t\t...(policy.signal ? { signal: policy.signal } : {}),\n\t\t\tonReady: (identity: NamespaceIdentity) => {\n\t\t\t\treadyObserved = true;\n\t\t\t\tif (journal.state.generation !== generation) throw new VerifiedRunError(\"stale_generation\");\n\t\t\t\tjournal.append({ kind: \"process_ready\", executionId, identity });\n\t\t\t\tif (!authority.store.effectStarted(token, claims, identity)) throw new VerifiedRunError(\"authority\");\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\t// Only pre-spawn rejections prove nothing ran; everything else may have\n\t\t// a live or dying effect, which stays owned until a witness or a later\n\t\t// reconcile settles it.\n\t\ttry {\n\t\t\tauthority.store.cancel(token);\n\t\t\tif (\n\t\t\t\t!supervisorInvoked ||\n\t\t\t\t(!readyObserved && error instanceof VerifiedRunError && NEVER_SPAWNED.has(error.code))\n\t\t\t)\n\t\t\t\tauthority.store.confirmTerminated(token);\n\t\t} catch (cleanupError) {\n\t\t\tthrow new AggregateError([error, cleanupError], \"Execution ownership cleanup failed\");\n\t\t}\n\t\tthrow error;\n\t}\n\tif (result.failure === \"cancelled\") authority.store.cancel(token);\n\t// Resolve means both witnesses fired: the direct child closed and the\n\t// recorded namespace drained empty. That is the termination-observed event\n\t// — the grant releases its claims here and nowhere else.\n\tif (!authority.store.confirmTerminated(token)) throw new VerifiedRunError(\"authority\");\n\tif (journal.state.generation !== generation) throw new VerifiedRunError(\"stale_generation\");\n\tjournal.append({ kind: \"exited\", executionId, failure: request.role === \"writer\" ? result.failure : null });\n\treturn { executionId, result, timeoutMs };\n}\n"]}
|