open-multi-agent-kit 0.99.0 → 1.2.0
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 +30 -1
- package/README.md +3 -3
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +1 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/register-bundled-coding-agent.d.ts +10 -0
- package/dist/bun/register-bundled-coding-agent.d.ts.map +1 -0
- package/dist/bun/register-bundled-coding-agent.js +12 -0
- package/dist/bun/register-bundled-coding-agent.js.map +1 -0
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +2 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/neo-cli.d.ts +9 -0
- package/dist/commands/neo-cli.d.ts.map +1 -0
- package/dist/commands/neo-cli.js +61 -0
- package/dist/commands/neo-cli.js.map +1 -0
- package/dist/coordination/awareness.d.ts +32 -0
- package/dist/coordination/awareness.d.ts.map +1 -0
- package/dist/coordination/awareness.js +55 -0
- package/dist/coordination/awareness.js.map +1 -0
- package/dist/coordination/broker.d.ts +79 -0
- package/dist/coordination/broker.d.ts.map +1 -0
- package/dist/coordination/broker.js +195 -0
- package/dist/coordination/broker.js.map +1 -0
- package/dist/coordination/index.d.ts +16 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +16 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/integration.d.ts +59 -0
- package/dist/coordination/integration.d.ts.map +1 -0
- package/dist/coordination/integration.js +126 -0
- package/dist/coordination/integration.js.map +1 -0
- package/dist/coordination/operation.d.ts +106 -0
- package/dist/coordination/operation.d.ts.map +1 -0
- package/dist/coordination/operation.js +179 -0
- package/dist/coordination/operation.js.map +1 -0
- package/dist/coordination/resource.d.ts +33 -0
- package/dist/coordination/resource.d.ts.map +1 -0
- package/dist/coordination/resource.js +89 -0
- package/dist/coordination/resource.js.map +1 -0
- package/dist/coordination/session.d.ts +74 -0
- package/dist/coordination/session.d.ts.map +1 -0
- package/dist/coordination/session.js +143 -0
- package/dist/coordination/session.js.map +1 -0
- package/dist/coordination/types.d.ts +68 -0
- package/dist/coordination/types.d.ts.map +1 -0
- package/dist/coordination/types.js +26 -0
- package/dist/coordination/types.js.map +1 -0
- package/dist/core/agent-session.d.ts +29 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +135 -37
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bundled-skills.d.ts +4 -0
- package/dist/core/bundled-skills.d.ts.map +1 -0
- package/dist/core/bundled-skills.js +32 -0
- package/dist/core/bundled-skills.js.map +1 -0
- package/dist/core/cli-diagnostics.d.ts +6 -0
- package/dist/core/cli-diagnostics.d.ts.map +1 -0
- package/dist/core/cli-diagnostics.js +20 -0
- package/dist/core/cli-diagnostics.js.map +1 -0
- package/dist/core/compaction/control-state.d.ts +41 -0
- package/dist/core/compaction/control-state.d.ts.map +1 -0
- package/dist/core/compaction/control-state.js +85 -0
- package/dist/core/compaction/control-state.js.map +1 -0
- package/dist/core/compaction/fallback.d.ts +60 -0
- package/dist/core/compaction/fallback.d.ts.map +1 -0
- package/dist/core/compaction/fallback.js +117 -0
- package/dist/core/compaction/fallback.js.map +1 -0
- package/dist/core/compaction/index.d.ts +2 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +2 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/context-budget-headroom-candidates.d.ts +16 -1
- package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-candidates.js +31 -13
- package/dist/core/context-budget-headroom-candidates.js.map +1 -1
- package/dist/core/context-budget-headroom-types.d.ts +7 -1
- package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-types.js +0 -1
- package/dist/core/context-budget-headroom-types.js.map +1 -1
- package/dist/core/context-budget-headroom.d.ts +22 -0
- package/dist/core/context-budget-headroom.d.ts.map +1 -1
- package/dist/core/context-budget-headroom.js +46 -2
- package/dist/core/context-budget-headroom.js.map +1 -1
- package/dist/core/context-budget-v2-global-pass.d.ts +21 -0
- package/dist/core/context-budget-v2-global-pass.d.ts.map +1 -0
- package/dist/core/context-budget-v2-global-pass.js +203 -0
- package/dist/core/context-budget-v2-global-pass.js.map +1 -0
- package/dist/core/context-budget-v2-input-validation.d.ts +4 -0
- package/dist/core/context-budget-v2-input-validation.d.ts.map +1 -0
- package/dist/core/context-budget-v2-input-validation.js +79 -0
- package/dist/core/context-budget-v2-input-validation.js.map +1 -0
- package/dist/core/context-budget-v2-observability.d.ts +15 -0
- package/dist/core/context-budget-v2-observability.d.ts.map +1 -0
- package/dist/core/context-budget-v2-observability.js +35 -0
- package/dist/core/context-budget-v2-observability.js.map +1 -0
- package/dist/core/context-budget-v2-planned-items.d.ts +17 -0
- package/dist/core/context-budget-v2-planned-items.d.ts.map +1 -0
- package/dist/core/context-budget-v2-planned-items.js +59 -0
- package/dist/core/context-budget-v2-planned-items.js.map +1 -0
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +69 -51
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-scoring.d.ts +7 -1
- package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
- package/dist/core/context-budget-v2-scoring.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +22 -3
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +41 -59
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-tiers.d.ts.map +1 -1
- package/dist/core/context-budget-v2-tiers.js +9 -42
- package/dist/core/context-budget-v2-tiers.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +14 -2
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js +6 -1
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/extensions/bundled-virtual-modules.d.ts +15 -0
- package/dist/core/extensions/bundled-virtual-modules.d.ts.map +1 -0
- package/dist/core/extensions/bundled-virtual-modules.js +63 -0
- package/dist/core/extensions/bundled-virtual-modules.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -42
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +10 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/loadout-runtime.d.ts +2 -8
- package/dist/core/loadout-runtime.d.ts.map +1 -1
- package/dist/core/loadout-runtime.js.map +1 -1
- package/dist/core/mcp/client.d.ts +27 -6
- package/dist/core/mcp/client.d.ts.map +1 -1
- package/dist/core/mcp/client.js +80 -20
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/manager.d.ts +10 -1
- package/dist/core/mcp/manager.d.ts.map +1 -1
- package/dist/core/mcp/manager.js +68 -9
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/protocol.d.ts +9 -3
- package/dist/core/mcp/protocol.d.ts.map +1 -1
- package/dist/core/mcp/protocol.js +61 -15
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/mcp/stdio-transport.d.ts +12 -1
- package/dist/core/mcp/stdio-transport.d.ts.map +1 -1
- package/dist/core/mcp/stdio-transport.js +30 -2
- package/dist/core/mcp/stdio-transport.js.map +1 -1
- package/dist/core/mcp-descriptor-injection.d.ts +26 -0
- package/dist/core/mcp-descriptor-injection.d.ts.map +1 -0
- package/dist/core/mcp-descriptor-injection.js +25 -0
- package/dist/core/mcp-descriptor-injection.js.map +1 -0
- package/dist/core/mcp-public-presets.d.ts +1 -3
- package/dist/core/mcp-public-presets.d.ts.map +1 -1
- package/dist/core/mcp-public-presets.js +3 -15
- package/dist/core/mcp-public-presets.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +24 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/neo/catalog.d.ts +20 -0
- package/dist/core/neo/catalog.d.ts.map +1 -0
- package/dist/core/neo/catalog.js +50 -0
- package/dist/core/neo/catalog.js.map +1 -0
- package/dist/core/neo/setup.d.ts +3 -0
- package/dist/core/neo/setup.d.ts.map +1 -0
- package/dist/core/neo/setup.js +47 -0
- package/dist/core/neo/setup.js.map +1 -0
- package/dist/core/provider-default-models.d.ts +2 -0
- package/dist/core/provider-default-models.d.ts.map +1 -1
- package/dist/core/provider-default-models.js +2 -0
- package/dist/core/provider-default-models.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +2 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/provider-error-classification.d.ts +57 -0
- package/dist/core/provider-error-classification.d.ts.map +1 -0
- package/dist/core/provider-error-classification.js +103 -0
- package/dist/core/provider-error-classification.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +10 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +36 -3
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-usage-commandcode.d.ts +9 -0
- package/dist/core/provider-usage-commandcode.d.ts.map +1 -0
- package/dist/core/provider-usage-commandcode.js +198 -0
- package/dist/core/provider-usage-commandcode.js.map +1 -0
- package/dist/core/provider-usage-devin.d.ts +5 -3
- package/dist/core/provider-usage-devin.d.ts.map +1 -1
- package/dist/core/provider-usage-devin.js +15 -5
- package/dist/core/provider-usage-devin.js.map +1 -1
- package/dist/core/provider-usage-types.d.ts +1 -1
- package/dist/core/provider-usage-types.d.ts.map +1 -1
- package/dist/core/provider-usage-types.js.map +1 -1
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +6 -0
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/reasoning-router-resolver.d.ts +7 -0
- package/dist/core/reasoning-router-resolver.d.ts.map +1 -1
- package/dist/core/reasoning-router-resolver.js +21 -3
- package/dist/core/reasoning-router-resolver.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts +8 -5
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +8 -5
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/resource-admission.d.ts +36 -0
- package/dist/core/resource-admission.d.ts.map +1 -1
- package/dist/core/resource-admission.js +59 -0
- package/dist/core/resource-admission.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +2 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/run-usage-ledger.d.ts +47 -0
- package/dist/core/run-usage-ledger.d.ts.map +1 -0
- package/dist/core/run-usage-ledger.js +162 -0
- package/dist/core/run-usage-ledger.js.map +1 -0
- package/dist/core/run-usage-operation.d.ts +8 -0
- package/dist/core/run-usage-operation.d.ts.map +1 -0
- package/dist/core/run-usage-operation.js +12 -0
- package/dist/core/run-usage-operation.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-compaction-service.d.ts +15 -0
- package/dist/core/session-compaction-service.d.ts.map +1 -1
- package/dist/core/session-compaction-service.js +17 -4
- package/dist/core/session-compaction-service.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts.map +1 -1
- package/dist/core/session-failure-cause.js +14 -5
- package/dist/core/session-failure-cause.js.map +1 -1
- package/dist/core/session-prompt-lifecycle.d.ts +6 -0
- package/dist/core/session-prompt-lifecycle.d.ts.map +1 -1
- package/dist/core/session-prompt-lifecycle.js +47 -2
- package/dist/core/session-prompt-lifecycle.js.map +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +4 -2
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/subagent-lane-authority.d.ts +28 -0
- package/dist/core/subagent-lane-authority.d.ts.map +1 -0
- package/dist/core/subagent-lane-authority.js +119 -0
- package/dist/core/subagent-lane-authority.js.map +1 -0
- package/dist/core/subagent-lane-contract.d.ts +114 -0
- package/dist/core/subagent-lane-contract.d.ts.map +1 -0
- package/dist/core/subagent-lane-contract.js +18 -0
- package/dist/core/subagent-lane-contract.js.map +1 -0
- package/dist/core/subagent-lane-launcher.d.ts +3 -6
- package/dist/core/subagent-lane-launcher.d.ts.map +1 -1
- package/dist/core/subagent-lane-launcher.js +53 -12
- package/dist/core/subagent-lane-launcher.js.map +1 -1
- package/dist/core/subagent-orchestration.d.ts +4 -17
- package/dist/core/subagent-orchestration.d.ts.map +1 -1
- package/dist/core/subagent-orchestration.js.map +1 -1
- package/dist/core/todo-runtime-state.d.ts +12 -0
- package/dist/core/todo-runtime-state.d.ts.map +1 -1
- package/dist/core/todo-runtime-state.js +23 -0
- package/dist/core/todo-runtime-state.js.map +1 -1
- package/dist/core/verified-run/broker.d.ts.map +1 -1
- package/dist/core/verified-run/broker.js +4 -1
- package/dist/core/verified-run/broker.js.map +1 -1
- package/dist/core/workload-permit-pool.d.ts +1 -1
- package/dist/core/workload-permit-pool.d.ts.map +1 -1
- package/dist/core/workload-permit-pool.js +3 -0
- package/dist/core/workload-permit-pool.js.map +1 -1
- package/dist/guardrails/strict-evidence-approval-adapter.d.ts +34 -0
- package/dist/guardrails/strict-evidence-approval-adapter.d.ts.map +1 -0
- package/dist/guardrails/strict-evidence-approval-adapter.js +70 -0
- package/dist/guardrails/strict-evidence-approval-adapter.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +11 -18
- package/dist/main.js.map +1 -1
- package/dist/metacognition/calibration-selective.d.ts +78 -0
- package/dist/metacognition/calibration-selective.d.ts.map +1 -0
- package/dist/metacognition/calibration-selective.js +161 -0
- package/dist/metacognition/calibration-selective.js.map +1 -0
- package/dist/metacognition/calibration.d.ts +62 -0
- package/dist/metacognition/calibration.d.ts.map +1 -0
- package/dist/metacognition/calibration.js +122 -0
- package/dist/metacognition/calibration.js.map +1 -0
- package/dist/metacognition/checkpoint.d.ts +60 -0
- package/dist/metacognition/checkpoint.d.ts.map +1 -0
- package/dist/metacognition/checkpoint.js +57 -0
- package/dist/metacognition/checkpoint.js.map +1 -0
- package/dist/metacognition/context7.d.ts +48 -0
- package/dist/metacognition/context7.d.ts.map +1 -0
- package/dist/metacognition/context7.js +154 -0
- package/dist/metacognition/context7.js.map +1 -0
- package/dist/metacognition/decision.d.ts +44 -0
- package/dist/metacognition/decision.d.ts.map +1 -0
- package/dist/metacognition/decision.js +111 -0
- package/dist/metacognition/decision.js.map +1 -0
- package/dist/metacognition/evaluation.d.ts +73 -0
- package/dist/metacognition/evaluation.d.ts.map +1 -0
- package/dist/metacognition/evaluation.js +97 -0
- package/dist/metacognition/evaluation.js.map +1 -0
- package/dist/metacognition/index.d.ts +31 -0
- package/dist/metacognition/index.d.ts.map +1 -0
- package/dist/metacognition/index.js +31 -0
- package/dist/metacognition/index.js.map +1 -0
- package/dist/metacognition/knowledge-action.d.ts +43 -0
- package/dist/metacognition/knowledge-action.d.ts.map +1 -0
- package/dist/metacognition/knowledge-action.js +60 -0
- package/dist/metacognition/knowledge-action.js.map +1 -0
- package/dist/metacognition/knowledge.d.ts +84 -0
- package/dist/metacognition/knowledge.d.ts.map +1 -0
- package/dist/metacognition/knowledge.js +165 -0
- package/dist/metacognition/knowledge.js.map +1 -0
- package/dist/metacognition/obligations.d.ts +82 -0
- package/dist/metacognition/obligations.d.ts.map +1 -0
- package/dist/metacognition/obligations.js +139 -0
- package/dist/metacognition/obligations.js.map +1 -0
- package/dist/metacognition/observation-validity.d.ts +83 -0
- package/dist/metacognition/observation-validity.d.ts.map +1 -0
- package/dist/metacognition/observation-validity.js +118 -0
- package/dist/metacognition/observation-validity.js.map +1 -0
- package/dist/metacognition/observe.d.ts +45 -0
- package/dist/metacognition/observe.d.ts.map +1 -0
- package/dist/metacognition/observe.js +59 -0
- package/dist/metacognition/observe.js.map +1 -0
- package/dist/metacognition/policy.d.ts +53 -0
- package/dist/metacognition/policy.d.ts.map +1 -0
- package/dist/metacognition/policy.js +155 -0
- package/dist/metacognition/policy.js.map +1 -0
- package/dist/metacognition/predictions.d.ts +78 -0
- package/dist/metacognition/predictions.d.ts.map +1 -0
- package/dist/metacognition/predictions.js +181 -0
- package/dist/metacognition/predictions.js.map +1 -0
- package/dist/metacognition/retrieval.d.ts +53 -0
- package/dist/metacognition/retrieval.d.ts.map +1 -0
- package/dist/metacognition/retrieval.js +170 -0
- package/dist/metacognition/retrieval.js.map +1 -0
- package/dist/metacognition/risk.d.ts +48 -0
- package/dist/metacognition/risk.d.ts.map +1 -0
- package/dist/metacognition/risk.js +165 -0
- package/dist/metacognition/risk.js.map +1 -0
- package/dist/metacognition/route-economics.d.ts +95 -0
- package/dist/metacognition/route-economics.d.ts.map +1 -0
- package/dist/metacognition/route-economics.js +110 -0
- package/dist/metacognition/route-economics.js.map +1 -0
- package/dist/metacognition/runtime-bridge.d.ts +54 -0
- package/dist/metacognition/runtime-bridge.d.ts.map +1 -0
- package/dist/metacognition/runtime-bridge.js +140 -0
- package/dist/metacognition/runtime-bridge.js.map +1 -0
- package/dist/metacognition/skills.d.ts +42 -0
- package/dist/metacognition/skills.d.ts.map +1 -0
- package/dist/metacognition/skills.js +220 -0
- package/dist/metacognition/skills.js.map +1 -0
- package/dist/metacognition/state.d.ts +110 -0
- package/dist/metacognition/state.d.ts.map +1 -0
- package/dist/metacognition/state.js +52 -0
- package/dist/metacognition/state.js.map +1 -0
- package/dist/metacognition/validation.d.ts +19 -0
- package/dist/metacognition/validation.d.ts.map +1 -0
- package/dist/metacognition/validation.js +58 -0
- package/dist/metacognition/validation.js.map +1 -0
- package/dist/metacognition/verification.d.ts +93 -0
- package/dist/metacognition/verification.d.ts.map +1 -0
- package/dist/metacognition/verification.js +132 -0
- package/dist/metacognition/verification.js.map +1 -0
- package/dist/metacognition/verifier.d.ts +49 -0
- package/dist/metacognition/verifier.d.ts.map +1 -0
- package/dist/metacognition/verifier.js +88 -0
- package/dist/metacognition/verifier.js.map +1 -0
- package/dist/modes/acp/acp-agent.d.ts +24 -0
- package/dist/modes/acp/acp-agent.d.ts.map +1 -0
- package/dist/modes/acp/acp-agent.js +133 -0
- package/dist/modes/acp/acp-agent.js.map +1 -0
- package/dist/modes/acp/acp-mode.d.ts +4 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +34 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/acp/acp-session.d.ts +4 -0
- package/dist/modes/acp/acp-session.d.ts.map +1 -0
- package/dist/modes/acp/acp-session.js +76 -0
- package/dist/modes/acp/acp-session.js.map +1 -0
- package/dist/modes/acp/acp-transport.d.ts +5 -0
- package/dist/modes/acp/acp-transport.d.ts.map +1 -0
- package/dist/modes/acp/acp-transport.js +90 -0
- package/dist/modes/acp/acp-transport.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/observation/identity.d.ts +14 -0
- package/dist/observation/identity.d.ts.map +1 -0
- package/dist/observation/identity.js +29 -0
- package/dist/observation/identity.js.map +1 -0
- package/dist/observation/index.d.ts +13 -0
- package/dist/observation/index.d.ts.map +1 -0
- package/dist/observation/index.js +13 -0
- package/dist/observation/index.js.map +1 -0
- package/dist/observation/observe-mode.d.ts +46 -0
- package/dist/observation/observe-mode.d.ts.map +1 -0
- package/dist/observation/observe-mode.js +83 -0
- package/dist/observation/observe-mode.js.map +1 -0
- package/dist/observation/store.d.ts +53 -0
- package/dist/observation/store.d.ts.map +1 -0
- package/dist/observation/store.js +126 -0
- package/dist/observation/store.js.map +1 -0
- package/dist/observation/types.d.ts +72 -0
- package/dist/observation/types.d.ts.map +1 -0
- package/dist/observation/types.js +9 -0
- package/dist/observation/types.js.map +1 -0
- package/dist/observation/view.d.ts +39 -0
- package/dist/observation/view.d.ts.map +1 -0
- package/dist/observation/view.js +173 -0
- package/dist/observation/view.js.map +1 -0
- package/docs/audit-revalidation-2026-09-17.md +77 -0
- package/docs/devin-harness.md +33 -4
- package/docs/ecraf-normalization.md +83 -0
- package/docs/metacognition.md +51 -0
- package/docs/model-catalog-refresh.md +110 -1
- package/docs/models.md +1 -1
- package/docs/neo.md +134 -0
- package/docs/providers.md +125 -6
- package/docs/run-usage-ledger.md +56 -0
- package/docs/runtime-algorithms.md +151 -3
- package/docs/skills.md +1 -1
- package/docs/usage.md +2 -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/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/subagent/adaptive-agent-runtime.ts +14 -1
- package/examples/extensions/subagent/graph-result.ts +48 -0
- package/examples/extensions/subagent/index.ts +246 -111
- package/examples/extensions/subagent/managed-process-tree.ts +42 -0
- package/examples/extensions/subagent/managed-process.test.ts +24 -0
- package/examples/extensions/subagent/managed-process.ts +93 -112
- package/examples/extensions/subagent/subagent-runtime-types.ts +17 -1
- package/examples/extensions/subagent/subagent-stream.ts +161 -0
- package/examples/extensions/terminal-browser/README.md +54 -0
- package/examples/extensions/terminal-browser/bridge-protocol.ts +29 -0
- package/examples/extensions/terminal-browser/bridge.ts +219 -0
- package/examples/extensions/terminal-browser/browser-surface.ts +288 -0
- package/examples/extensions/terminal-browser/index.ts +215 -0
- package/examples/extensions/terminal-browser/placeholders.ts +49 -0
- 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 +8 -7
- package/resources/neo/skills/omk-browser/SKILL.md +32 -0
- package/resources/neo/skills/omk-code-review/SKILL.md +24 -0
- package/resources/neo/skills/omk-computeruse/SKILL.md +34 -0
- package/resources/neo/skills/omk-mcp-setup/SKILL.md +48 -0
- package/resources/neo/skills/omk-research/SKILL.md +24 -0
- package/resources/neo/skills/omk-site/SKILL.md +28 -0
|
@@ -9,4 +9,27 @@ export function setCurrentTodoState(state) {
|
|
|
9
9
|
export function resetCurrentTodoState() {
|
|
10
10
|
currentTodoState = EMPTY_TODO_STATE;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Host control authority for the compaction service. Maps the live TODO ledger
|
|
14
|
+
* onto the preserved-provenance fields: every non-done item stays an open task
|
|
15
|
+
* so resume never mistakes "summarized" for "finished", and blocked items keep
|
|
16
|
+
* their blocker reason. The snapshot is deterministic for unchanged state —
|
|
17
|
+
* it deliberately excludes `updatedAt` — because the commit boundary digests
|
|
18
|
+
* it and discards a summary captured under different control state. `branch`
|
|
19
|
+
* stays null until a VCS-branch authority is attached; no production producer
|
|
20
|
+
* exists today and an empty string would be worse than an explicit null.
|
|
21
|
+
*/
|
|
22
|
+
export function todoControlState() {
|
|
23
|
+
const openTasks = [];
|
|
24
|
+
const blockerReasons = [];
|
|
25
|
+
for (const item of currentTodoState.items) {
|
|
26
|
+
if (item.status === "done")
|
|
27
|
+
continue;
|
|
28
|
+
openTasks.push(`${item.id} ${item.label}`);
|
|
29
|
+
if (item.status === "blocked") {
|
|
30
|
+
blockerReasons.push(item.detail === undefined ? `${item.id} ${item.label}` : `${item.id} ${item.label} — ${item.detail}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { openTasks, blockerReasons, branch: null };
|
|
34
|
+
}
|
|
12
35
|
//# sourceMappingURL=todo-runtime-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"todo-runtime-state.js","sourceRoot":"","sources":["../../src/core/todo-runtime-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"todo-runtime-state.js","sourceRoot":"","sources":["../../src/core/todo-runtime-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAkB,MAAM,iBAAiB,CAAC;AAEnE,IAAI,gBAAgB,GAAc,gBAAgB,CAAC;AAEnD,MAAM,UAAU,mBAAmB,GAAc;IAChD,OAAO,gBAAgB,CAAC;AAAA,CACxB;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAgB,EAAQ;IAC3D,gBAAgB,GAAG,KAAK,CAAC;AAAA,CACzB;AAED,MAAM,UAAU,qBAAqB,GAAS;IAC7C,gBAAgB,GAAG,gBAAgB,CAAC;AAAA,CACpC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,GAA2B;IAC1D,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;YAAE,SAAS;QACrC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,cAAc,CAAC,IAAI,CAClB,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,QAAM,IAAI,CAAC,MAAM,EAAE,CACpG,CAAC;QACH,CAAC;IACF,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,CACnD","sourcesContent":["import type { CompactionControlState } from \"./compaction/control-state.ts\";\nimport { EMPTY_TODO_STATE, type TodoState } from \"./todo-state.ts\";\n\nlet currentTodoState: TodoState = EMPTY_TODO_STATE;\n\nexport function getCurrentTodoState(): TodoState {\n\treturn currentTodoState;\n}\n\nexport function setCurrentTodoState(state: TodoState): void {\n\tcurrentTodoState = state;\n}\n\nexport function resetCurrentTodoState(): void {\n\tcurrentTodoState = EMPTY_TODO_STATE;\n}\n\n/**\n * Host control authority for the compaction service. Maps the live TODO ledger\n * onto the preserved-provenance fields: every non-done item stays an open task\n * so resume never mistakes \"summarized\" for \"finished\", and blocked items keep\n * their blocker reason. The snapshot is deterministic for unchanged state —\n * it deliberately excludes `updatedAt` — because the commit boundary digests\n * it and discards a summary captured under different control state. `branch`\n * stays null until a VCS-branch authority is attached; no production producer\n * exists today and an empty string would be worse than an explicit null.\n */\nexport function todoControlState(): CompactionControlState {\n\tconst openTasks: string[] = [];\n\tconst blockerReasons: string[] = [];\n\tfor (const item of currentTodoState.items) {\n\t\tif (item.status === \"done\") continue;\n\t\topenTasks.push(`${item.id} ${item.label}`);\n\t\tif (item.status === \"blocked\") {\n\t\t\tblockerReasons.push(\n\t\t\t\titem.detail === undefined ? `${item.id} ${item.label}` : `${item.id} ${item.label} — ${item.detail}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn { openTasks, blockerReasons, branch: null };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/broker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAsCjE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AACD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAE,QAAQ,GAAG,UAAqB,GAAG,MAAM,CA0ChH;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAS3C;AAED,0GAA0G;AAC1G,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/broker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAsCjE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AACD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAE,QAAQ,GAAG,UAAqB,GAAG,MAAM,CA0ChH;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAS3C;AAED,0GAA0G;AAC1G,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8GvF","sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { release } from \"node:os\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunContract } from \"omk-protocol\";\nimport type { NamespaceIdentity } from \"./namespace-identity.ts\";\nimport { identityFromSandboxInfo, PROCESS_GATE_ARGV } from \"./process-gate.ts\";\nimport { digestBytes, digestObject, VerifiedRunError } from \"./storage.ts\";\n\nconst BWRAP = \"/usr/bin/bwrap\";\nconst SYSTEM_ARGS = [\n\t\"--unshare-all\",\n\t\"--die-with-parent\",\n\t\"--new-session\",\n\t\"--cap-drop\",\n\t\"ALL\",\n\t\"--clearenv\",\n\t\"--ro-bind\",\n\t\"/usr\",\n\t\"/usr\",\n\t\"--symlink\",\n\t\"usr/bin\",\n\t\"/bin\",\n\t\"--symlink\",\n\t\"usr/lib\",\n\t\"/lib\",\n\t\"--symlink\",\n\t\"usr/lib64\",\n\t\"/lib64\",\n\t\"--proc\",\n\t\"/proc\",\n\t\"--dev\",\n\t\"/dev\",\n\t\"--tmpfs\",\n\t\"/tmp\",\n\t\"--setenv\",\n\t\"PATH\",\n\t\"/usr/bin:/bin\",\n\t\"--setenv\",\n\t\"LANG\",\n\t\"C.UTF-8\",\n] as const;\n\nexport interface SandboxExecution {\n\treadonly workspace: string;\n\treadonly argv: readonly string[];\n\treadonly writable: boolean;\n\treadonly timeoutMs: number;\n\treadonly cleanupMs: number;\n\treadonly maxOutputBytes: number;\n\treadonly signal?: AbortSignal;\n\treadonly onReady?: (identity: NamespaceIdentity) => void | Promise<void>;\n}\nexport interface SandboxOutcome {\n\treadonly stdout: Buffer;\n\treadonly stderr: Buffer;\n\treadonly exitCode: number | null;\n\treadonly failure: string | null;\n\treadonly startedAt: string;\n\treadonly finishedAt: string;\n\treadonly durationMs: number;\n}\n\nexport function commandEnvironmentDigest(contract: RunContract, driver: \"legacy\" | \"gated-v1\" = \"legacy\"): string {\n\tif (process.platform !== \"linux\" || !existsSync(BWRAP)) throw new VerifiedRunError(\"unsupported\");\n\tlet writers: readonly (readonly string[])[];\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-v1\":\n\t\t\twriters = [contract.writer];\n\t\t\tbreak;\n\t\tcase \"linux-scripted-agent-v1\":\n\t\t\twriters = contract.writer.steps;\n\t\t\tbreak;\n\t\tcase \"linux-command-dag-v1\":\n\t\t\twriters = contract.writer.tasks.flatMap((task) => task.attempts);\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tconst binaries = [\n\t\t...new Set([\n\t\t\tBWRAP,\n\t\t\t...writers.map((argv) => argv[0]),\n\t\t\t...contract.checks.map((check) => check.argv[0]),\n\t\t\t...(driver === \"gated-v1\" ? [PROCESS_GATE_ARGV[0]] : []),\n\t\t]),\n\t];\n\tconst materials = binaries.map((binary) => {\n\t\tif (!binary || (!binary.startsWith(\"/usr/bin/\") && !binary.startsWith(\"/bin/\")))\n\t\t\tthrow new VerifiedRunError(\"unsupported_executable\");\n\t\tconst path = realpathSync(binary);\n\t\tif (!path.startsWith(\"/usr/\")) throw new VerifiedRunError(\"unsupported_executable\");\n\t\treturn { path, digest: digestBytes(readFileSync(path)) };\n\t});\n\treturn digestObject({\n\t\tprofile: contract.profile,\n\t\tplatform: process.platform,\n\t\tarchitecture: process.arch,\n\t\tkernel: release(),\n\t\tsandbox: SYSTEM_ARGS,\n\t\t...(driver === \"gated-v1\" ? { gate: PROCESS_GATE_ARGV, infoFd: 3 } : {}),\n\t\tbinaries: materials,\n\t});\n}\n\nexport function probeVerifiedSandbox(): void {\n\tif (process.platform !== \"linux\" || !existsSync(BWRAP)) throw new VerifiedRunError(\"unsupported\");\n\tconst probe = spawnSync(BWRAP, [...SYSTEM_ARGS, \"--\", \"/bin/true\"], {\n\t\tenv: {},\n\t\ttimeout: 3000,\n\t\tmaxBuffer: 4096,\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (probe.error || probe.status !== 0) throw new VerifiedRunError(\"unsupported\");\n}\n\n/** The only process dispatch port; close means the PID namespace and its inherited pipes have drained. */\nexport async function executeSandbox(request: SandboxExecution): Promise<SandboxOutcome> {\n\tif (request.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tif (request.timeoutMs <= 0) throw new VerifiedRunError(\"deadline\");\n\tconst started = performance.now();\n\tconst startedAt = new Date().toISOString();\n\tconst argv = [\n\t\t...SYSTEM_ARGS,\n\t\trequest.writable ? \"--bind\" : \"--ro-bind\",\n\t\trequest.workspace,\n\t\t\"/workspace\",\n\t\t\"--chdir\",\n\t\t\"/workspace\",\n\t\t...(request.onReady ? [\"--info-fd\", \"3\", \"--\", ...PROCESS_GATE_ARGV] : [\"--\"]),\n\t\t...request.argv,\n\t];\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = request.onReady\n\t\t\t? spawn(BWRAP, argv, { env: {}, stdio: [\"pipe\", \"pipe\", \"pipe\", \"pipe\"] })\n\t\t\t: spawn(BWRAP, argv, { env: {}, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tlet gateFailed = false;\n\t\tlet gateError: unknown;\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet size = 0;\n\t\tlet failure: string | null = null;\n\t\tlet cleanup: ReturnType<typeof setTimeout> | undefined;\n\t\tlet finished = false;\n\t\tconst stop = (reason: string): void => {\n\t\t\tif (finished || failure) return;\n\t\t\tfailure = reason;\n\t\t\tchild.kill(\"SIGKILL\");\n\t\t\t// When the gate already failed, surface its real cause rather than a\n\t\t\t// generic unsettled — the close handler may still arrive first, and\n\t\t\t// either path must report the same error.\n\t\t\tcleanup = setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\treject(\n\t\t\t\t\t\tgateFailed ? (gateError ?? new VerifiedRunError(\"unsettled\")) : new VerifiedRunError(\"unsettled\"),\n\t\t\t\t\t),\n\t\t\t\trequest.cleanupMs,\n\t\t\t);\n\t\t};\n\t\tconst deadline = setTimeout(() => stop(\"deadline\"), request.timeoutMs);\n\t\tconst abort = (): void => stop(\"cancelled\");\n\t\trequest.signal?.addEventListener(\"abort\", abort, { once: true });\n\t\tif (request.signal?.aborted) abort();\n\t\tconst collect = (target: Buffer[], chunk: Buffer): void => {\n\t\t\tif (failure) return;\n\t\t\tsize += chunk.length;\n\t\t\tif (size > request.maxOutputBytes) {\n\t\t\t\tstop(\"output_limit\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(chunk);\n\t\t};\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => collect(stdout, chunk));\n\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => collect(stderr, chunk));\n\t\tif (request.onReady) {\n\t\t\tconst info = child.stdio[3];\n\t\t\tlet metadata = \"\";\n\t\t\tif (!info || !child.stdin) {\n\t\t\t\tgateFailed = true;\n\t\t\t\tgateError = new VerifiedRunError(\"process_identity\");\n\t\t\t\tstop(\"process_identity\");\n\t\t\t} else {\n\t\t\t\tchild.stdin.on(\"error\", () => stop(\"execution_failed\"));\n\t\t\t\tinfo.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tmetadata += chunk.toString(\"utf8\");\n\t\t\t\t\tif (metadata.length > 4096) stop(\"process_identity\");\n\t\t\t\t});\n\t\t\t\tinfo.once(\"end\", async () => {\n\t\t\t\t\tif (finished || failure) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait request.onReady?.(identityFromSandboxInfo(metadata));\n\t\t\t\t\t\tif (performance.now() - started >= request.timeoutMs || request.signal?.aborted)\n\t\t\t\t\t\t\tstop(request.signal?.aborted ? \"cancelled\" : \"deadline\");\n\t\t\t\t\t\tif (!finished && !failure) child.stdin?.end(\"go\\n\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tgateFailed = true;\n\t\t\t\t\t\tgateError = error;\n\t\t\t\t\t\tstop(\"process_identity\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tchild.once(\"error\", () => {\n\t\t\tfailure = \"execution_failed\";\n\t\t});\n\t\tchild.once(\"close\", (exitCode) => {\n\t\t\tfinished = true;\n\t\t\tclearTimeout(deadline);\n\t\t\tclearTimeout(cleanup);\n\t\t\trequest.signal?.removeEventListener(\"abort\", abort);\n\t\t\tif (gateFailed) {\n\t\t\t\treject(gateError);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst durationMs = Math.max(0, Math.round(performance.now() - started));\n\t\t\tresolve({\n\t\t\t\tstdout: Buffer.concat(stdout),\n\t\t\t\tstderr: Buffer.concat(stderr),\n\t\t\t\texitCode,\n\t\t\t\tfailure: failure ?? (exitCode === 0 ? null : \"execution_failed\"),\n\t\t\t\tstartedAt,\n\t\t\t\t// Project the finish instant from the start's wall reference and monotonic elapsed time.\n\t\t\t\tfinishedAt: new Date(Date.parse(startedAt) + durationMs).toISOString(),\n\t\t\t\tdurationMs,\n\t\t\t});\n\t\t});\n\t});\n}\n"]}
|
|
@@ -129,7 +129,10 @@ export async function executeSandbox(request) {
|
|
|
129
129
|
return;
|
|
130
130
|
failure = reason;
|
|
131
131
|
child.kill("SIGKILL");
|
|
132
|
-
|
|
132
|
+
// When the gate already failed, surface its real cause rather than a
|
|
133
|
+
// generic unsettled — the close handler may still arrive first, and
|
|
134
|
+
// either path must report the same error.
|
|
135
|
+
cleanup = setTimeout(() => reject(gateFailed ? (gateError ?? new VerifiedRunError("unsettled")) : new VerifiedRunError("unsettled")), request.cleanupMs);
|
|
133
136
|
};
|
|
134
137
|
const deadline = setTimeout(() => stop("deadline"), request.timeoutMs);
|
|
135
138
|
const abort = () => stop("cancelled");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/core/verified-run/broker.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { release } from \"node:os\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunContract } from \"omk-protocol\";\nimport type { NamespaceIdentity } from \"./namespace-identity.ts\";\nimport { identityFromSandboxInfo, PROCESS_GATE_ARGV } from \"./process-gate.ts\";\nimport { digestBytes, digestObject, VerifiedRunError } from \"./storage.ts\";\n\nconst BWRAP = \"/usr/bin/bwrap\";\nconst SYSTEM_ARGS = [\n\t\"--unshare-all\",\n\t\"--die-with-parent\",\n\t\"--new-session\",\n\t\"--cap-drop\",\n\t\"ALL\",\n\t\"--clearenv\",\n\t\"--ro-bind\",\n\t\"/usr\",\n\t\"/usr\",\n\t\"--symlink\",\n\t\"usr/bin\",\n\t\"/bin\",\n\t\"--symlink\",\n\t\"usr/lib\",\n\t\"/lib\",\n\t\"--symlink\",\n\t\"usr/lib64\",\n\t\"/lib64\",\n\t\"--proc\",\n\t\"/proc\",\n\t\"--dev\",\n\t\"/dev\",\n\t\"--tmpfs\",\n\t\"/tmp\",\n\t\"--setenv\",\n\t\"PATH\",\n\t\"/usr/bin:/bin\",\n\t\"--setenv\",\n\t\"LANG\",\n\t\"C.UTF-8\",\n] as const;\n\nexport interface SandboxExecution {\n\treadonly workspace: string;\n\treadonly argv: readonly string[];\n\treadonly writable: boolean;\n\treadonly timeoutMs: number;\n\treadonly cleanupMs: number;\n\treadonly maxOutputBytes: number;\n\treadonly signal?: AbortSignal;\n\treadonly onReady?: (identity: NamespaceIdentity) => void | Promise<void>;\n}\nexport interface SandboxOutcome {\n\treadonly stdout: Buffer;\n\treadonly stderr: Buffer;\n\treadonly exitCode: number | null;\n\treadonly failure: string | null;\n\treadonly startedAt: string;\n\treadonly finishedAt: string;\n\treadonly durationMs: number;\n}\n\nexport function commandEnvironmentDigest(contract: RunContract, driver: \"legacy\" | \"gated-v1\" = \"legacy\"): string {\n\tif (process.platform !== \"linux\" || !existsSync(BWRAP)) throw new VerifiedRunError(\"unsupported\");\n\tlet writers: readonly (readonly string[])[];\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-v1\":\n\t\t\twriters = [contract.writer];\n\t\t\tbreak;\n\t\tcase \"linux-scripted-agent-v1\":\n\t\t\twriters = contract.writer.steps;\n\t\t\tbreak;\n\t\tcase \"linux-command-dag-v1\":\n\t\t\twriters = contract.writer.tasks.flatMap((task) => task.attempts);\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tconst binaries = [\n\t\t...new Set([\n\t\t\tBWRAP,\n\t\t\t...writers.map((argv) => argv[0]),\n\t\t\t...contract.checks.map((check) => check.argv[0]),\n\t\t\t...(driver === \"gated-v1\" ? [PROCESS_GATE_ARGV[0]] : []),\n\t\t]),\n\t];\n\tconst materials = binaries.map((binary) => {\n\t\tif (!binary || (!binary.startsWith(\"/usr/bin/\") && !binary.startsWith(\"/bin/\")))\n\t\t\tthrow new VerifiedRunError(\"unsupported_executable\");\n\t\tconst path = realpathSync(binary);\n\t\tif (!path.startsWith(\"/usr/\")) throw new VerifiedRunError(\"unsupported_executable\");\n\t\treturn { path, digest: digestBytes(readFileSync(path)) };\n\t});\n\treturn digestObject({\n\t\tprofile: contract.profile,\n\t\tplatform: process.platform,\n\t\tarchitecture: process.arch,\n\t\tkernel: release(),\n\t\tsandbox: SYSTEM_ARGS,\n\t\t...(driver === \"gated-v1\" ? { gate: PROCESS_GATE_ARGV, infoFd: 3 } : {}),\n\t\tbinaries: materials,\n\t});\n}\n\nexport function probeVerifiedSandbox(): void {\n\tif (process.platform !== \"linux\" || !existsSync(BWRAP)) throw new VerifiedRunError(\"unsupported\");\n\tconst probe = spawnSync(BWRAP, [...SYSTEM_ARGS, \"--\", \"/bin/true\"], {\n\t\tenv: {},\n\t\ttimeout: 3000,\n\t\tmaxBuffer: 4096,\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (probe.error || probe.status !== 0) throw new VerifiedRunError(\"unsupported\");\n}\n\n/** The only process dispatch port; close means the PID namespace and its inherited pipes have drained. */\nexport async function executeSandbox(request: SandboxExecution): Promise<SandboxOutcome> {\n\tif (request.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tif (request.timeoutMs <= 0) throw new VerifiedRunError(\"deadline\");\n\tconst started = performance.now();\n\tconst startedAt = new Date().toISOString();\n\tconst argv = [\n\t\t...SYSTEM_ARGS,\n\t\trequest.writable ? \"--bind\" : \"--ro-bind\",\n\t\trequest.workspace,\n\t\t\"/workspace\",\n\t\t\"--chdir\",\n\t\t\"/workspace\",\n\t\t...(request.onReady ? [\"--info-fd\", \"3\", \"--\", ...PROCESS_GATE_ARGV] : [\"--\"]),\n\t\t...request.argv,\n\t];\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = request.onReady\n\t\t\t? spawn(BWRAP, argv, { env: {}, stdio: [\"pipe\", \"pipe\", \"pipe\", \"pipe\"] })\n\t\t\t: spawn(BWRAP, argv, { env: {}, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tlet gateFailed = false;\n\t\tlet gateError: unknown;\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet size = 0;\n\t\tlet failure: string | null = null;\n\t\tlet cleanup: ReturnType<typeof setTimeout> | undefined;\n\t\tlet finished = false;\n\t\tconst stop = (reason: string): void => {\n\t\t\tif (finished || failure) return;\n\t\t\tfailure = reason;\n\t\t\tchild.kill(\"SIGKILL\");\n\t\t\tcleanup = setTimeout(() => reject(new VerifiedRunError(\"unsettled\")), request.cleanupMs);\n\t\t};\n\t\tconst deadline = setTimeout(() => stop(\"deadline\"), request.timeoutMs);\n\t\tconst abort = (): void => stop(\"cancelled\");\n\t\trequest.signal?.addEventListener(\"abort\", abort, { once: true });\n\t\tif (request.signal?.aborted) abort();\n\t\tconst collect = (target: Buffer[], chunk: Buffer): void => {\n\t\t\tif (failure) return;\n\t\t\tsize += chunk.length;\n\t\t\tif (size > request.maxOutputBytes) {\n\t\t\t\tstop(\"output_limit\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(chunk);\n\t\t};\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => collect(stdout, chunk));\n\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => collect(stderr, chunk));\n\t\tif (request.onReady) {\n\t\t\tconst info = child.stdio[3];\n\t\t\tlet metadata = \"\";\n\t\t\tif (!info || !child.stdin) {\n\t\t\t\tgateFailed = true;\n\t\t\t\tgateError = new VerifiedRunError(\"process_identity\");\n\t\t\t\tstop(\"process_identity\");\n\t\t\t} else {\n\t\t\t\tchild.stdin.on(\"error\", () => stop(\"execution_failed\"));\n\t\t\t\tinfo.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tmetadata += chunk.toString(\"utf8\");\n\t\t\t\t\tif (metadata.length > 4096) stop(\"process_identity\");\n\t\t\t\t});\n\t\t\t\tinfo.once(\"end\", async () => {\n\t\t\t\t\tif (finished || failure) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait request.onReady?.(identityFromSandboxInfo(metadata));\n\t\t\t\t\t\tif (performance.now() - started >= request.timeoutMs || request.signal?.aborted)\n\t\t\t\t\t\t\tstop(request.signal?.aborted ? \"cancelled\" : \"deadline\");\n\t\t\t\t\t\tif (!finished && !failure) child.stdin?.end(\"go\\n\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tgateFailed = true;\n\t\t\t\t\t\tgateError = error;\n\t\t\t\t\t\tstop(\"process_identity\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tchild.once(\"error\", () => {\n\t\t\tfailure = \"execution_failed\";\n\t\t});\n\t\tchild.once(\"close\", (exitCode) => {\n\t\t\tfinished = true;\n\t\t\tclearTimeout(deadline);\n\t\t\tclearTimeout(cleanup);\n\t\t\trequest.signal?.removeEventListener(\"abort\", abort);\n\t\t\tif (gateFailed) {\n\t\t\t\treject(gateError);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst durationMs = Math.max(0, Math.round(performance.now() - started));\n\t\t\tresolve({\n\t\t\t\tstdout: Buffer.concat(stdout),\n\t\t\t\tstderr: Buffer.concat(stderr),\n\t\t\t\texitCode,\n\t\t\t\tfailure: failure ?? (exitCode === 0 ? null : \"execution_failed\"),\n\t\t\t\tstartedAt,\n\t\t\t\t// Project the finish instant from the start's wall reference and monotonic elapsed time.\n\t\t\t\tfinishedAt: new Date(Date.parse(startedAt) + durationMs).toISOString(),\n\t\t\t\tdurationMs,\n\t\t\t});\n\t\t});\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/core/verified-run/broker.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { release } from \"node:os\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunContract } from \"omk-protocol\";\nimport type { NamespaceIdentity } from \"./namespace-identity.ts\";\nimport { identityFromSandboxInfo, PROCESS_GATE_ARGV } from \"./process-gate.ts\";\nimport { digestBytes, digestObject, VerifiedRunError } from \"./storage.ts\";\n\nconst BWRAP = \"/usr/bin/bwrap\";\nconst SYSTEM_ARGS = [\n\t\"--unshare-all\",\n\t\"--die-with-parent\",\n\t\"--new-session\",\n\t\"--cap-drop\",\n\t\"ALL\",\n\t\"--clearenv\",\n\t\"--ro-bind\",\n\t\"/usr\",\n\t\"/usr\",\n\t\"--symlink\",\n\t\"usr/bin\",\n\t\"/bin\",\n\t\"--symlink\",\n\t\"usr/lib\",\n\t\"/lib\",\n\t\"--symlink\",\n\t\"usr/lib64\",\n\t\"/lib64\",\n\t\"--proc\",\n\t\"/proc\",\n\t\"--dev\",\n\t\"/dev\",\n\t\"--tmpfs\",\n\t\"/tmp\",\n\t\"--setenv\",\n\t\"PATH\",\n\t\"/usr/bin:/bin\",\n\t\"--setenv\",\n\t\"LANG\",\n\t\"C.UTF-8\",\n] as const;\n\nexport interface SandboxExecution {\n\treadonly workspace: string;\n\treadonly argv: readonly string[];\n\treadonly writable: boolean;\n\treadonly timeoutMs: number;\n\treadonly cleanupMs: number;\n\treadonly maxOutputBytes: number;\n\treadonly signal?: AbortSignal;\n\treadonly onReady?: (identity: NamespaceIdentity) => void | Promise<void>;\n}\nexport interface SandboxOutcome {\n\treadonly stdout: Buffer;\n\treadonly stderr: Buffer;\n\treadonly exitCode: number | null;\n\treadonly failure: string | null;\n\treadonly startedAt: string;\n\treadonly finishedAt: string;\n\treadonly durationMs: number;\n}\n\nexport function commandEnvironmentDigest(contract: RunContract, driver: \"legacy\" | \"gated-v1\" = \"legacy\"): string {\n\tif (process.platform !== \"linux\" || !existsSync(BWRAP)) throw new VerifiedRunError(\"unsupported\");\n\tlet writers: readonly (readonly string[])[];\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-v1\":\n\t\t\twriters = [contract.writer];\n\t\t\tbreak;\n\t\tcase \"linux-scripted-agent-v1\":\n\t\t\twriters = contract.writer.steps;\n\t\t\tbreak;\n\t\tcase \"linux-command-dag-v1\":\n\t\t\twriters = contract.writer.tasks.flatMap((task) => task.attempts);\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tconst binaries = [\n\t\t...new Set([\n\t\t\tBWRAP,\n\t\t\t...writers.map((argv) => argv[0]),\n\t\t\t...contract.checks.map((check) => check.argv[0]),\n\t\t\t...(driver === \"gated-v1\" ? [PROCESS_GATE_ARGV[0]] : []),\n\t\t]),\n\t];\n\tconst materials = binaries.map((binary) => {\n\t\tif (!binary || (!binary.startsWith(\"/usr/bin/\") && !binary.startsWith(\"/bin/\")))\n\t\t\tthrow new VerifiedRunError(\"unsupported_executable\");\n\t\tconst path = realpathSync(binary);\n\t\tif (!path.startsWith(\"/usr/\")) throw new VerifiedRunError(\"unsupported_executable\");\n\t\treturn { path, digest: digestBytes(readFileSync(path)) };\n\t});\n\treturn digestObject({\n\t\tprofile: contract.profile,\n\t\tplatform: process.platform,\n\t\tarchitecture: process.arch,\n\t\tkernel: release(),\n\t\tsandbox: SYSTEM_ARGS,\n\t\t...(driver === \"gated-v1\" ? { gate: PROCESS_GATE_ARGV, infoFd: 3 } : {}),\n\t\tbinaries: materials,\n\t});\n}\n\nexport function probeVerifiedSandbox(): void {\n\tif (process.platform !== \"linux\" || !existsSync(BWRAP)) throw new VerifiedRunError(\"unsupported\");\n\tconst probe = spawnSync(BWRAP, [...SYSTEM_ARGS, \"--\", \"/bin/true\"], {\n\t\tenv: {},\n\t\ttimeout: 3000,\n\t\tmaxBuffer: 4096,\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (probe.error || probe.status !== 0) throw new VerifiedRunError(\"unsupported\");\n}\n\n/** The only process dispatch port; close means the PID namespace and its inherited pipes have drained. */\nexport async function executeSandbox(request: SandboxExecution): Promise<SandboxOutcome> {\n\tif (request.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tif (request.timeoutMs <= 0) throw new VerifiedRunError(\"deadline\");\n\tconst started = performance.now();\n\tconst startedAt = new Date().toISOString();\n\tconst argv = [\n\t\t...SYSTEM_ARGS,\n\t\trequest.writable ? \"--bind\" : \"--ro-bind\",\n\t\trequest.workspace,\n\t\t\"/workspace\",\n\t\t\"--chdir\",\n\t\t\"/workspace\",\n\t\t...(request.onReady ? [\"--info-fd\", \"3\", \"--\", ...PROCESS_GATE_ARGV] : [\"--\"]),\n\t\t...request.argv,\n\t];\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = request.onReady\n\t\t\t? spawn(BWRAP, argv, { env: {}, stdio: [\"pipe\", \"pipe\", \"pipe\", \"pipe\"] })\n\t\t\t: spawn(BWRAP, argv, { env: {}, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\t\tlet gateFailed = false;\n\t\tlet gateError: unknown;\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet size = 0;\n\t\tlet failure: string | null = null;\n\t\tlet cleanup: ReturnType<typeof setTimeout> | undefined;\n\t\tlet finished = false;\n\t\tconst stop = (reason: string): void => {\n\t\t\tif (finished || failure) return;\n\t\t\tfailure = reason;\n\t\t\tchild.kill(\"SIGKILL\");\n\t\t\t// When the gate already failed, surface its real cause rather than a\n\t\t\t// generic unsettled — the close handler may still arrive first, and\n\t\t\t// either path must report the same error.\n\t\t\tcleanup = setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\treject(\n\t\t\t\t\t\tgateFailed ? (gateError ?? new VerifiedRunError(\"unsettled\")) : new VerifiedRunError(\"unsettled\"),\n\t\t\t\t\t),\n\t\t\t\trequest.cleanupMs,\n\t\t\t);\n\t\t};\n\t\tconst deadline = setTimeout(() => stop(\"deadline\"), request.timeoutMs);\n\t\tconst abort = (): void => stop(\"cancelled\");\n\t\trequest.signal?.addEventListener(\"abort\", abort, { once: true });\n\t\tif (request.signal?.aborted) abort();\n\t\tconst collect = (target: Buffer[], chunk: Buffer): void => {\n\t\t\tif (failure) return;\n\t\t\tsize += chunk.length;\n\t\t\tif (size > request.maxOutputBytes) {\n\t\t\t\tstop(\"output_limit\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(chunk);\n\t\t};\n\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => collect(stdout, chunk));\n\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => collect(stderr, chunk));\n\t\tif (request.onReady) {\n\t\t\tconst info = child.stdio[3];\n\t\t\tlet metadata = \"\";\n\t\t\tif (!info || !child.stdin) {\n\t\t\t\tgateFailed = true;\n\t\t\t\tgateError = new VerifiedRunError(\"process_identity\");\n\t\t\t\tstop(\"process_identity\");\n\t\t\t} else {\n\t\t\t\tchild.stdin.on(\"error\", () => stop(\"execution_failed\"));\n\t\t\t\tinfo.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tmetadata += chunk.toString(\"utf8\");\n\t\t\t\t\tif (metadata.length > 4096) stop(\"process_identity\");\n\t\t\t\t});\n\t\t\t\tinfo.once(\"end\", async () => {\n\t\t\t\t\tif (finished || failure) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait request.onReady?.(identityFromSandboxInfo(metadata));\n\t\t\t\t\t\tif (performance.now() - started >= request.timeoutMs || request.signal?.aborted)\n\t\t\t\t\t\t\tstop(request.signal?.aborted ? \"cancelled\" : \"deadline\");\n\t\t\t\t\t\tif (!finished && !failure) child.stdin?.end(\"go\\n\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tgateFailed = true;\n\t\t\t\t\t\tgateError = error;\n\t\t\t\t\t\tstop(\"process_identity\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tchild.once(\"error\", () => {\n\t\t\tfailure = \"execution_failed\";\n\t\t});\n\t\tchild.once(\"close\", (exitCode) => {\n\t\t\tfinished = true;\n\t\t\tclearTimeout(deadline);\n\t\t\tclearTimeout(cleanup);\n\t\t\trequest.signal?.removeEventListener(\"abort\", abort);\n\t\t\tif (gateFailed) {\n\t\t\t\treject(gateError);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst durationMs = Math.max(0, Math.round(performance.now() - started));\n\t\t\tresolve({\n\t\t\t\tstdout: Buffer.concat(stdout),\n\t\t\t\tstderr: Buffer.concat(stderr),\n\t\t\t\texitCode,\n\t\t\t\tfailure: failure ?? (exitCode === 0 ? null : \"execution_failed\"),\n\t\t\t\tstartedAt,\n\t\t\t\t// Project the finish instant from the start's wall reference and monotonic elapsed time.\n\t\t\t\tfinishedAt: new Date(Date.parse(startedAt) + durationMs).toISOString(),\n\t\t\t\tdurationMs,\n\t\t\t});\n\t\t});\n\t});\n}\n"]}
|
|
@@ -33,7 +33,7 @@ export interface WorkloadPermitPoolSnapshot {
|
|
|
33
33
|
readonly activeWeight: number;
|
|
34
34
|
readonly queuedCount: number;
|
|
35
35
|
}
|
|
36
|
-
export type WorkloadPermitErrorCode = "queue_overflow" | "timeout" | "aborted" | "over_capacity_weight";
|
|
36
|
+
export type WorkloadPermitErrorCode = "queue_overflow" | "timeout" | "aborted" | "over_capacity_weight" | "invalid_weight";
|
|
37
37
|
export declare class WorkloadPermitError extends Error {
|
|
38
38
|
readonly code: WorkloadPermitErrorCode;
|
|
39
39
|
readonly requestId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-permit-pool.d.ts","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"workload-permit-pool.d.ts","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,uBAAuB,GAChC,gBAAgB,GAChB,SAAS,GACT,SAAS,GACT,sBAAsB,GACtB,gBAAgB,CAAC;AAEpB,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,IAAI,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAK3D;CACD;AAUD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,yBAAyB,GAAG;IACvC,uEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAK;IAE3B,YAAY,OAAO,CAAC,EAAE,yBAAyB,EAI9C;IAED;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,+EAA+E;IAC/E,OAAO,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiC7D;IAED,QAAQ,IAAI,0BAA0B,CAErC;IAED,uEAAsE;IACtE,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,OAAO,CAAC,KAAK;IAmBb,gFAA+E;IAC/E,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,aAAa;CAUrB","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { WorkloadClass } from \"./workload-classifier.ts\";\n\n/**\n * Shared workload permit pool (OMK v0.97.x roadmap §10, M3/PR5).\n *\n * Bounds concurrent heavy/cpu subprocesses independently of tool concurrency\n * (§10.1: 4 concurrent reads != 4 concurrent `npm test` processes). One pool\n * instance is shared by a session and, later, its child subagents (§14.1) —\n * a child creating its own pool would oversubscribe the host.\n *\n * §10.3 rules implemented here: strict FIFO (§10.4), abort- and\n * timeout-aware waiting, exactly-once release with double-release recorded\n * as a diagnostic no-op, immediate rejection of requests wider than\n * capacity, and a hard queue cap whose overflow surfaces as a structured\n * error code (§15.4 `queue_overflow`). Waiter timers stay ref'd — a permit\n * wait is actively awaited work — and are cleared on settle.\n */\n\nexport interface WorkloadPermitRequest {\n\treadonly requestId: string;\n\treadonly promptRunId: string;\n\treadonly workloadClass: WorkloadClass;\n\treadonly weight: 1 | 2;\n\treadonly signal?: AbortSignal;\n\treadonly timeoutMs?: number;\n}\n\nexport interface WorkloadPermit {\n\treadonly permitId: string;\n\treadonly requestId: string;\n\treadonly acquiredAt: string;\n\trelease(): void;\n}\n\nexport interface WorkloadPermitPoolSnapshot {\n\treadonly capacity: number;\n\treadonly activeWeight: number;\n\treadonly queuedCount: number;\n}\n\nexport type WorkloadPermitErrorCode =\n\t| \"queue_overflow\"\n\t| \"timeout\"\n\t| \"aborted\"\n\t| \"over_capacity_weight\"\n\t| \"invalid_weight\";\n\nexport class WorkloadPermitError extends Error {\n\treadonly code: WorkloadPermitErrorCode;\n\treadonly requestId: string;\n\n\tconstructor(code: WorkloadPermitErrorCode, requestId: string) {\n\t\tsuper(`workload permit ${code} (request ${requestId})`);\n\t\tthis.name = \"WorkloadPermitError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\ninterface Waiter {\n\treadonly request: WorkloadPermitRequest;\n\treadonly resolve: (permit: WorkloadPermit) => void;\n\treadonly reject: (error: WorkloadPermitError) => void;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tabortListener: (() => void) | null;\n}\n\nexport const DEFAULT_PERMIT_QUEUE_CAP = 32;\n\nexport type WorkloadPermitPoolOptions = {\n\t/** Concurrent weight budget; §7.2 heavy caps feed this. Default 2. */\n\tcapacity?: number;\n\t/** §10.3 queue length hard cap. Default 32. */\n\tmaxQueue?: number;\n\t/** Injectable clock for deterministic tests. */\n\tnow?: () => Date;\n};\n\nexport class WorkloadPermitPool {\n\tprivate capacity: number;\n\tprivate readonly maxQueue: number;\n\tprivate readonly now: () => Date;\n\tprivate activeWeight = 0;\n\tprivate readonly queue: Waiter[] = [];\n\tprivate doubleReleases = 0;\n\n\tconstructor(options?: WorkloadPermitPoolOptions) {\n\t\tthis.capacity = sanitizeCapacity(options?.capacity, 2);\n\t\tthis.maxQueue = sanitizeCapacity(options?.maxQueue, DEFAULT_PERMIT_QUEUE_CAP);\n\t\tthis.now = options?.now ?? (() => new Date());\n\t}\n\n\t/**\n\t * Update capacity from a new admission decision. In-flight permits are\n\t * never revoked; a reduction only delays future grants until active\n\t * weight drains below the new capacity.\n\t */\n\tsetCapacity(capacity: number): void {\n\t\tthis.capacity = sanitizeCapacity(capacity, this.capacity);\n\t\tthis.grantWhilePossible();\n\t}\n\n\t/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */\n\tacquire(input: WorkloadPermitRequest): Promise<WorkloadPermit> {\n\t\tconst request = { ...input };\n\t\tif (request.weight !== 1 && request.weight !== 2) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"invalid_weight\", request.requestId));\n\t\t}\n\t\tif (request.weight > this.capacity) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"over_capacity_weight\", request.requestId));\n\t\t}\n\t\tif (request.signal?.aborted) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"aborted\", request.requestId));\n\t\t}\n\t\tif (this.queue.length === 0 && this.activeWeight + request.weight <= this.capacity) {\n\t\t\treturn Promise.resolve(this.grant(request));\n\t\t}\n\t\tif (this.queue.length >= this.maxQueue) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"queue_overflow\", request.requestId));\n\t\t}\n\t\treturn new Promise<WorkloadPermit>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { request, resolve, reject, timer: null, abortListener: null };\n\t\t\tif (typeof request.timeoutMs === \"number\" && Number.isFinite(request.timeoutMs) && request.timeoutMs > 0) {\n\t\t\t\twaiter.timer = setTimeout(() => {\n\t\t\t\t\tthis.evict(waiter, \"timeout\");\n\t\t\t\t}, request.timeoutMs);\n\t\t\t}\n\t\t\tif (request.signal) {\n\t\t\t\tconst signal = request.signal;\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tthis.evict(waiter, \"aborted\");\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.queue.push(waiter);\n\t\t});\n\t}\n\n\tsnapshot(): WorkloadPermitPoolSnapshot {\n\t\treturn { capacity: this.capacity, activeWeight: this.activeWeight, queuedCount: this.queue.length };\n\t}\n\n\t/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */\n\tget doubleReleaseCount(): number {\n\t\treturn this.doubleReleases;\n\t}\n\n\tprivate grant(request: WorkloadPermitRequest): WorkloadPermit {\n\t\tconst acquiredAt = this.now().toISOString();\n\t\tconst permitId = `permit-${randomUUID()}`;\n\t\tthis.activeWeight += request.weight;\n\t\tlet released = false;\n\t\tconst release = (): void => {\n\t\t\t// §10.3 exactly-once: a late or repeated settlement must not return\n\t\t\t// weight it no longer owns.\n\t\t\tif (released) {\n\t\t\t\tthis.doubleReleases += 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis.activeWeight -= request.weight;\n\t\t\tthis.grantWhilePossible();\n\t\t};\n\t\treturn { permitId, requestId: request.requestId, acquiredAt, release };\n\t}\n\n\t/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */\n\tprivate grantWhilePossible(): void {\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst head = this.queue[0];\n\t\t\tif (head.request.weight > this.capacity) {\n\t\t\t\t// Capacity shrank below the head's weight: reject rather than\n\t\t\t\t// starving everyone behind it forever.\n\t\t\t\tthis.queue.shift();\n\t\t\t\tthis.settleCleanup(head);\n\t\t\t\thead.reject(new WorkloadPermitError(\"over_capacity_weight\", head.request.requestId));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.activeWeight + head.request.weight > this.capacity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.queue.shift();\n\t\t\tthis.settleCleanup(head);\n\t\t\thead.resolve(this.grant(head.request));\n\t\t}\n\t}\n\n\tprivate evict(waiter: Waiter, code: WorkloadPermitErrorCode): void {\n\t\tconst index = this.queue.indexOf(waiter);\n\t\tif (index === -1) {\n\t\t\treturn; // Already granted or already evicted.\n\t\t}\n\t\tthis.queue.splice(index, 1);\n\t\tthis.settleCleanup(waiter);\n\t\twaiter.reject(new WorkloadPermitError(code, waiter.request.requestId));\n\t\tthis.grantWhilePossible();\n\t}\n\n\tprivate settleCleanup(waiter: Waiter): void {\n\t\tif (waiter.timer !== null) {\n\t\t\tclearTimeout(waiter.timer);\n\t\t\twaiter.timer = null;\n\t\t}\n\t\tif (waiter.abortListener !== null) {\n\t\t\twaiter.request.signal?.removeEventListener(\"abort\", waiter.abortListener);\n\t\t\twaiter.abortListener = null;\n\t\t}\n\t}\n}\n\nfunction sanitizeCapacity(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n"]}
|
|
@@ -34,6 +34,9 @@ export class WorkloadPermitPool {
|
|
|
34
34
|
/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */
|
|
35
35
|
acquire(input) {
|
|
36
36
|
const request = { ...input };
|
|
37
|
+
if (request.weight !== 1 && request.weight !== 2) {
|
|
38
|
+
return Promise.reject(new WorkloadPermitError("invalid_weight", request.requestId));
|
|
39
|
+
}
|
|
37
40
|
if (request.weight > this.capacity) {
|
|
38
41
|
return Promise.reject(new WorkloadPermitError("over_capacity_weight", request.requestId));
|
|
39
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-permit-pool.js","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { WorkloadClass } from \"./workload-classifier.ts\";\n\n/**\n * Shared workload permit pool (OMK v0.97.x roadmap §10, M3/PR5).\n *\n * Bounds concurrent heavy/cpu subprocesses independently of tool concurrency\n * (§10.1: 4 concurrent reads != 4 concurrent `npm test` processes). One pool\n * instance is shared by a session and, later, its child subagents (§14.1) —\n * a child creating its own pool would oversubscribe the host.\n *\n * §10.3 rules implemented here: strict FIFO (§10.4), abort- and\n * timeout-aware waiting, exactly-once release with double-release recorded\n * as a diagnostic no-op, immediate rejection of requests wider than\n * capacity, and a hard queue cap whose overflow surfaces as a structured\n * error code (§15.4 `queue_overflow`). Waiter timers stay ref'd — a permit\n * wait is actively awaited work — and are cleared on settle.\n */\n\nexport interface WorkloadPermitRequest {\n\treadonly requestId: string;\n\treadonly promptRunId: string;\n\treadonly workloadClass: WorkloadClass;\n\treadonly weight: 1 | 2;\n\treadonly signal?: AbortSignal;\n\treadonly timeoutMs?: number;\n}\n\nexport interface WorkloadPermit {\n\treadonly permitId: string;\n\treadonly requestId: string;\n\treadonly acquiredAt: string;\n\trelease(): void;\n}\n\nexport interface WorkloadPermitPoolSnapshot {\n\treadonly capacity: number;\n\treadonly activeWeight: number;\n\treadonly queuedCount: number;\n}\n\nexport type WorkloadPermitErrorCode = \"queue_overflow\" | \"timeout\" | \"aborted\" | \"over_capacity_weight\";\n\nexport class WorkloadPermitError extends Error {\n\treadonly code: WorkloadPermitErrorCode;\n\treadonly requestId: string;\n\n\tconstructor(code: WorkloadPermitErrorCode, requestId: string) {\n\t\tsuper(`workload permit ${code} (request ${requestId})`);\n\t\tthis.name = \"WorkloadPermitError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\ninterface Waiter {\n\treadonly request: WorkloadPermitRequest;\n\treadonly resolve: (permit: WorkloadPermit) => void;\n\treadonly reject: (error: WorkloadPermitError) => void;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tabortListener: (() => void) | null;\n}\n\nexport const DEFAULT_PERMIT_QUEUE_CAP = 32;\n\nexport type WorkloadPermitPoolOptions = {\n\t/** Concurrent weight budget; §7.2 heavy caps feed this. Default 2. */\n\tcapacity?: number;\n\t/** §10.3 queue length hard cap. Default 32. */\n\tmaxQueue?: number;\n\t/** Injectable clock for deterministic tests. */\n\tnow?: () => Date;\n};\n\nexport class WorkloadPermitPool {\n\tprivate capacity: number;\n\tprivate readonly maxQueue: number;\n\tprivate readonly now: () => Date;\n\tprivate activeWeight = 0;\n\tprivate readonly queue: Waiter[] = [];\n\tprivate doubleReleases = 0;\n\n\tconstructor(options?: WorkloadPermitPoolOptions) {\n\t\tthis.capacity = sanitizeCapacity(options?.capacity, 2);\n\t\tthis.maxQueue = sanitizeCapacity(options?.maxQueue, DEFAULT_PERMIT_QUEUE_CAP);\n\t\tthis.now = options?.now ?? (() => new Date());\n\t}\n\n\t/**\n\t * Update capacity from a new admission decision. In-flight permits are\n\t * never revoked; a reduction only delays future grants until active\n\t * weight drains below the new capacity.\n\t */\n\tsetCapacity(capacity: number): void {\n\t\tthis.capacity = sanitizeCapacity(capacity, this.capacity);\n\t\tthis.grantWhilePossible();\n\t}\n\n\t/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */\n\tacquire(input: WorkloadPermitRequest): Promise<WorkloadPermit> {\n\t\tconst request = { ...input };\n\t\tif (request.weight > this.capacity) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"over_capacity_weight\", request.requestId));\n\t\t}\n\t\tif (request.signal?.aborted) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"aborted\", request.requestId));\n\t\t}\n\t\tif (this.queue.length === 0 && this.activeWeight + request.weight <= this.capacity) {\n\t\t\treturn Promise.resolve(this.grant(request));\n\t\t}\n\t\tif (this.queue.length >= this.maxQueue) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"queue_overflow\", request.requestId));\n\t\t}\n\t\treturn new Promise<WorkloadPermit>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { request, resolve, reject, timer: null, abortListener: null };\n\t\t\tif (typeof request.timeoutMs === \"number\" && Number.isFinite(request.timeoutMs) && request.timeoutMs > 0) {\n\t\t\t\twaiter.timer = setTimeout(() => {\n\t\t\t\t\tthis.evict(waiter, \"timeout\");\n\t\t\t\t}, request.timeoutMs);\n\t\t\t}\n\t\t\tif (request.signal) {\n\t\t\t\tconst signal = request.signal;\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tthis.evict(waiter, \"aborted\");\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.queue.push(waiter);\n\t\t});\n\t}\n\n\tsnapshot(): WorkloadPermitPoolSnapshot {\n\t\treturn { capacity: this.capacity, activeWeight: this.activeWeight, queuedCount: this.queue.length };\n\t}\n\n\t/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */\n\tget doubleReleaseCount(): number {\n\t\treturn this.doubleReleases;\n\t}\n\n\tprivate grant(request: WorkloadPermitRequest): WorkloadPermit {\n\t\tconst acquiredAt = this.now().toISOString();\n\t\tconst permitId = `permit-${randomUUID()}`;\n\t\tthis.activeWeight += request.weight;\n\t\tlet released = false;\n\t\tconst release = (): void => {\n\t\t\t// §10.3 exactly-once: a late or repeated settlement must not return\n\t\t\t// weight it no longer owns.\n\t\t\tif (released) {\n\t\t\t\tthis.doubleReleases += 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis.activeWeight -= request.weight;\n\t\t\tthis.grantWhilePossible();\n\t\t};\n\t\treturn { permitId, requestId: request.requestId, acquiredAt, release };\n\t}\n\n\t/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */\n\tprivate grantWhilePossible(): void {\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst head = this.queue[0];\n\t\t\tif (head.request.weight > this.capacity) {\n\t\t\t\t// Capacity shrank below the head's weight: reject rather than\n\t\t\t\t// starving everyone behind it forever.\n\t\t\t\tthis.queue.shift();\n\t\t\t\tthis.settleCleanup(head);\n\t\t\t\thead.reject(new WorkloadPermitError(\"over_capacity_weight\", head.request.requestId));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.activeWeight + head.request.weight > this.capacity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.queue.shift();\n\t\t\tthis.settleCleanup(head);\n\t\t\thead.resolve(this.grant(head.request));\n\t\t}\n\t}\n\n\tprivate evict(waiter: Waiter, code: WorkloadPermitErrorCode): void {\n\t\tconst index = this.queue.indexOf(waiter);\n\t\tif (index === -1) {\n\t\t\treturn; // Already granted or already evicted.\n\t\t}\n\t\tthis.queue.splice(index, 1);\n\t\tthis.settleCleanup(waiter);\n\t\twaiter.reject(new WorkloadPermitError(code, waiter.request.requestId));\n\t\tthis.grantWhilePossible();\n\t}\n\n\tprivate settleCleanup(waiter: Waiter): void {\n\t\tif (waiter.timer !== null) {\n\t\t\tclearTimeout(waiter.timer);\n\t\t\twaiter.timer = null;\n\t\t}\n\t\tif (waiter.abortListener !== null) {\n\t\t\twaiter.request.signal?.removeEventListener(\"abort\", waiter.abortListener);\n\t\t\twaiter.abortListener = null;\n\t\t}\n\t}\n}\n\nfunction sanitizeCapacity(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workload-permit-pool.js","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAgDzC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACpC,IAAI,CAA0B;IAC9B,SAAS,CAAS;IAE3B,YAAY,IAA6B,EAAE,SAAiB,EAAE;QAC7D,KAAK,CAAC,mBAAmB,IAAI,aAAa,SAAS,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAAA,CAC3B;CACD;AAUD,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAW3C,MAAM,OAAO,kBAAkB;IACtB,QAAQ,CAAS;IACR,QAAQ,CAAS;IACjB,GAAG,CAAa;IACzB,YAAY,GAAG,CAAC,CAAC;IACR,KAAK,GAAa,EAAE,CAAC;IAC9B,cAAc,GAAG,CAAC,CAAC;IAE3B,YAAY,OAAmC,EAAE;QAChD,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,wBAAwB,CAAC,CAAC;QAC9E,IAAI,CAAC,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAAA,CAC9C;IAED;;;;OAIG;IACH,WAAW,CAAC,QAAgB,EAAQ;QACnC,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAAA,CAC1B;IAED,+EAA+E;IAC/E,OAAO,CAAC,KAA4B,EAA2B;QAC9D,MAAM,OAAO,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,sBAAsB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;YACvD,MAAM,MAAM,GAAW,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;YACtF,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;gBAC1G,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;oBAC/B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;gBAAA,CAC9B,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACvB,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBAC9B,MAAM,CAAC,aAAa,GAAG,GAAG,EAAE,CAAC;oBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;gBAAA,CAC9B,CAAC;gBACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAAA,CACxB,CAAC,CAAC;IAAA,CACH;IAED,QAAQ,GAA+B;QACtC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IAAA,CACpG;IAED,uEAAsE;IACtE,IAAI,kBAAkB,GAAW;QAChC,OAAO,IAAI,CAAC,cAAc,CAAC;IAAA,CAC3B;IAEO,KAAK,CAAC,OAA8B,EAAkB;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,UAAU,UAAU,EAAE,EAAE,CAAC;QAC1C,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;QACpC,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC;YAC3B,qEAAoE;YACpE,4BAA4B;YAC5B,IAAI,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;gBACzB,OAAO;YACR,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAAA,CAC1B,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IAAA,CACvE;IAED,gFAA+E;IACvE,kBAAkB,GAAS;QAClC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACzC,8DAA8D;gBAC9D,uCAAuC;gBACvC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBACzB,IAAI,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;gBACrF,SAAS;YACV,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC7D,OAAO;YACR,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC;IAAA,CACD;IAEO,KAAK,CAAC,MAAc,EAAE,IAA6B,EAAQ;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,CAAC,sCAAsC;QAC/C,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAAA,CAC1B;IAEO,aAAa,CAAC,MAAc,EAAQ;QAC3C,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YAC3B,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,IAAI,MAAM,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YACnC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;YAC1E,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;QAC7B,CAAC;IAAA,CACD;CACD;AAED,SAAS,gBAAgB,CAAC,KAAyB,EAAE,QAAgB,EAAU;IAC9E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAAA,CACzB","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { WorkloadClass } from \"./workload-classifier.ts\";\n\n/**\n * Shared workload permit pool (OMK v0.97.x roadmap §10, M3/PR5).\n *\n * Bounds concurrent heavy/cpu subprocesses independently of tool concurrency\n * (§10.1: 4 concurrent reads != 4 concurrent `npm test` processes). One pool\n * instance is shared by a session and, later, its child subagents (§14.1) —\n * a child creating its own pool would oversubscribe the host.\n *\n * §10.3 rules implemented here: strict FIFO (§10.4), abort- and\n * timeout-aware waiting, exactly-once release with double-release recorded\n * as a diagnostic no-op, immediate rejection of requests wider than\n * capacity, and a hard queue cap whose overflow surfaces as a structured\n * error code (§15.4 `queue_overflow`). Waiter timers stay ref'd — a permit\n * wait is actively awaited work — and are cleared on settle.\n */\n\nexport interface WorkloadPermitRequest {\n\treadonly requestId: string;\n\treadonly promptRunId: string;\n\treadonly workloadClass: WorkloadClass;\n\treadonly weight: 1 | 2;\n\treadonly signal?: AbortSignal;\n\treadonly timeoutMs?: number;\n}\n\nexport interface WorkloadPermit {\n\treadonly permitId: string;\n\treadonly requestId: string;\n\treadonly acquiredAt: string;\n\trelease(): void;\n}\n\nexport interface WorkloadPermitPoolSnapshot {\n\treadonly capacity: number;\n\treadonly activeWeight: number;\n\treadonly queuedCount: number;\n}\n\nexport type WorkloadPermitErrorCode =\n\t| \"queue_overflow\"\n\t| \"timeout\"\n\t| \"aborted\"\n\t| \"over_capacity_weight\"\n\t| \"invalid_weight\";\n\nexport class WorkloadPermitError extends Error {\n\treadonly code: WorkloadPermitErrorCode;\n\treadonly requestId: string;\n\n\tconstructor(code: WorkloadPermitErrorCode, requestId: string) {\n\t\tsuper(`workload permit ${code} (request ${requestId})`);\n\t\tthis.name = \"WorkloadPermitError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\ninterface Waiter {\n\treadonly request: WorkloadPermitRequest;\n\treadonly resolve: (permit: WorkloadPermit) => void;\n\treadonly reject: (error: WorkloadPermitError) => void;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tabortListener: (() => void) | null;\n}\n\nexport const DEFAULT_PERMIT_QUEUE_CAP = 32;\n\nexport type WorkloadPermitPoolOptions = {\n\t/** Concurrent weight budget; §7.2 heavy caps feed this. Default 2. */\n\tcapacity?: number;\n\t/** §10.3 queue length hard cap. Default 32. */\n\tmaxQueue?: number;\n\t/** Injectable clock for deterministic tests. */\n\tnow?: () => Date;\n};\n\nexport class WorkloadPermitPool {\n\tprivate capacity: number;\n\tprivate readonly maxQueue: number;\n\tprivate readonly now: () => Date;\n\tprivate activeWeight = 0;\n\tprivate readonly queue: Waiter[] = [];\n\tprivate doubleReleases = 0;\n\n\tconstructor(options?: WorkloadPermitPoolOptions) {\n\t\tthis.capacity = sanitizeCapacity(options?.capacity, 2);\n\t\tthis.maxQueue = sanitizeCapacity(options?.maxQueue, DEFAULT_PERMIT_QUEUE_CAP);\n\t\tthis.now = options?.now ?? (() => new Date());\n\t}\n\n\t/**\n\t * Update capacity from a new admission decision. In-flight permits are\n\t * never revoked; a reduction only delays future grants until active\n\t * weight drains below the new capacity.\n\t */\n\tsetCapacity(capacity: number): void {\n\t\tthis.capacity = sanitizeCapacity(capacity, this.capacity);\n\t\tthis.grantWhilePossible();\n\t}\n\n\t/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */\n\tacquire(input: WorkloadPermitRequest): Promise<WorkloadPermit> {\n\t\tconst request = { ...input };\n\t\tif (request.weight !== 1 && request.weight !== 2) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"invalid_weight\", request.requestId));\n\t\t}\n\t\tif (request.weight > this.capacity) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"over_capacity_weight\", request.requestId));\n\t\t}\n\t\tif (request.signal?.aborted) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"aborted\", request.requestId));\n\t\t}\n\t\tif (this.queue.length === 0 && this.activeWeight + request.weight <= this.capacity) {\n\t\t\treturn Promise.resolve(this.grant(request));\n\t\t}\n\t\tif (this.queue.length >= this.maxQueue) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"queue_overflow\", request.requestId));\n\t\t}\n\t\treturn new Promise<WorkloadPermit>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { request, resolve, reject, timer: null, abortListener: null };\n\t\t\tif (typeof request.timeoutMs === \"number\" && Number.isFinite(request.timeoutMs) && request.timeoutMs > 0) {\n\t\t\t\twaiter.timer = setTimeout(() => {\n\t\t\t\t\tthis.evict(waiter, \"timeout\");\n\t\t\t\t}, request.timeoutMs);\n\t\t\t}\n\t\t\tif (request.signal) {\n\t\t\t\tconst signal = request.signal;\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tthis.evict(waiter, \"aborted\");\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.queue.push(waiter);\n\t\t});\n\t}\n\n\tsnapshot(): WorkloadPermitPoolSnapshot {\n\t\treturn { capacity: this.capacity, activeWeight: this.activeWeight, queuedCount: this.queue.length };\n\t}\n\n\t/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */\n\tget doubleReleaseCount(): number {\n\t\treturn this.doubleReleases;\n\t}\n\n\tprivate grant(request: WorkloadPermitRequest): WorkloadPermit {\n\t\tconst acquiredAt = this.now().toISOString();\n\t\tconst permitId = `permit-${randomUUID()}`;\n\t\tthis.activeWeight += request.weight;\n\t\tlet released = false;\n\t\tconst release = (): void => {\n\t\t\t// §10.3 exactly-once: a late or repeated settlement must not return\n\t\t\t// weight it no longer owns.\n\t\t\tif (released) {\n\t\t\t\tthis.doubleReleases += 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis.activeWeight -= request.weight;\n\t\t\tthis.grantWhilePossible();\n\t\t};\n\t\treturn { permitId, requestId: request.requestId, acquiredAt, release };\n\t}\n\n\t/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */\n\tprivate grantWhilePossible(): void {\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst head = this.queue[0];\n\t\t\tif (head.request.weight > this.capacity) {\n\t\t\t\t// Capacity shrank below the head's weight: reject rather than\n\t\t\t\t// starving everyone behind it forever.\n\t\t\t\tthis.queue.shift();\n\t\t\t\tthis.settleCleanup(head);\n\t\t\t\thead.reject(new WorkloadPermitError(\"over_capacity_weight\", head.request.requestId));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.activeWeight + head.request.weight > this.capacity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.queue.shift();\n\t\t\tthis.settleCleanup(head);\n\t\t\thead.resolve(this.grant(head.request));\n\t\t}\n\t}\n\n\tprivate evict(waiter: Waiter, code: WorkloadPermitErrorCode): void {\n\t\tconst index = this.queue.indexOf(waiter);\n\t\tif (index === -1) {\n\t\t\treturn; // Already granted or already evicted.\n\t\t}\n\t\tthis.queue.splice(index, 1);\n\t\tthis.settleCleanup(waiter);\n\t\twaiter.reject(new WorkloadPermitError(code, waiter.request.requestId));\n\t\tthis.grantWhilePossible();\n\t}\n\n\tprivate settleCleanup(waiter: Waiter): void {\n\t\tif (waiter.timer !== null) {\n\t\t\tclearTimeout(waiter.timer);\n\t\t\twaiter.timer = null;\n\t\t}\n\t\tif (waiter.abortListener !== null) {\n\t\t\twaiter.request.signal?.removeEventListener(\"abort\", waiter.abortListener);\n\t\t\twaiter.abortListener = null;\n\t\t}\n\t}\n}\n\nfunction sanitizeCapacity(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ExecutionAttempt, type StrictEvidenceBinding, type StrictEvidenceCompletion, type TaskSpec, type WaiverRecord } from "omk-protocol";
|
|
2
|
+
import type { EvidenceReceipt } from "../types/evidence.ts";
|
|
3
|
+
export interface StrictEvidenceApprovalScope {
|
|
4
|
+
readonly taskSpec: TaskSpec;
|
|
5
|
+
readonly attempt: ExecutionAttempt;
|
|
6
|
+
readonly binding: StrictEvidenceBinding;
|
|
7
|
+
readonly requiredCheckIds: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface StrictEvidenceAdmission {
|
|
10
|
+
readonly entries: readonly {
|
|
11
|
+
readonly receipt: EvidenceReceipt;
|
|
12
|
+
readonly completion: StrictEvidenceCompletion;
|
|
13
|
+
}[];
|
|
14
|
+
readonly pendingExecutionIds: readonly string[];
|
|
15
|
+
readonly waivers?: readonly WaiverRecord[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Trusted host port, not a worker/JSON approval field. The host must authenticate origins,
|
|
19
|
+
* bind exact receipt cores to executions and this scope, allocate sequences, and return a
|
|
20
|
+
* complete atomic snapshot including all open producers. A checksum alone is insufficient.
|
|
21
|
+
* null means admission unavailable/denied. Exceptions propagate; there is no legacy fallback.
|
|
22
|
+
*/
|
|
23
|
+
export type StrictEvidenceAdmissionHost = (scope: StrictEvidenceApprovalScope) => StrictEvidenceAdmission | null;
|
|
24
|
+
/**
|
|
25
|
+
* Opt-in library adapter. Pin BEFORE verification; changing a round or check set requires
|
|
26
|
+
* a new scope and renewed host approval. This is not wired into CLI/TUI or verified-run.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createStrictEvidenceApprovalAdapter(scope: StrictEvidenceApprovalScope, admit: StrictEvidenceAdmissionHost): Readonly<{
|
|
29
|
+
evaluate(request: {
|
|
30
|
+
readonly evaluationId: string;
|
|
31
|
+
readonly evaluatedAt: string;
|
|
32
|
+
}): import("omk-protocol").EvaluationResult;
|
|
33
|
+
}>;
|
|
34
|
+
//# sourceMappingURL=strict-evidence-approval-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strict-evidence-approval-adapter.d.ts","sourceRoot":"","sources":["../../src/guardrails/strict-evidence-approval-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,gBAAgB,EAKrB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAC1B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;QAClC,QAAQ,CAAC,UAAU,EAAE,wBAAwB,CAAC;KAC9C,EAAE,CAAC;IACJ,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,2BAA2B,KAAK,uBAAuB,GAAG,IAAI,CAAC;AAUjH;;;GAGG;AACH,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,2BAA2B,EAClC,KAAK,EAAE,2BAA2B;;;;;GA0DlC","sourcesContent":["import {\n\ttype ExecutionAttempt,\n\tevaluateTask,\n\tparseExecutionAttempt,\n\tparseStrictEvidenceBinding,\n\tparseTaskSpec,\n\ttype StrictEvidenceBinding,\n\ttype StrictEvidenceCompletion,\n\ttype TaskSpec,\n\ttype WaiverRecord,\n} from \"omk-protocol\";\nimport type { EvidenceReceipt } from \"../types/evidence.ts\";\nimport { evidenceReceiptToObservation } from \"./evidence-protocol.ts\";\nimport { validateEvidenceReceipt } from \"./evidence-receipt.ts\";\n\nexport interface StrictEvidenceApprovalScope {\n\treadonly taskSpec: TaskSpec;\n\treadonly attempt: ExecutionAttempt;\n\treadonly binding: StrictEvidenceBinding;\n\treadonly requiredCheckIds: readonly string[];\n}\n\nexport interface StrictEvidenceAdmission {\n\treadonly entries: readonly {\n\t\treadonly receipt: EvidenceReceipt;\n\t\treadonly completion: StrictEvidenceCompletion;\n\t}[];\n\treadonly pendingExecutionIds: readonly string[];\n\treadonly waivers?: readonly WaiverRecord[];\n}\n\n/**\n * Trusted host port, not a worker/JSON approval field. The host must authenticate origins,\n * bind exact receipt cores to executions and this scope, allocate sequences, and return a\n * complete atomic snapshot including all open producers. A checksum alone is insufficient.\n * null means admission unavailable/denied. Exceptions propagate; there is no legacy fallback.\n */\nexport type StrictEvidenceAdmissionHost = (scope: StrictEvidenceApprovalScope) => StrictEvidenceAdmission | null;\n\nfunction freeze<T>(value: T): T {\n\tif (typeof value === \"object\" && value !== null) {\n\t\tfor (const child of Object.values(value)) freeze(child);\n\t\tObject.freeze(value);\n\t}\n\treturn value;\n}\n\n/**\n * Opt-in library adapter. Pin BEFORE verification; changing a round or check set requires\n * a new scope and renewed host approval. This is not wired into CLI/TUI or verified-run.\n */\nexport function createStrictEvidenceApprovalAdapter(\n\tscope: StrictEvidenceApprovalScope,\n\tadmit: StrictEvidenceAdmissionHost,\n) {\n\tif (typeof admit !== \"function\") throw new Error(\"Strict evidence requires a host admission callback\");\n\tconst pinned = freeze(structuredClone(scope));\n\tparseTaskSpec(pinned.taskSpec);\n\tparseExecutionAttempt(pinned.attempt);\n\tparseStrictEvidenceBinding(pinned.binding);\n\tif (\n\t\tpinned.requiredCheckIds.length === 0 ||\n\t\tnew Set(pinned.requiredCheckIds).size !== pinned.requiredCheckIds.length ||\n\t\tpinned.requiredCheckIds.some((id) => typeof id !== \"string\" || id.trim().length === 0)\n\t) {\n\t\tthrow new Error(\"Strict evidence requires a nonempty unique pinned check set\");\n\t}\n\tif (\n\t\tpinned.taskSpec.taskId !== pinned.binding.taskId ||\n\t\tpinned.attempt.taskId !== pinned.binding.taskId ||\n\t\tpinned.attempt.candidateHash !== pinned.binding.candidateHash\n\t)\n\t\tthrow new Error(\"Strict evidence scope mismatch\");\n\treturn Object.freeze({\n\t\tevaluate(request: { readonly evaluationId: string; readonly evaluatedAt: string }) {\n\t\t\tconst admission = admit(pinned);\n\t\t\tif (admission === null) throw new Error(\"Strict evidence host admission denied\");\n\t\t\tconst snapshot = freeze(structuredClone(admission));\n\t\t\tconst observations = snapshot.entries.map(({ receipt, completion }) => {\n\t\t\t\tconst validated = validateEvidenceReceipt(receipt);\n\t\t\t\tconst observation = evidenceReceiptToObservation(validated, pinned.attempt.attemptId);\n\t\t\t\tif (completion.observationId !== observation.observationId)\n\t\t\t\t\tthrow new Error(\"Strict receipt identity mismatch\");\n\t\t\t\tif (completion.verdict === \"passed\" && validated.core.status !== \"passed\") {\n\t\t\t\t\tthrow new Error(\"Strict admission cannot promote a failed receipt\");\n\t\t\t\t}\n\t\t\t\tconst candidate = validated.core.workspaceAfter.manifestSha256;\n\t\t\t\tif (\n\t\t\t\t\tcandidate !== completion.binding.candidateHash ||\n\t\t\t\t\tvalidated.core.workspaceBefore.manifestSha256 !== candidate\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"Strict receipt workspace does not match admitted candidate\");\n\t\t\t\t}\n\t\t\t\treturn Object.freeze({ ...observation, facts: Object.freeze({ ...observation.facts, candidate }) });\n\t\t\t});\n\t\t\treturn evaluateTask({\n\t\t\t\t...request,\n\t\t\t\ttaskSpec: pinned.taskSpec,\n\t\t\t\tattempt: pinned.attempt,\n\t\t\t\tobservations,\n\t\t\t\twaivers: snapshot.waivers,\n\t\t\t\tstrictEvidence: {\n\t\t\t\t\tpolicy: \"omk.strict-evidence.v1\",\n\t\t\t\t\tbinding: pinned.binding,\n\t\t\t\t\trequiredCheckIds: pinned.requiredCheckIds,\n\t\t\t\t\tpendingExecutionIds: snapshot.pendingExecutionIds,\n\t\t\t\t\tresults: snapshot.entries.map(({ completion }) => completion),\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { evaluateTask, parseExecutionAttempt, parseStrictEvidenceBinding, parseTaskSpec, } from "omk-protocol";
|
|
2
|
+
import { evidenceReceiptToObservation } from "./evidence-protocol.js";
|
|
3
|
+
import { validateEvidenceReceipt } from "./evidence-receipt.js";
|
|
4
|
+
function freeze(value) {
|
|
5
|
+
if (typeof value === "object" && value !== null) {
|
|
6
|
+
for (const child of Object.values(value))
|
|
7
|
+
freeze(child);
|
|
8
|
+
Object.freeze(value);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Opt-in library adapter. Pin BEFORE verification; changing a round or check set requires
|
|
14
|
+
* a new scope and renewed host approval. This is not wired into CLI/TUI or verified-run.
|
|
15
|
+
*/
|
|
16
|
+
export function createStrictEvidenceApprovalAdapter(scope, admit) {
|
|
17
|
+
if (typeof admit !== "function")
|
|
18
|
+
throw new Error("Strict evidence requires a host admission callback");
|
|
19
|
+
const pinned = freeze(structuredClone(scope));
|
|
20
|
+
parseTaskSpec(pinned.taskSpec);
|
|
21
|
+
parseExecutionAttempt(pinned.attempt);
|
|
22
|
+
parseStrictEvidenceBinding(pinned.binding);
|
|
23
|
+
if (pinned.requiredCheckIds.length === 0 ||
|
|
24
|
+
new Set(pinned.requiredCheckIds).size !== pinned.requiredCheckIds.length ||
|
|
25
|
+
pinned.requiredCheckIds.some((id) => typeof id !== "string" || id.trim().length === 0)) {
|
|
26
|
+
throw new Error("Strict evidence requires a nonempty unique pinned check set");
|
|
27
|
+
}
|
|
28
|
+
if (pinned.taskSpec.taskId !== pinned.binding.taskId ||
|
|
29
|
+
pinned.attempt.taskId !== pinned.binding.taskId ||
|
|
30
|
+
pinned.attempt.candidateHash !== pinned.binding.candidateHash)
|
|
31
|
+
throw new Error("Strict evidence scope mismatch");
|
|
32
|
+
return Object.freeze({
|
|
33
|
+
evaluate(request) {
|
|
34
|
+
const admission = admit(pinned);
|
|
35
|
+
if (admission === null)
|
|
36
|
+
throw new Error("Strict evidence host admission denied");
|
|
37
|
+
const snapshot = freeze(structuredClone(admission));
|
|
38
|
+
const observations = snapshot.entries.map(({ receipt, completion }) => {
|
|
39
|
+
const validated = validateEvidenceReceipt(receipt);
|
|
40
|
+
const observation = evidenceReceiptToObservation(validated, pinned.attempt.attemptId);
|
|
41
|
+
if (completion.observationId !== observation.observationId)
|
|
42
|
+
throw new Error("Strict receipt identity mismatch");
|
|
43
|
+
if (completion.verdict === "passed" && validated.core.status !== "passed") {
|
|
44
|
+
throw new Error("Strict admission cannot promote a failed receipt");
|
|
45
|
+
}
|
|
46
|
+
const candidate = validated.core.workspaceAfter.manifestSha256;
|
|
47
|
+
if (candidate !== completion.binding.candidateHash ||
|
|
48
|
+
validated.core.workspaceBefore.manifestSha256 !== candidate) {
|
|
49
|
+
throw new Error("Strict receipt workspace does not match admitted candidate");
|
|
50
|
+
}
|
|
51
|
+
return Object.freeze({ ...observation, facts: Object.freeze({ ...observation.facts, candidate }) });
|
|
52
|
+
});
|
|
53
|
+
return evaluateTask({
|
|
54
|
+
...request,
|
|
55
|
+
taskSpec: pinned.taskSpec,
|
|
56
|
+
attempt: pinned.attempt,
|
|
57
|
+
observations,
|
|
58
|
+
waivers: snapshot.waivers,
|
|
59
|
+
strictEvidence: {
|
|
60
|
+
policy: "omk.strict-evidence.v1",
|
|
61
|
+
binding: pinned.binding,
|
|
62
|
+
requiredCheckIds: pinned.requiredCheckIds,
|
|
63
|
+
pendingExecutionIds: snapshot.pendingExecutionIds,
|
|
64
|
+
results: snapshot.entries.map(({ completion }) => completion),
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=strict-evidence-approval-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strict-evidence-approval-adapter.js","sourceRoot":"","sources":["../../src/guardrails/strict-evidence-approval-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ExecutionAttempt,\n\tevaluateTask,\n\tparseExecutionAttempt,\n\tparseStrictEvidenceBinding,\n\tparseTaskSpec,\n\ttype StrictEvidenceBinding,\n\ttype StrictEvidenceCompletion,\n\ttype TaskSpec,\n\ttype WaiverRecord,\n} from \"omk-protocol\";\nimport type { EvidenceReceipt } from \"../types/evidence.ts\";\nimport { evidenceReceiptToObservation } from \"./evidence-protocol.ts\";\nimport { validateEvidenceReceipt } from \"./evidence-receipt.ts\";\n\nexport interface StrictEvidenceApprovalScope {\n\treadonly taskSpec: TaskSpec;\n\treadonly attempt: ExecutionAttempt;\n\treadonly binding: StrictEvidenceBinding;\n\treadonly requiredCheckIds: readonly string[];\n}\n\nexport interface StrictEvidenceAdmission {\n\treadonly entries: readonly {\n\t\treadonly receipt: EvidenceReceipt;\n\t\treadonly completion: StrictEvidenceCompletion;\n\t}[];\n\treadonly pendingExecutionIds: readonly string[];\n\treadonly waivers?: readonly WaiverRecord[];\n}\n\n/**\n * Trusted host port, not a worker/JSON approval field. The host must authenticate origins,\n * bind exact receipt cores to executions and this scope, allocate sequences, and return a\n * complete atomic snapshot including all open producers. A checksum alone is insufficient.\n * null means admission unavailable/denied. Exceptions propagate; there is no legacy fallback.\n */\nexport type StrictEvidenceAdmissionHost = (scope: StrictEvidenceApprovalScope) => StrictEvidenceAdmission | null;\n\nfunction freeze<T>(value: T): T {\n\tif (typeof value === \"object\" && value !== null) {\n\t\tfor (const child of Object.values(value)) freeze(child);\n\t\tObject.freeze(value);\n\t}\n\treturn value;\n}\n\n/**\n * Opt-in library adapter. Pin BEFORE verification; changing a round or check set requires\n * a new scope and renewed host approval. This is not wired into CLI/TUI or verified-run.\n */\nexport function createStrictEvidenceApprovalAdapter(\n\tscope: StrictEvidenceApprovalScope,\n\tadmit: StrictEvidenceAdmissionHost,\n) {\n\tif (typeof admit !== \"function\") throw new Error(\"Strict evidence requires a host admission callback\");\n\tconst pinned = freeze(structuredClone(scope));\n\tparseTaskSpec(pinned.taskSpec);\n\tparseExecutionAttempt(pinned.attempt);\n\tparseStrictEvidenceBinding(pinned.binding);\n\tif (\n\t\tpinned.requiredCheckIds.length === 0 ||\n\t\tnew Set(pinned.requiredCheckIds).size !== pinned.requiredCheckIds.length ||\n\t\tpinned.requiredCheckIds.some((id) => typeof id !== \"string\" || id.trim().length === 0)\n\t) {\n\t\tthrow new Error(\"Strict evidence requires a nonempty unique pinned check set\");\n\t}\n\tif (\n\t\tpinned.taskSpec.taskId !== pinned.binding.taskId ||\n\t\tpinned.attempt.taskId !== pinned.binding.taskId ||\n\t\tpinned.attempt.candidateHash !== pinned.binding.candidateHash\n\t)\n\t\tthrow new Error(\"Strict evidence scope mismatch\");\n\treturn Object.freeze({\n\t\tevaluate(request: { readonly evaluationId: string; readonly evaluatedAt: string }) {\n\t\t\tconst admission = admit(pinned);\n\t\t\tif (admission === null) throw new Error(\"Strict evidence host admission denied\");\n\t\t\tconst snapshot = freeze(structuredClone(admission));\n\t\t\tconst observations = snapshot.entries.map(({ receipt, completion }) => {\n\t\t\t\tconst validated = validateEvidenceReceipt(receipt);\n\t\t\t\tconst observation = evidenceReceiptToObservation(validated, pinned.attempt.attemptId);\n\t\t\t\tif (completion.observationId !== observation.observationId)\n\t\t\t\t\tthrow new Error(\"Strict receipt identity mismatch\");\n\t\t\t\tif (completion.verdict === \"passed\" && validated.core.status !== \"passed\") {\n\t\t\t\t\tthrow new Error(\"Strict admission cannot promote a failed receipt\");\n\t\t\t\t}\n\t\t\t\tconst candidate = validated.core.workspaceAfter.manifestSha256;\n\t\t\t\tif (\n\t\t\t\t\tcandidate !== completion.binding.candidateHash ||\n\t\t\t\t\tvalidated.core.workspaceBefore.manifestSha256 !== candidate\n\t\t\t\t) {\n\t\t\t\t\tthrow new Error(\"Strict receipt workspace does not match admitted candidate\");\n\t\t\t\t}\n\t\t\t\treturn Object.freeze({ ...observation, facts: Object.freeze({ ...observation.facts, candidate }) });\n\t\t\t});\n\t\t\treturn evaluateTask({\n\t\t\t\t...request,\n\t\t\t\ttaskSpec: pinned.taskSpec,\n\t\t\t\tattempt: pinned.attempt,\n\t\t\t\tobservations,\n\t\t\t\twaivers: snapshot.waivers,\n\t\t\t\tstrictEvidence: {\n\t\t\t\t\tpolicy: \"omk.strict-evidence.v1\",\n\t\t\t\t\tbinding: pinned.binding,\n\t\t\t\t\trequiredCheckIds: pinned.requiredCheckIds,\n\t\t\t\t\tpendingExecutionIds: snapshot.pendingExecutionIds,\n\t\t\t\t\tresults: snapshot.entries.map(({ completion }) => completion),\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t});\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -48,6 +48,11 @@ export { type BranchSummaryEntry, buildSessionContext, type CompactionEntry, typ
|
|
|
48
48
|
export { type AgentRuntimeSettings, type CompactionSettings, type ImageSettings, type PackageSource, type RetrySettings, SettingsManager, type ToolSchedulerSetting, } from "./core/settings-manager.ts";
|
|
49
49
|
export { formatSkillsForPrompt, type LoadSkillsFromDirOptions, type LoadSkillsResult, loadSkills, loadSkillsFromDir, type Skill, type SkillFrontmatter, } from "./core/skills.ts";
|
|
50
50
|
export { createSyntheticSourceInfo } from "./core/source-info.ts";
|
|
51
|
+
export * from "./coordination/index.ts";
|
|
52
|
+
export * from "./metacognition/index.ts";
|
|
53
|
+
export { createSubagentLaneAuthority, type SubagentLaneAuthority, type SubagentLaneAuthorityDispatchInput, type SubagentLaneAuthorityDispatchResult, type SubagentLaneAuthorityHostBinding, } from "./core/subagent-lane-authority.ts";
|
|
54
|
+
export type { SubagentLaneSpec } from "./core/subagent-orchestration.ts";
|
|
55
|
+
export type { LaneOutcome } from "./core/subagent-lane-launcher.ts";
|
|
51
56
|
export { type BashOperations, type BashSpawnContext, type BashSpawnHook, type BashToolDetails, type BashToolInput, type BashToolOptions, createBashToolDefinition, type LocalBashOperationsOptions, createDiagnosticsTool, createDiagnosticsToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLocalBashOperations, createLsToolDefinition, createReadToolDefinition, createWriteToolDefinition, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type DiagnosticLine, type DiagnosticsToolDetails, type DiagnosticsToolInput, type EditOperations, type EditToolDetails, type EditToolInput, type EditToolOptions, type FindOperations, type FindToolDetails, type FindToolInput, type FindToolOptions, formatSize, type GrepOperations, type GrepToolDetails, type GrepToolInput, type GrepToolOptions, type LsOperations, type LsToolDetails, type LsToolInput, type LsToolOptions, type ReadOperations, type ReadToolDetails, type ReadToolInput, type ReadToolOptions, type ToolsOptions, type TruncationOptions, type TruncationResult, truncateHead, truncateLine, truncateTail, type WriteOperations, type WriteToolInput, type WriteToolOptions, withFileMutationQueue, } from "./core/tools/index.ts";
|
|
52
57
|
export { createVerifiedBashOperations, executeVerifiedBash, executeVerifiedLocalBash, VERIFIED_BASH_REDACTION_POLICY_ID, VerifiedBashAdapterError, type VerifiedBashExecutionRequest, type VerifiedBashOperationsBinding, type VerifiedLocalBashExecutionRequest, } from "./core/verified-bash-adapter.ts";
|
|
53
58
|
export { isVerifiedBashEnabled, resolveSessionWorkspaceScope } from "./core/verified-bash-runtime.ts";
|