open-multi-agent-kit 0.96.2 → 0.98.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 +51 -0
- package/README.md +43 -9
- package/dist/cli/args.d.ts +2 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +13 -189
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +194 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js +2 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/resource-paths.d.ts +4 -0
- package/dist/cli/resource-paths.d.ts.map +1 -0
- package/dist/cli/resource-paths.js +59 -0
- package/dist/cli/resource-paths.js.map +1 -0
- package/dist/commands/adaptorch-doctor-cli.d.ts +13 -0
- package/dist/commands/adaptorch-doctor-cli.d.ts.map +1 -0
- package/dist/commands/adaptorch-doctor-cli.js +115 -0
- package/dist/commands/adaptorch-doctor-cli.js.map +1 -0
- package/dist/commands/resource-doctor-cli.d.ts +4 -0
- package/dist/commands/resource-doctor-cli.d.ts.map +1 -1
- package/dist/commands/resource-doctor-cli.js +35 -5
- package/dist/commands/resource-doctor-cli.js.map +1 -1
- package/dist/core/adaptorch-bridge.d.ts +11 -13
- package/dist/core/adaptorch-bridge.d.ts.map +1 -1
- package/dist/core/adaptorch-bridge.js +11 -13
- package/dist/core/adaptorch-bridge.js.map +1 -1
- package/dist/core/agent-session-snapshot.d.ts +16 -0
- package/dist/core/agent-session-snapshot.d.ts.map +1 -0
- package/dist/core/agent-session-snapshot.js +111 -0
- package/dist/core/agent-session-snapshot.js.map +1 -0
- package/dist/core/agent-session.d.ts +14 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +102 -217
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agent-tool-settings.d.ts +10 -0
- package/dist/core/agent-tool-settings.d.ts.map +1 -1
- package/dist/core/agent-tool-settings.js +10 -1
- package/dist/core/agent-tool-settings.js.map +1 -1
- package/dist/core/attachment-store.d.ts +39 -0
- package/dist/core/attachment-store.d.ts.map +1 -0
- package/dist/core/attachment-store.js +81 -0
- package/dist/core/attachment-store.js.map +1 -0
- package/dist/core/command-safety.d.ts +8 -0
- package/dist/core/command-safety.d.ts.map +1 -1
- package/dist/core/command-safety.js +140 -14
- package/dist/core/command-safety.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +13 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +60 -62
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts +1 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/knowledge-triage-format.d.ts +9 -0
- package/dist/core/compaction/knowledge-triage-format.d.ts.map +1 -0
- package/dist/core/compaction/knowledge-triage-format.js +71 -0
- package/dist/core/compaction/knowledge-triage-format.js.map +1 -0
- package/dist/core/compaction/knowledge-triage-types.d.ts +7 -0
- package/dist/core/compaction/knowledge-triage-types.d.ts.map +1 -0
- package/dist/core/compaction/knowledge-triage-types.js +2 -0
- package/dist/core/compaction/knowledge-triage-types.js.map +1 -0
- package/dist/core/compaction/knowledge-triage.d.ts +29 -0
- package/dist/core/compaction/knowledge-triage.d.ts.map +1 -0
- package/dist/core/compaction/knowledge-triage.js +189 -0
- package/dist/core/compaction/knowledge-triage.js.map +1 -0
- package/dist/core/compaction/transaction.d.ts.map +1 -1
- package/dist/core/compaction/transaction.js +1 -1
- package/dist/core/compaction/transaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +4 -0
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +37 -0
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/completion-sound-io.d.ts +14 -0
- package/dist/core/completion-sound-io.d.ts.map +1 -0
- package/dist/core/completion-sound-io.js +64 -0
- package/dist/core/completion-sound-io.js.map +1 -0
- package/dist/core/completion-sound.d.ts +4 -10
- package/dist/core/completion-sound.d.ts.map +1 -1
- package/dist/core/completion-sound.js +28 -58
- package/dist/core/completion-sound.js.map +1 -1
- package/dist/core/context-budget-governor-v2.d.ts +1 -1
- package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
- package/dist/core/context-budget-governor-v2.js +1 -1
- package/dist/core/context-budget-governor-v2.js.map +1 -1
- package/dist/core/context-budget-relevance.d.ts +15 -2
- package/dist/core/context-budget-relevance.d.ts.map +1 -1
- package/dist/core/context-budget-relevance.js +21 -9
- package/dist/core/context-budget-relevance.js.map +1 -1
- package/dist/core/context-budget-system-prompt-items.d.ts +1 -1
- package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt-items.js.map +1 -1
- package/dist/core/context-budget-system-prompt.d.ts +1 -1
- package/dist/core/context-budget-system-prompt.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt.js.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.d.ts +3 -0
- package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-cache-keys.js +2 -0
- package/dist/core/context-budget-v2-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -1
- package/dist/core/context-budget-v2-plan-cache-keys.js +3 -0
- package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -1
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +2 -1
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-scoring.d.ts +17 -0
- package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
- package/dist/core/context-budget-v2-scoring.js +25 -8
- package/dist/core/context-budget-v2-scoring.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +2 -2
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +18 -1
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +17 -0
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js +15 -0
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/context-file.d.ts +23 -0
- package/dist/core/context-file.d.ts.map +1 -0
- package/dist/core/context-file.js +17 -0
- package/dist/core/context-file.js.map +1 -0
- package/dist/core/extensions/builtin/command-safety-gate.d.ts +3 -1
- package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
- package/dist/core/extensions/builtin/command-safety-gate.js +7 -0
- package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
- package/dist/core/extensions/types.d.ts +12 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +6 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-prompt-policy.d.ts +1 -1
- package/dist/core/model-prompt-policy.d.ts.map +1 -1
- package/dist/core/model-prompt-policy.js.map +1 -1
- package/dist/core/model-registry.d.ts +8 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +71 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-doctor-source-scan.d.ts +9 -0
- package/dist/core/package-doctor-source-scan.d.ts.map +1 -1
- package/dist/core/package-doctor-source-scan.js +77 -4
- package/dist/core/package-doctor-source-scan.js.map +1 -1
- package/dist/core/prompt-attachment.d.ts +51 -0
- package/dist/core/prompt-attachment.d.ts.map +1 -0
- package/dist/core/prompt-attachment.js +186 -0
- package/dist/core/prompt-attachment.js.map +1 -0
- package/dist/core/prompt-settlement.d.ts +6 -3
- package/dist/core/prompt-settlement.d.ts.map +1 -1
- package/dist/core/prompt-settlement.js +10 -14
- package/dist/core/prompt-settlement.js.map +1 -1
- package/dist/core/provider-resilience.d.ts +28 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +50 -0
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-retry.d.ts +1 -1
- package/dist/core/provider-retry.d.ts.map +1 -1
- package/dist/core/provider-retry.js +1 -1
- package/dist/core/provider-retry.js.map +1 -1
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +68 -2
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/reasoning-router-promotion.d.ts +124 -0
- package/dist/core/reasoning-router-promotion.d.ts.map +1 -0
- package/dist/core/reasoning-router-promotion.js +121 -0
- package/dist/core/reasoning-router-promotion.js.map +1 -0
- package/dist/core/reasoning-router-replay-stability.d.ts +65 -0
- package/dist/core/reasoning-router-replay-stability.d.ts.map +1 -0
- package/dist/core/reasoning-router-replay-stability.js +67 -0
- package/dist/core/reasoning-router-replay-stability.js.map +1 -0
- package/dist/core/reasoning-router-v4-weights.d.ts +6 -6
- package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4-weights.js +3 -3
- package/dist/core/reasoning-router-v4-weights.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +6 -6
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/redaction.d.ts.map +1 -1
- package/dist/core/redaction.js +1 -1
- package/dist/core/redaction.js.map +1 -1
- package/dist/core/resource-admission.d.ts +2 -1
- package/dist/core/resource-admission.d.ts.map +1 -1
- package/dist/core/resource-admission.js +11 -0
- package/dist/core/resource-admission.js.map +1 -1
- package/dist/core/resource-governor-format.d.ts +1 -1
- package/dist/core/resource-governor-format.d.ts.map +1 -1
- package/dist/core/resource-governor-format.js.map +1 -1
- package/dist/core/resource-governor-settings.d.ts +6 -12
- package/dist/core/resource-governor-settings.d.ts.map +1 -1
- package/dist/core/resource-governor-settings.js.map +1 -1
- package/dist/core/resource-governor-types.d.ts +24 -0
- package/dist/core/resource-governor-types.d.ts.map +1 -0
- package/dist/core/resource-governor-types.js +15 -0
- package/dist/core/resource-governor-types.js.map +1 -0
- package/dist/core/resource-loader.d.ts +1 -7
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/resource-observation-journal.d.ts +2 -1
- package/dist/core/resource-observation-journal.d.ts.map +1 -1
- package/dist/core/resource-observation-journal.js +4 -3
- package/dist/core/resource-observation-journal.js.map +1 -1
- package/dist/core/resource-observation-report-reader.d.ts +7 -0
- package/dist/core/resource-observation-report-reader.d.ts.map +1 -0
- package/dist/core/resource-observation-report-reader.js +157 -0
- package/dist/core/resource-observation-report-reader.js.map +1 -0
- package/dist/core/resource-observation-report.d.ts +24 -0
- package/dist/core/resource-observation-report.d.ts.map +1 -0
- package/dist/core/resource-observation-report.js +101 -0
- package/dist/core/resource-observation-report.js.map +1 -0
- package/dist/core/router-feedback-collector.d.ts +1 -1
- package/dist/core/router-feedback-collector.d.ts.map +1 -1
- package/dist/core/router-feedback-collector.js.map +1 -1
- package/dist/core/session-bash-service.d.ts.map +1 -1
- package/dist/core/session-bash-service.js +4 -3
- package/dist/core/session-bash-service.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts +33 -0
- package/dist/core/session-failure-cause.d.ts.map +1 -0
- package/dist/core/session-failure-cause.js +141 -0
- package/dist/core/session-failure-cause.js.map +1 -0
- package/dist/core/session-system-prompt.d.ts +1 -1
- package/dist/core/session-system-prompt.d.ts.map +1 -1
- package/dist/core/session-system-prompt.js.map +1 -1
- package/dist/core/session-termination.d.ts +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +11 -2
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +10 -14
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +13 -48
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -34
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/workload-classifier.d.ts +2 -10
- package/dist/core/workload-classifier.d.ts.map +1 -1
- package/dist/core/workload-classifier.js +17 -0
- package/dist/core/workload-classifier.js.map +1 -1
- package/dist/core/workload-family-matcher.d.ts +1 -1
- package/dist/core/workload-family-matcher.d.ts.map +1 -1
- package/dist/core/workload-family-matcher.js.map +1 -1
- package/dist/core/workload-shard-execution-types.d.ts +40 -0
- package/dist/core/workload-shard-execution-types.d.ts.map +1 -0
- package/dist/core/workload-shard-execution-types.js +14 -0
- package/dist/core/workload-shard-execution-types.js.map +1 -0
- package/dist/core/workload-shard-executor.d.ts +3 -27
- package/dist/core/workload-shard-executor.d.ts.map +1 -1
- package/dist/core/workload-shard-executor.js.map +1 -1
- package/dist/core/workload-shard-runner.d.ts +1 -1
- package/dist/core/workload-shard-runner.d.ts.map +1 -1
- package/dist/core/workload-shard-runner.js.map +1 -1
- package/dist/core/workload-types.d.ts +24 -0
- package/dist/core/workload-types.d.ts.map +1 -0
- package/dist/core/workload-types.js +15 -0
- package/dist/core/workload-types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +27 -47
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/attachment-strip.d.ts +21 -0
- package/dist/modes/interactive/components/attachment-strip.d.ts.map +1 -0
- package/dist/modes/interactive/components/attachment-strip.js +136 -0
- package/dist/modes/interactive/components/attachment-strip.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +6 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +26 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-sidebar.js +12 -1
- package/dist/modes/interactive/components/status-sidebar.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +23 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +174 -53
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/omk-control-panel.json +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +42 -33
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +14 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/adaptorch-preview-spec.md +20 -18
- package/docs/adaptorch-preview.md +9 -9
- package/docs/compaction.md +25 -4
- package/docs/correctness-wall.md +10 -10
- package/docs/docs.json +12 -0
- package/docs/environment-variables.md +9 -2
- package/docs/extensions.md +12 -3
- package/docs/index.md +7 -1
- package/docs/metrics.md +74 -2
- package/docs/provider-resilience.md +11 -0
- package/docs/runtime-algorithms.md +359 -0
- package/docs/sdk.md +2 -2
- package/docs/settings.md +11 -10
- package/docs/usage.md +19 -3
- 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/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 +7 -7
- package/dist/core/context-budget-governor.d.ts +0 -67
- package/dist/core/context-budget-governor.d.ts.map +0 -1
- package/dist/core/context-budget-governor.js +0 -224
- package/dist/core/context-budget-governor.js.map +0 -1
- package/dist/core/lean-ctx.d.ts +0 -99
- package/dist/core/lean-ctx.d.ts.map +0 -1
- package/dist/core/lean-ctx.js +0 -225
- package/dist/core/lean-ctx.js.map +0 -1
- package/dist/core/read-anchors.d.ts +0 -110
- package/dist/core/read-anchors.d.ts.map +0 -1
- package/dist/core/read-anchors.js +0 -193
- package/dist/core/read-anchors.js.map +0 -1
- package/dist/core/recovery-checkpoint.d.ts +0 -196
- package/dist/core/recovery-checkpoint.d.ts.map +0 -1
- package/dist/core/recovery-checkpoint.js +0 -382
- package/dist/core/recovery-checkpoint.js.map +0 -1
- package/dist/core/sandbox-policy-v2.d.ts +0 -49
- package/dist/core/sandbox-policy-v2.d.ts.map +0 -1
- package/dist/core/sandbox-policy-v2.js +0 -368
- package/dist/core/sandbox-policy-v2.js.map +0 -1
- package/dist/core/tools/omp-pure-seams.d.ts +0 -41
- package/dist/core/tools/omp-pure-seams.d.ts.map +0 -1
- package/dist/core/tools/omp-pure-seams.js +0 -142
- package/dist/core/tools/omp-pure-seams.js.map +0 -1
- package/dist/core/tools/omp-seam-runtime.d.ts +0 -100
- package/dist/core/tools/omp-seam-runtime.d.ts.map +0 -1
- package/dist/core/tools/omp-seam-runtime.js +0 -40
- package/dist/core/tools/omp-seam-runtime.js.map +0 -1
- package/dist/guardrails/audit-logger.d.ts +0 -4
- package/dist/guardrails/audit-logger.d.ts.map +0 -1
- package/dist/guardrails/audit-logger.js +0 -28
- package/dist/guardrails/audit-logger.js.map +0 -1
- package/dist/guardrails/freedomd-adapter.d.ts +0 -16
- package/dist/guardrails/freedomd-adapter.d.ts.map +0 -1
- package/dist/guardrails/freedomd-adapter.js +0 -87
- package/dist/guardrails/freedomd-adapter.js.map +0 -1
- package/dist/orchestration/lane-grant-auditor.d.ts +0 -4
- package/dist/orchestration/lane-grant-auditor.d.ts.map +0 -1
- package/dist/orchestration/lane-grant-auditor.js +0 -87
- package/dist/orchestration/lane-grant-auditor.js.map +0 -1
- package/dist/types/guardrails.d.ts +0 -61
- package/dist/types/guardrails.d.ts.map +0 -1
- package/dist/types/guardrails.js +0 -9
- package/dist/types/guardrails.js.map +0 -1
- package/dist/types/lane-grant.d.ts +0 -58
- package/dist/types/lane-grant.d.ts.map +0 -1
- package/dist/types/lane-grant.js +0 -9
- package/dist/types/lane-grant.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-family-matcher.d.ts","sourceRoot":"","sources":["../../src/core/workload-family-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,sBAAsB,EAAyB,MAAM,
|
|
1
|
+
{"version":3,"file":"workload-family-matcher.d.ts","sourceRoot":"","sources":["../../src/core/workload-family-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,sBAAsB,EAAyB,MAAM,qBAAqB,CAAC;AA4CxG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,sBAAsB,CAQnF","sourcesContent":["import type { WorkloadClass, WorkloadClassification, WorkloadCommandFamily } from \"./workload-types.ts\";\n\nconst LIGHT_EXECUTABLES = new Set([\n\t\"ls\",\n\t\"cat\",\n\t\"head\",\n\t\"tail\",\n\t\"grep\",\n\t\"rg\",\n\t\"find\",\n\t\"echo\",\n\t\"pwd\",\n\t\"which\",\n\t\"wc\",\n\t\"stat\",\n\t\"file\",\n\t\"true\",\n\t\"false\",\n]);\nconst LIGHT_GIT_SUBCOMMANDS = new Set([\"status\", \"log\", \"diff\", \"show\", \"branch\", \"rev-parse\", \"blame\"]);\nconst IO_EXECUTABLES = new Set([\"cp\", \"mv\", \"rsync\", \"mkdir\", \"touch\", \"dd\"]);\nconst CPU_EXECUTABLES = new Set([\"eslint\", \"prettier\", \"biome\", \"ruff\", \"gofmt\", \"rustfmt\"]);\nconst PACKAGE_MANAGERS = new Set([\"npm\", \"pnpm\", \"yarn\", \"bun\"]);\nconst JS_TEST_RUNNERS = new Set([\"vitest\", \"jest\"]);\nconst SHARD_CONFLICT_FLAGS = [\"--shard\", \"--runInBand\", \"--coverage\", \"--watch\", \"-u\", \"--updateSnapshot\", \"-w\"];\n\nfunction classification(\n\tworkloadClass: WorkloadClass,\n\tcommandFamily: WorkloadCommandFamily,\n\toptions?: { readonly safeToAutoShard?: boolean; readonly extraReasons?: readonly string[] },\n): WorkloadClassification {\n\treturn {\n\t\tworkloadClass,\n\t\tcommandFamily,\n\t\tcomplexity: \"simple-argv\",\n\t\tsafeToAutoShard: options?.safeToAutoShard ?? false,\n\t\treasonCodes: [`family.${commandFamily}`, `class.${workloadClass}`, ...(options?.extraReasons ?? [])],\n\t};\n}\n\nfunction hasShardConflictFlag(argv: readonly string[]): boolean {\n\treturn argv.some((token) => SHARD_CONFLICT_FLAGS.some((flag) => token === flag || token.startsWith(`${flag}=`)));\n}\n\nexport function matchWorkloadFamily(argv: readonly string[]): WorkloadClassification {\n\tconst executable = basename(argv[0]);\n\tconst rest = argv.slice(1);\n\treturn (\n\t\tmatchToolchainFamily(executable, rest) ??\n\t\tmatchInfraFamily(executable, rest) ??\n\t\tmatchTierFallback(executable, rest)\n\t);\n}\n\n/** JS/TS/Go/Rust toolchains (§9.2 first block). */\nfunction matchToolchainFamily(executable: string, rest: readonly string[]): WorkloadClassification | null {\n\tif (JS_TEST_RUNNERS.has(executable)) {\n\t\t// §12.2: direct vitest/jest invocations are shard candidates unless a\n\t\t// conflicting flag changes semantics; the M5 planner enforces the rest.\n\t\tconst conflict = hasShardConflictFlag(rest);\n\t\treturn classification(\"heavy\", \"node-test\", {\n\t\t\tsafeToAutoShard: !conflict,\n\t\t\textraReasons: conflict ? [\"shard.flag.conflict\"] : [],\n\t\t});\n\t}\n\tif (PACKAGE_MANAGERS.has(executable)) {\n\t\tconst script = rest[0] === \"run\" ? rest[1] : rest[0];\n\t\tif (script === \"test\" || script === \"t\" || script?.startsWith(\"test\")) {\n\t\t\t// Opaque wrapper: the underlying runner is unknown statically (§12.1).\n\t\t\treturn classification(\"heavy\", \"node-test\", { extraReasons: [\"shard.wrapper.opaque\"] });\n\t\t}\n\t\tif (script === \"build\" || script?.startsWith(\"build\")) {\n\t\t\treturn classification(\"heavy\", \"node-build\");\n\t\t}\n\t\treturn classification(\"unknown\", \"generic-process\");\n\t}\n\tif (executable === \"tsc\") {\n\t\tconst hasProjectFlag = rest.some((token) => [\"-p\", \"--project\", \"-b\", \"--build\"].includes(token));\n\t\tconst hasFileArg = rest.some((token) => !token.startsWith(\"-\"));\n\t\tif (hasProjectFlag || !hasFileArg) {\n\t\t\treturn classification(\"heavy\", \"typescript\");\n\t\t}\n\t\treturn classification(\"cpu\", \"typescript\");\n\t}\n\tif (executable === \"go\" && rest[0] === \"test\") {\n\t\tconst packageArgs = rest.slice(1).filter((token) => !token.startsWith(\"-\"));\n\t\tconst recursive = packageArgs.some((token) => token.endsWith(\"...\"));\n\t\tif (recursive || packageArgs.length >= 2) {\n\t\t\treturn classification(\"heavy\", \"go-test\", { safeToAutoShard: recursive && !rest.includes(\"-run\") });\n\t\t}\n\t\treturn classification(\"cpu\", \"go-test\");\n\t}\n\tif (executable === \"cargo\" && [\"build\", \"test\", \"check\", \"clippy\"].includes(rest[0] ?? \"\")) {\n\t\treturn classification(\"heavy\", \"rust-build\");\n\t}\n\treturn null;\n}\n\n/** Container/monorepo/archive tooling (§9.2 second block). */\nfunction matchInfraFamily(executable: string, rest: readonly string[]): WorkloadClassification | null {\n\tif ((executable === \"docker\" || executable === \"podman\") && rest[0] === \"build\") {\n\t\treturn classification(\"heavy\", \"container-build\");\n\t}\n\tif ((executable === \"nx\" && rest[0] === \"run-many\") || (executable === \"turbo\" && rest[0] === \"run\")) {\n\t\treturn classification(\"heavy\", \"monorepo\");\n\t}\n\tif (executable === \"tar\") {\n\t\tconst flags = rest[0] ?? \"\";\n\t\tif (flags.includes(\"c\") || rest.includes(\"--create\")) {\n\t\t\treturn classification(\"heavy\", \"archive\");\n\t\t}\n\t\treturn classification(\"io\", \"archive\");\n\t}\n\tif ((executable === \"zip\" && rest.includes(\"-r\")) || (executable === \"7z\" && rest[0] === \"a\")) {\n\t\treturn classification(\"heavy\", \"archive\");\n\t}\n\treturn null;\n}\n\n/** Known light/io/cpu tiers, else unknown/generic-process. */\nfunction matchTierFallback(executable: string, rest: readonly string[]): WorkloadClassification {\n\tif (executable === \"git\" && LIGHT_GIT_SUBCOMMANDS.has(rest[0] ?? \"\")) {\n\t\treturn classification(\"light\", \"generic-process\");\n\t}\n\tif (LIGHT_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"light\", \"generic-process\");\n\t}\n\tif (IO_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"io\", \"generic-process\");\n\t}\n\tif (CPU_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"cpu\", \"generic-process\");\n\t}\n\treturn classification(\"unknown\", \"generic-process\");\n}\n\nfunction basename(token: string): string {\n\tconst slash = token.lastIndexOf(\"/\");\n\treturn slash === -1 ? token : token.slice(slash + 1);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-family-matcher.js","sourceRoot":"","sources":["../../src/core/workload-family-matcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { WorkloadClass, WorkloadClassification, WorkloadCommandFamily } from \"./workload-classifier.ts\";\n\nconst LIGHT_EXECUTABLES = new Set([\n\t\"ls\",\n\t\"cat\",\n\t\"head\",\n\t\"tail\",\n\t\"grep\",\n\t\"rg\",\n\t\"find\",\n\t\"echo\",\n\t\"pwd\",\n\t\"which\",\n\t\"wc\",\n\t\"stat\",\n\t\"file\",\n\t\"true\",\n\t\"false\",\n]);\nconst LIGHT_GIT_SUBCOMMANDS = new Set([\"status\", \"log\", \"diff\", \"show\", \"branch\", \"rev-parse\", \"blame\"]);\nconst IO_EXECUTABLES = new Set([\"cp\", \"mv\", \"rsync\", \"mkdir\", \"touch\", \"dd\"]);\nconst CPU_EXECUTABLES = new Set([\"eslint\", \"prettier\", \"biome\", \"ruff\", \"gofmt\", \"rustfmt\"]);\nconst PACKAGE_MANAGERS = new Set([\"npm\", \"pnpm\", \"yarn\", \"bun\"]);\nconst JS_TEST_RUNNERS = new Set([\"vitest\", \"jest\"]);\nconst SHARD_CONFLICT_FLAGS = [\"--shard\", \"--runInBand\", \"--coverage\", \"--watch\", \"-u\", \"--updateSnapshot\", \"-w\"];\n\nfunction classification(\n\tworkloadClass: WorkloadClass,\n\tcommandFamily: WorkloadCommandFamily,\n\toptions?: { readonly safeToAutoShard?: boolean; readonly extraReasons?: readonly string[] },\n): WorkloadClassification {\n\treturn {\n\t\tworkloadClass,\n\t\tcommandFamily,\n\t\tcomplexity: \"simple-argv\",\n\t\tsafeToAutoShard: options?.safeToAutoShard ?? false,\n\t\treasonCodes: [`family.${commandFamily}`, `class.${workloadClass}`, ...(options?.extraReasons ?? [])],\n\t};\n}\n\nfunction hasShardConflictFlag(argv: readonly string[]): boolean {\n\treturn argv.some((token) => SHARD_CONFLICT_FLAGS.some((flag) => token === flag || token.startsWith(`${flag}=`)));\n}\n\nexport function matchWorkloadFamily(argv: readonly string[]): WorkloadClassification {\n\tconst executable = basename(argv[0]);\n\tconst rest = argv.slice(1);\n\treturn (\n\t\tmatchToolchainFamily(executable, rest) ??\n\t\tmatchInfraFamily(executable, rest) ??\n\t\tmatchTierFallback(executable, rest)\n\t);\n}\n\n/** JS/TS/Go/Rust toolchains (§9.2 first block). */\nfunction matchToolchainFamily(executable: string, rest: readonly string[]): WorkloadClassification | null {\n\tif (JS_TEST_RUNNERS.has(executable)) {\n\t\t// §12.2: direct vitest/jest invocations are shard candidates unless a\n\t\t// conflicting flag changes semantics; the M5 planner enforces the rest.\n\t\tconst conflict = hasShardConflictFlag(rest);\n\t\treturn classification(\"heavy\", \"node-test\", {\n\t\t\tsafeToAutoShard: !conflict,\n\t\t\textraReasons: conflict ? [\"shard.flag.conflict\"] : [],\n\t\t});\n\t}\n\tif (PACKAGE_MANAGERS.has(executable)) {\n\t\tconst script = rest[0] === \"run\" ? rest[1] : rest[0];\n\t\tif (script === \"test\" || script === \"t\" || script?.startsWith(\"test\")) {\n\t\t\t// Opaque wrapper: the underlying runner is unknown statically (§12.1).\n\t\t\treturn classification(\"heavy\", \"node-test\", { extraReasons: [\"shard.wrapper.opaque\"] });\n\t\t}\n\t\tif (script === \"build\" || script?.startsWith(\"build\")) {\n\t\t\treturn classification(\"heavy\", \"node-build\");\n\t\t}\n\t\treturn classification(\"unknown\", \"generic-process\");\n\t}\n\tif (executable === \"tsc\") {\n\t\tconst hasProjectFlag = rest.some((token) => [\"-p\", \"--project\", \"-b\", \"--build\"].includes(token));\n\t\tconst hasFileArg = rest.some((token) => !token.startsWith(\"-\"));\n\t\tif (hasProjectFlag || !hasFileArg) {\n\t\t\treturn classification(\"heavy\", \"typescript\");\n\t\t}\n\t\treturn classification(\"cpu\", \"typescript\");\n\t}\n\tif (executable === \"go\" && rest[0] === \"test\") {\n\t\tconst packageArgs = rest.slice(1).filter((token) => !token.startsWith(\"-\"));\n\t\tconst recursive = packageArgs.some((token) => token.endsWith(\"...\"));\n\t\tif (recursive || packageArgs.length >= 2) {\n\t\t\treturn classification(\"heavy\", \"go-test\", { safeToAutoShard: recursive && !rest.includes(\"-run\") });\n\t\t}\n\t\treturn classification(\"cpu\", \"go-test\");\n\t}\n\tif (executable === \"cargo\" && [\"build\", \"test\", \"check\", \"clippy\"].includes(rest[0] ?? \"\")) {\n\t\treturn classification(\"heavy\", \"rust-build\");\n\t}\n\treturn null;\n}\n\n/** Container/monorepo/archive tooling (§9.2 second block). */\nfunction matchInfraFamily(executable: string, rest: readonly string[]): WorkloadClassification | null {\n\tif ((executable === \"docker\" || executable === \"podman\") && rest[0] === \"build\") {\n\t\treturn classification(\"heavy\", \"container-build\");\n\t}\n\tif ((executable === \"nx\" && rest[0] === \"run-many\") || (executable === \"turbo\" && rest[0] === \"run\")) {\n\t\treturn classification(\"heavy\", \"monorepo\");\n\t}\n\tif (executable === \"tar\") {\n\t\tconst flags = rest[0] ?? \"\";\n\t\tif (flags.includes(\"c\") || rest.includes(\"--create\")) {\n\t\t\treturn classification(\"heavy\", \"archive\");\n\t\t}\n\t\treturn classification(\"io\", \"archive\");\n\t}\n\tif ((executable === \"zip\" && rest.includes(\"-r\")) || (executable === \"7z\" && rest[0] === \"a\")) {\n\t\treturn classification(\"heavy\", \"archive\");\n\t}\n\treturn null;\n}\n\n/** Known light/io/cpu tiers, else unknown/generic-process. */\nfunction matchTierFallback(executable: string, rest: readonly string[]): WorkloadClassification {\n\tif (executable === \"git\" && LIGHT_GIT_SUBCOMMANDS.has(rest[0] ?? \"\")) {\n\t\treturn classification(\"light\", \"generic-process\");\n\t}\n\tif (LIGHT_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"light\", \"generic-process\");\n\t}\n\tif (IO_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"io\", \"generic-process\");\n\t}\n\tif (CPU_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"cpu\", \"generic-process\");\n\t}\n\treturn classification(\"unknown\", \"generic-process\");\n}\n\nfunction basename(token: string): string {\n\tconst slash = token.lastIndexOf(\"/\");\n\treturn slash === -1 ? token : token.slice(slash + 1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workload-family-matcher.js","sourceRoot":"","sources":["../../src/core/workload-family-matcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { WorkloadClass, WorkloadClassification, WorkloadCommandFamily } from \"./workload-types.ts\";\n\nconst LIGHT_EXECUTABLES = new Set([\n\t\"ls\",\n\t\"cat\",\n\t\"head\",\n\t\"tail\",\n\t\"grep\",\n\t\"rg\",\n\t\"find\",\n\t\"echo\",\n\t\"pwd\",\n\t\"which\",\n\t\"wc\",\n\t\"stat\",\n\t\"file\",\n\t\"true\",\n\t\"false\",\n]);\nconst LIGHT_GIT_SUBCOMMANDS = new Set([\"status\", \"log\", \"diff\", \"show\", \"branch\", \"rev-parse\", \"blame\"]);\nconst IO_EXECUTABLES = new Set([\"cp\", \"mv\", \"rsync\", \"mkdir\", \"touch\", \"dd\"]);\nconst CPU_EXECUTABLES = new Set([\"eslint\", \"prettier\", \"biome\", \"ruff\", \"gofmt\", \"rustfmt\"]);\nconst PACKAGE_MANAGERS = new Set([\"npm\", \"pnpm\", \"yarn\", \"bun\"]);\nconst JS_TEST_RUNNERS = new Set([\"vitest\", \"jest\"]);\nconst SHARD_CONFLICT_FLAGS = [\"--shard\", \"--runInBand\", \"--coverage\", \"--watch\", \"-u\", \"--updateSnapshot\", \"-w\"];\n\nfunction classification(\n\tworkloadClass: WorkloadClass,\n\tcommandFamily: WorkloadCommandFamily,\n\toptions?: { readonly safeToAutoShard?: boolean; readonly extraReasons?: readonly string[] },\n): WorkloadClassification {\n\treturn {\n\t\tworkloadClass,\n\t\tcommandFamily,\n\t\tcomplexity: \"simple-argv\",\n\t\tsafeToAutoShard: options?.safeToAutoShard ?? false,\n\t\treasonCodes: [`family.${commandFamily}`, `class.${workloadClass}`, ...(options?.extraReasons ?? [])],\n\t};\n}\n\nfunction hasShardConflictFlag(argv: readonly string[]): boolean {\n\treturn argv.some((token) => SHARD_CONFLICT_FLAGS.some((flag) => token === flag || token.startsWith(`${flag}=`)));\n}\n\nexport function matchWorkloadFamily(argv: readonly string[]): WorkloadClassification {\n\tconst executable = basename(argv[0]);\n\tconst rest = argv.slice(1);\n\treturn (\n\t\tmatchToolchainFamily(executable, rest) ??\n\t\tmatchInfraFamily(executable, rest) ??\n\t\tmatchTierFallback(executable, rest)\n\t);\n}\n\n/** JS/TS/Go/Rust toolchains (§9.2 first block). */\nfunction matchToolchainFamily(executable: string, rest: readonly string[]): WorkloadClassification | null {\n\tif (JS_TEST_RUNNERS.has(executable)) {\n\t\t// §12.2: direct vitest/jest invocations are shard candidates unless a\n\t\t// conflicting flag changes semantics; the M5 planner enforces the rest.\n\t\tconst conflict = hasShardConflictFlag(rest);\n\t\treturn classification(\"heavy\", \"node-test\", {\n\t\t\tsafeToAutoShard: !conflict,\n\t\t\textraReasons: conflict ? [\"shard.flag.conflict\"] : [],\n\t\t});\n\t}\n\tif (PACKAGE_MANAGERS.has(executable)) {\n\t\tconst script = rest[0] === \"run\" ? rest[1] : rest[0];\n\t\tif (script === \"test\" || script === \"t\" || script?.startsWith(\"test\")) {\n\t\t\t// Opaque wrapper: the underlying runner is unknown statically (§12.1).\n\t\t\treturn classification(\"heavy\", \"node-test\", { extraReasons: [\"shard.wrapper.opaque\"] });\n\t\t}\n\t\tif (script === \"build\" || script?.startsWith(\"build\")) {\n\t\t\treturn classification(\"heavy\", \"node-build\");\n\t\t}\n\t\treturn classification(\"unknown\", \"generic-process\");\n\t}\n\tif (executable === \"tsc\") {\n\t\tconst hasProjectFlag = rest.some((token) => [\"-p\", \"--project\", \"-b\", \"--build\"].includes(token));\n\t\tconst hasFileArg = rest.some((token) => !token.startsWith(\"-\"));\n\t\tif (hasProjectFlag || !hasFileArg) {\n\t\t\treturn classification(\"heavy\", \"typescript\");\n\t\t}\n\t\treturn classification(\"cpu\", \"typescript\");\n\t}\n\tif (executable === \"go\" && rest[0] === \"test\") {\n\t\tconst packageArgs = rest.slice(1).filter((token) => !token.startsWith(\"-\"));\n\t\tconst recursive = packageArgs.some((token) => token.endsWith(\"...\"));\n\t\tif (recursive || packageArgs.length >= 2) {\n\t\t\treturn classification(\"heavy\", \"go-test\", { safeToAutoShard: recursive && !rest.includes(\"-run\") });\n\t\t}\n\t\treturn classification(\"cpu\", \"go-test\");\n\t}\n\tif (executable === \"cargo\" && [\"build\", \"test\", \"check\", \"clippy\"].includes(rest[0] ?? \"\")) {\n\t\treturn classification(\"heavy\", \"rust-build\");\n\t}\n\treturn null;\n}\n\n/** Container/monorepo/archive tooling (§9.2 second block). */\nfunction matchInfraFamily(executable: string, rest: readonly string[]): WorkloadClassification | null {\n\tif ((executable === \"docker\" || executable === \"podman\") && rest[0] === \"build\") {\n\t\treturn classification(\"heavy\", \"container-build\");\n\t}\n\tif ((executable === \"nx\" && rest[0] === \"run-many\") || (executable === \"turbo\" && rest[0] === \"run\")) {\n\t\treturn classification(\"heavy\", \"monorepo\");\n\t}\n\tif (executable === \"tar\") {\n\t\tconst flags = rest[0] ?? \"\";\n\t\tif (flags.includes(\"c\") || rest.includes(\"--create\")) {\n\t\t\treturn classification(\"heavy\", \"archive\");\n\t\t}\n\t\treturn classification(\"io\", \"archive\");\n\t}\n\tif ((executable === \"zip\" && rest.includes(\"-r\")) || (executable === \"7z\" && rest[0] === \"a\")) {\n\t\treturn classification(\"heavy\", \"archive\");\n\t}\n\treturn null;\n}\n\n/** Known light/io/cpu tiers, else unknown/generic-process. */\nfunction matchTierFallback(executable: string, rest: readonly string[]): WorkloadClassification {\n\tif (executable === \"git\" && LIGHT_GIT_SUBCOMMANDS.has(rest[0] ?? \"\")) {\n\t\treturn classification(\"light\", \"generic-process\");\n\t}\n\tif (LIGHT_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"light\", \"generic-process\");\n\t}\n\tif (IO_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"io\", \"generic-process\");\n\t}\n\tif (CPU_EXECUTABLES.has(executable)) {\n\t\treturn classification(\"cpu\", \"generic-process\");\n\t}\n\treturn classification(\"unknown\", \"generic-process\");\n}\n\nfunction basename(token: string): string {\n\tconst slash = token.lastIndexOf(\"/\");\n\treturn slash === -1 ? token : token.slice(slash + 1);\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shard execution contract.
|
|
3
|
+
*
|
|
4
|
+
* These declarations describe the call the executor makes and the input it
|
|
5
|
+
* takes. They lived in the executor, so the runner — which the executor calls
|
|
6
|
+
* to advance one shard — had to import the executor back to name its own
|
|
7
|
+
* parameter type. Moving the contract below both leaves the executor free to
|
|
8
|
+
* depend on the runner without the runner depending on the executor.
|
|
9
|
+
*
|
|
10
|
+
* Types only. Imports stay on the plan, store, admission, and permit modules,
|
|
11
|
+
* none of which reach the executor or the runner.
|
|
12
|
+
*/
|
|
13
|
+
import type { ResourceAdmissionDecision } from "./resource-admission.ts";
|
|
14
|
+
import type { WorkloadPermitPool } from "./workload-permit-pool.ts";
|
|
15
|
+
import type { WorkloadShardPlan, WorkloadShardSpec } from "./workload-shard-plan.ts";
|
|
16
|
+
import type { WorkloadShardStore } from "./workload-shard-store.ts";
|
|
17
|
+
export interface ShardRunContext {
|
|
18
|
+
readonly shard: WorkloadShardSpec;
|
|
19
|
+
readonly attempt: number;
|
|
20
|
+
readonly signal?: AbortSignal;
|
|
21
|
+
}
|
|
22
|
+
export type ShardRunner = (context: ShardRunContext) => Promise<{
|
|
23
|
+
readonly exitCode: number;
|
|
24
|
+
readonly evidenceRefs?: readonly string[];
|
|
25
|
+
}>;
|
|
26
|
+
export interface ExecuteWorkloadShardPlanInput {
|
|
27
|
+
readonly plan: WorkloadShardPlan;
|
|
28
|
+
readonly store: WorkloadShardStore;
|
|
29
|
+
readonly runner: ShardRunner;
|
|
30
|
+
readonly decision: ResourceAdmissionDecision;
|
|
31
|
+
readonly permitPool?: WorkloadPermitPool;
|
|
32
|
+
readonly signal?: AbortSignal;
|
|
33
|
+
/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */
|
|
34
|
+
readonly retryFailed?: boolean;
|
|
35
|
+
/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */
|
|
36
|
+
readonly resumeAborted?: boolean;
|
|
37
|
+
readonly permitWaitTimeoutMs?: number;
|
|
38
|
+
readonly now?: () => Date;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=workload-shard-execution-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-shard-execution-types.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-execution-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,MAAM,WAAW,GAAG,CACzB,OAAO,EAAE,eAAe,KACpB,OAAO,CAAC;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAEvF,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,kFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,gGAA+F;IAC/F,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B","sourcesContent":["/**\n * Shard execution contract.\n *\n * These declarations describe the call the executor makes and the input it\n * takes. They lived in the executor, so the runner — which the executor calls\n * to advance one shard — had to import the executor back to name its own\n * parameter type. Moving the contract below both leaves the executor free to\n * depend on the runner without the runner depending on the executor.\n *\n * Types only. Imports stay on the plan, store, admission, and permit modules,\n * none of which reach the executor or the runner.\n */\n\nimport type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport type { WorkloadShardPlan, WorkloadShardSpec } from \"./workload-shard-plan.ts\";\nimport type { WorkloadShardStore } from \"./workload-shard-store.ts\";\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shard execution contract.
|
|
3
|
+
*
|
|
4
|
+
* These declarations describe the call the executor makes and the input it
|
|
5
|
+
* takes. They lived in the executor, so the runner — which the executor calls
|
|
6
|
+
* to advance one shard — had to import the executor back to name its own
|
|
7
|
+
* parameter type. Moving the contract below both leaves the executor free to
|
|
8
|
+
* depend on the runner without the runner depending on the executor.
|
|
9
|
+
*
|
|
10
|
+
* Types only. Imports stay on the plan, store, admission, and permit modules,
|
|
11
|
+
* none of which reach the executor or the runner.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=workload-shard-execution-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-shard-execution-types.js","sourceRoot":"","sources":["../../src/core/workload-shard-execution-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG","sourcesContent":["/**\n * Shard execution contract.\n *\n * These declarations describe the call the executor makes and the input it\n * takes. They lived in the executor, so the runner — which the executor calls\n * to advance one shard — had to import the executor back to name its own\n * parameter type. Moving the contract below both leaves the executor free to\n * depend on the runner without the runner depending on the executor.\n *\n * Types only. Imports stay on the plan, store, admission, and permit modules,\n * none of which reach the executor or the runner.\n */\n\nimport type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport type { WorkloadShardPlan, WorkloadShardSpec } from \"./workload-shard-plan.ts\";\nimport type { WorkloadShardStore } from \"./workload-shard-store.ts\";\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type
|
|
3
|
-
|
|
4
|
-
import { type WorkloadShardStore } from "./workload-shard-store.ts";
|
|
1
|
+
import type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner } from "./workload-shard-execution-types.ts";
|
|
2
|
+
import { type WorkloadShardState } from "./workload-shard-plan.ts";
|
|
3
|
+
export type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner };
|
|
5
4
|
/**
|
|
6
5
|
* Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).
|
|
7
6
|
*
|
|
@@ -19,29 +18,6 @@ import { type WorkloadShardStore } from "./workload-shard-store.ts";
|
|
|
19
18
|
* it only runs what the plan's descriptors already describe via the
|
|
20
19
|
* injected runner.
|
|
21
20
|
*/
|
|
22
|
-
export interface ShardRunContext {
|
|
23
|
-
readonly shard: WorkloadShardSpec;
|
|
24
|
-
readonly attempt: number;
|
|
25
|
-
readonly signal?: AbortSignal;
|
|
26
|
-
}
|
|
27
|
-
export type ShardRunner = (context: ShardRunContext) => Promise<{
|
|
28
|
-
readonly exitCode: number;
|
|
29
|
-
readonly evidenceRefs?: readonly string[];
|
|
30
|
-
}>;
|
|
31
|
-
export interface ExecuteWorkloadShardPlanInput {
|
|
32
|
-
readonly plan: WorkloadShardPlan;
|
|
33
|
-
readonly store: WorkloadShardStore;
|
|
34
|
-
readonly runner: ShardRunner;
|
|
35
|
-
readonly decision: ResourceAdmissionDecision;
|
|
36
|
-
readonly permitPool?: WorkloadPermitPool;
|
|
37
|
-
readonly signal?: AbortSignal;
|
|
38
|
-
/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */
|
|
39
|
-
readonly retryFailed?: boolean;
|
|
40
|
-
/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */
|
|
41
|
-
readonly resumeAborted?: boolean;
|
|
42
|
-
readonly permitWaitTimeoutMs?: number;
|
|
43
|
-
readonly now?: () => Date;
|
|
44
|
-
}
|
|
45
21
|
export interface ShardResultSummary {
|
|
46
22
|
readonly shardId: string;
|
|
47
23
|
readonly state: WorkloadShardState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-shard-executor.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAIN,KAAK,iBAAiB,EAEtB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/F;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,MAAM,WAAW,GAAG,CACzB,OAAO,EAAE,eAAe,KACpB,OAAO,CAAC;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAEvF,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,kFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,gGAA+F;IAC/F,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,kEAAgE;AAChE,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,6BAA6B,GAClC,OAAO,CAAC,8BAA8B,CAAC,CAoFzC","sourcesContent":["import type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport {\n\tplanShardResume,\n\treduceShardRecords,\n\tvalidateWorkloadShardPlan,\n\ttype WorkloadShardPlan,\n\ttype WorkloadShardProjection,\n\ttype WorkloadShardSpec,\n\ttype WorkloadShardState,\n} from \"./workload-shard-plan.ts\";\nimport { applyTransition, runOneShard, shardById } from \"./workload-shard-runner.ts\";\nimport { WorkloadShardJournalError, type WorkloadShardStore } from \"./workload-shard-store.ts\";\n\n/**\n * Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).\n *\n * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state\n * machine: passed shards are terminal and never re-run (§13.5 step 3),\n * crash-orphaned `running` shards are recovered through `pending` re-arm\n * records, concurrency is recomputed from the CURRENT admission decision\n * (§13.5 step 6) plus the shared permit pool, and completion produces an\n * aggregate evidence receipt (§13.6) — an observation input for\n * `evaluateTask()`, never a task verdict by itself.\n *\n * Fail-closed rules (§21): a corrupt journal is quarantined and the run is\n * `blocked`; a journal written for a different plan is `blocked`; an invalid\n * plan never starts. The executor never rewrites shard commands (§12.3) —\n * it only runs what the plan's descriptors already describe via the\n * injected runner.\n */\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n\nexport interface ShardResultSummary {\n\treadonly shardId: string;\n\treadonly state: WorkloadShardState;\n\treadonly attempt: number;\n\treadonly evidenceRefs: readonly string[];\n\treadonly reasonCode?: string;\n}\n\n/** §13.6 aggregate evidence receipt; §15.1 observation kind. */\nexport interface WorkloadShardAggregateEvidence {\n\treadonly kind: \"workload_shard_result.v1\";\n\treadonly planId: string;\n\treadonly promptRunId: string;\n\treadonly commandDigest: string;\n\treadonly strategy: string;\n\treadonly verdict: \"passed\" | \"failed\" | \"aborted\" | \"blocked\";\n\treadonly reasonCodes: readonly string[];\n\treadonly shardCount: number;\n\treadonly counts: Readonly<Record<WorkloadShardState, number>>;\n\treadonly shards: readonly ShardResultSummary[];\n\treadonly effectiveConcurrency: number;\n\treadonly completedAt: string;\n}\n\nexport async function executeWorkloadShardPlan(\n\tinput: ExecuteWorkloadShardPlanInput,\n): Promise<WorkloadShardAggregateEvidence> {\n\tconst now = input.now ?? (() => new Date());\n\tconst planErrors = validateWorkloadShardPlan(input.plan);\n\tif (planErrors.length > 0) {\n\t\treturn blockedEvidence(input, now, [\"plan.invalid\", ...planErrors.slice(0, 3)]);\n\t}\n\n\tlet journal: ReturnType<WorkloadShardStore[\"load\"]>;\n\ttry {\n\t\tjournal = input.store.load();\n\t} catch (error) {\n\t\t// §21 fail closed: corrupt evidence is quarantined, never silently rebuilt.\n\t\tif (error instanceof WorkloadShardJournalError) {\n\t\t\tinput.store.quarantine();\n\t\t\treturn blockedEvidence(input, now, [`journal.${error.code}`]);\n\t\t}\n\t\tthrow error;\n\t}\n\tif (journal.plan === null) {\n\t\tinput.store.appendPlan(input.plan);\n\t} else if (journal.plan.planId !== input.plan.planId || journal.plan.commandDigest !== input.plan.commandDigest) {\n\t\treturn blockedEvidence(input, now, [\"plan.mismatch\"]);\n\t}\n\n\tconst projections = new Map<string, WorkloadShardProjection>(\n\t\tjournal.projections ?? reduceShardRecords(input.plan, []),\n\t);\n\tconst effectiveConcurrency = Math.max(1, Math.min(input.plan.maxConcurrency, input.decision.maxHeavyProcesses));\n\n\t// §13.5 steps 2-4: re-arm recoverable shards through explicit pending records.\n\tconst resume = planShardResume(input.plan, projections);\n\tconst rearm = [\n\t\t...resume.interrupted,\n\t\t...(input.retryFailed ? resume.retryable : []),\n\t\t...((input.resumeAborted ?? true) ? resume.resumable : []),\n\t];\n\tfor (const shardId of rearm) {\n\t\t// §13.5 step 2: a crash-orphaned `running` shard is first projected as\n\t\t// interrupted (running -> pending is illegal in §13.4), then re-armed.\n\t\tif (projections.get(shardId)?.state === \"running\") {\n\t\t\tapplyTransition(input, projections, shardId, \"interrupted\", { reasonCode: \"recovery.orphaned\", now });\n\t\t}\n\t\tapplyTransition(input, projections, shardId, \"pending\", { reasonCode: \"recovery.rearm\", now });\n\t}\n\n\t// Dependency-wave scheduler: launch ready shards up to the recomputed width.\n\tconst remaining = new Set(\n\t\tinput.plan.shards.map((shard) => shard.shardId).filter((id) => projections.get(id)?.state !== \"passed\"),\n\t);\n\tlet active = 0;\n\tlet wake: (() => void) | undefined;\n\tconst waitTurn = () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\twake = resolve;\n\t\t});\n\tconst running = new Map<string, Promise<void>>();\n\n\twhile (remaining.size > 0 && !input.signal?.aborted) {\n\t\tconst ready = [...remaining].filter((id) => {\n\t\t\tconst projection = projections.get(id);\n\t\t\tif (projection?.state !== \"pending\") return false;\n\t\t\tconst spec = shardById(input.plan, id);\n\t\t\treturn spec.dependencyIds.every((dep) => projections.get(dep)?.state === \"passed\");\n\t\t});\n\t\tconst launchable = ready.slice(0, Math.max(0, effectiveConcurrency - active));\n\t\tif (launchable.length === 0) {\n\t\t\tif (running.size === 0) break; // deadlock = blocked dependents; aggregate reports them\n\t\t\tawait Promise.race([...running.values(), waitTurn()]);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const shardId of launchable) {\n\t\t\tremaining.delete(shardId);\n\t\t\tactive += 1;\n\t\t\tconst task = runOneShard(input, projections, shardId, now).finally(() => {\n\t\t\t\tactive -= 1;\n\t\t\t\trunning.delete(shardId);\n\t\t\t\twake?.();\n\t\t\t});\n\t\t\trunning.set(shardId, task);\n\t\t}\n\t}\n\tawait Promise.all(running.values());\n\n\treturn aggregate(input, projections, effectiveConcurrency, now, input.signal?.aborted ? [\"run.aborted\"] : []);\n}\n\nfunction aggregate(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: ReadonlyMap<string, WorkloadShardProjection>,\n\teffectiveConcurrency: number,\n\tnow: () => Date,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: 0,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\tconst shards: ShardResultSummary[] = input.plan.shards.map((shard) => {\n\t\tconst projection = projections.get(shard.shardId);\n\t\tconst state = projection?.state ?? \"pending\";\n\t\tcounts[state] += 1;\n\t\treturn {\n\t\t\tshardId: shard.shardId,\n\t\t\tstate,\n\t\t\tattempt: projection?.attempt ?? 0,\n\t\t\tevidenceRefs: projection?.evidenceRefs ?? [],\n\t\t\t...(projection?.reasonCode !== undefined ? { reasonCode: projection.reasonCode } : {}),\n\t\t};\n\t});\n\tconst verdict = aggregateVerdict(counts, input.plan.shards.length, extraReasons);\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict,\n\t\treasonCodes: extraReasons,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards,\n\t\teffectiveConcurrency,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\nfunction blockedEvidence(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tnow: () => Date,\n\treasonCodes: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: input.plan.shards.length,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict: \"blocked\",\n\t\treasonCodes,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards: input.plan.shards.map((shard) => ({\n\t\t\tshardId: shard.shardId,\n\t\t\tstate: \"pending\" as const,\n\t\t\tattempt: 0,\n\t\t\tevidenceRefs: [],\n\t\t})),\n\t\teffectiveConcurrency: 0,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\n/** §13.6: \"passed\" requires EVERY shard to hold terminal passed evidence. */\nfunction aggregateVerdict(\n\tcounts: Readonly<Record<WorkloadShardState, number>>,\n\tshardCount: number,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence[\"verdict\"] {\n\tif (counts.passed === shardCount) return \"passed\";\n\tif (counts.aborted > 0 || extraReasons.includes(\"run.aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workload-shard-executor.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACvH,OAAO,EAKN,KAAK,kBAAkB,EACvB,MAAM,0BAA0B,CAAC;AAMlC,YAAY,EAAE,6BAA6B,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAE5E;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,kEAAgE;AAChE,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,6BAA6B,GAClC,OAAO,CAAC,8BAA8B,CAAC,CAoFzC","sourcesContent":["import type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner } from \"./workload-shard-execution-types.ts\";\nimport {\n\tplanShardResume,\n\treduceShardRecords,\n\tvalidateWorkloadShardPlan,\n\ttype WorkloadShardProjection,\n\ttype WorkloadShardState,\n} from \"./workload-shard-plan.ts\";\nimport { applyTransition, runOneShard, shardById } from \"./workload-shard-runner.ts\";\nimport { WorkloadShardJournalError, type WorkloadShardStore } from \"./workload-shard-store.ts\";\n\n// The contract lives in `workload-shard-execution-types.ts` so the runner can\n// name its own parameter type without importing this module back.\nexport type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner };\n\n/**\n * Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).\n *\n * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state\n * machine: passed shards are terminal and never re-run (§13.5 step 3),\n * crash-orphaned `running` shards are recovered through `pending` re-arm\n * records, concurrency is recomputed from the CURRENT admission decision\n * (§13.5 step 6) plus the shared permit pool, and completion produces an\n * aggregate evidence receipt (§13.6) — an observation input for\n * `evaluateTask()`, never a task verdict by itself.\n *\n * Fail-closed rules (§21): a corrupt journal is quarantined and the run is\n * `blocked`; a journal written for a different plan is `blocked`; an invalid\n * plan never starts. The executor never rewrites shard commands (§12.3) —\n * it only runs what the plan's descriptors already describe via the\n * injected runner.\n */\n\nexport interface ShardResultSummary {\n\treadonly shardId: string;\n\treadonly state: WorkloadShardState;\n\treadonly attempt: number;\n\treadonly evidenceRefs: readonly string[];\n\treadonly reasonCode?: string;\n}\n\n/** §13.6 aggregate evidence receipt; §15.1 observation kind. */\nexport interface WorkloadShardAggregateEvidence {\n\treadonly kind: \"workload_shard_result.v1\";\n\treadonly planId: string;\n\treadonly promptRunId: string;\n\treadonly commandDigest: string;\n\treadonly strategy: string;\n\treadonly verdict: \"passed\" | \"failed\" | \"aborted\" | \"blocked\";\n\treadonly reasonCodes: readonly string[];\n\treadonly shardCount: number;\n\treadonly counts: Readonly<Record<WorkloadShardState, number>>;\n\treadonly shards: readonly ShardResultSummary[];\n\treadonly effectiveConcurrency: number;\n\treadonly completedAt: string;\n}\n\nexport async function executeWorkloadShardPlan(\n\tinput: ExecuteWorkloadShardPlanInput,\n): Promise<WorkloadShardAggregateEvidence> {\n\tconst now = input.now ?? (() => new Date());\n\tconst planErrors = validateWorkloadShardPlan(input.plan);\n\tif (planErrors.length > 0) {\n\t\treturn blockedEvidence(input, now, [\"plan.invalid\", ...planErrors.slice(0, 3)]);\n\t}\n\n\tlet journal: ReturnType<WorkloadShardStore[\"load\"]>;\n\ttry {\n\t\tjournal = input.store.load();\n\t} catch (error) {\n\t\t// §21 fail closed: corrupt evidence is quarantined, never silently rebuilt.\n\t\tif (error instanceof WorkloadShardJournalError) {\n\t\t\tinput.store.quarantine();\n\t\t\treturn blockedEvidence(input, now, [`journal.${error.code}`]);\n\t\t}\n\t\tthrow error;\n\t}\n\tif (journal.plan === null) {\n\t\tinput.store.appendPlan(input.plan);\n\t} else if (journal.plan.planId !== input.plan.planId || journal.plan.commandDigest !== input.plan.commandDigest) {\n\t\treturn blockedEvidence(input, now, [\"plan.mismatch\"]);\n\t}\n\n\tconst projections = new Map<string, WorkloadShardProjection>(\n\t\tjournal.projections ?? reduceShardRecords(input.plan, []),\n\t);\n\tconst effectiveConcurrency = Math.max(1, Math.min(input.plan.maxConcurrency, input.decision.maxHeavyProcesses));\n\n\t// §13.5 steps 2-4: re-arm recoverable shards through explicit pending records.\n\tconst resume = planShardResume(input.plan, projections);\n\tconst rearm = [\n\t\t...resume.interrupted,\n\t\t...(input.retryFailed ? resume.retryable : []),\n\t\t...((input.resumeAborted ?? true) ? resume.resumable : []),\n\t];\n\tfor (const shardId of rearm) {\n\t\t// §13.5 step 2: a crash-orphaned `running` shard is first projected as\n\t\t// interrupted (running -> pending is illegal in §13.4), then re-armed.\n\t\tif (projections.get(shardId)?.state === \"running\") {\n\t\t\tapplyTransition(input, projections, shardId, \"interrupted\", { reasonCode: \"recovery.orphaned\", now });\n\t\t}\n\t\tapplyTransition(input, projections, shardId, \"pending\", { reasonCode: \"recovery.rearm\", now });\n\t}\n\n\t// Dependency-wave scheduler: launch ready shards up to the recomputed width.\n\tconst remaining = new Set(\n\t\tinput.plan.shards.map((shard) => shard.shardId).filter((id) => projections.get(id)?.state !== \"passed\"),\n\t);\n\tlet active = 0;\n\tlet wake: (() => void) | undefined;\n\tconst waitTurn = () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\twake = resolve;\n\t\t});\n\tconst running = new Map<string, Promise<void>>();\n\n\twhile (remaining.size > 0 && !input.signal?.aborted) {\n\t\tconst ready = [...remaining].filter((id) => {\n\t\t\tconst projection = projections.get(id);\n\t\t\tif (projection?.state !== \"pending\") return false;\n\t\t\tconst spec = shardById(input.plan, id);\n\t\t\treturn spec.dependencyIds.every((dep) => projections.get(dep)?.state === \"passed\");\n\t\t});\n\t\tconst launchable = ready.slice(0, Math.max(0, effectiveConcurrency - active));\n\t\tif (launchable.length === 0) {\n\t\t\tif (running.size === 0) break; // deadlock = blocked dependents; aggregate reports them\n\t\t\tawait Promise.race([...running.values(), waitTurn()]);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const shardId of launchable) {\n\t\t\tremaining.delete(shardId);\n\t\t\tactive += 1;\n\t\t\tconst task = runOneShard(input, projections, shardId, now).finally(() => {\n\t\t\t\tactive -= 1;\n\t\t\t\trunning.delete(shardId);\n\t\t\t\twake?.();\n\t\t\t});\n\t\t\trunning.set(shardId, task);\n\t\t}\n\t}\n\tawait Promise.all(running.values());\n\n\treturn aggregate(input, projections, effectiveConcurrency, now, input.signal?.aborted ? [\"run.aborted\"] : []);\n}\n\nfunction aggregate(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: ReadonlyMap<string, WorkloadShardProjection>,\n\teffectiveConcurrency: number,\n\tnow: () => Date,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: 0,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\tconst shards: ShardResultSummary[] = input.plan.shards.map((shard) => {\n\t\tconst projection = projections.get(shard.shardId);\n\t\tconst state = projection?.state ?? \"pending\";\n\t\tcounts[state] += 1;\n\t\treturn {\n\t\t\tshardId: shard.shardId,\n\t\t\tstate,\n\t\t\tattempt: projection?.attempt ?? 0,\n\t\t\tevidenceRefs: projection?.evidenceRefs ?? [],\n\t\t\t...(projection?.reasonCode !== undefined ? { reasonCode: projection.reasonCode } : {}),\n\t\t};\n\t});\n\tconst verdict = aggregateVerdict(counts, input.plan.shards.length, extraReasons);\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict,\n\t\treasonCodes: extraReasons,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards,\n\t\teffectiveConcurrency,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\nfunction blockedEvidence(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tnow: () => Date,\n\treasonCodes: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: input.plan.shards.length,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict: \"blocked\",\n\t\treasonCodes,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards: input.plan.shards.map((shard) => ({\n\t\t\tshardId: shard.shardId,\n\t\t\tstate: \"pending\" as const,\n\t\t\tattempt: 0,\n\t\t\tevidenceRefs: [],\n\t\t})),\n\t\teffectiveConcurrency: 0,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\n/** §13.6: \"passed\" requires EVERY shard to hold terminal passed evidence. */\nfunction aggregateVerdict(\n\tcounts: Readonly<Record<WorkloadShardState, number>>,\n\tshardCount: number,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence[\"verdict\"] {\n\tif (counts.passed === shardCount) return \"passed\";\n\tif (counts.aborted > 0 || extraReasons.includes(\"run.aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-shard-executor.js","sourceRoot":"","sources":["../../src/core/workload-shard-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport {\n\tplanShardResume,\n\treduceShardRecords,\n\tvalidateWorkloadShardPlan,\n\ttype WorkloadShardPlan,\n\ttype WorkloadShardProjection,\n\ttype WorkloadShardSpec,\n\ttype WorkloadShardState,\n} from \"./workload-shard-plan.ts\";\nimport { applyTransition, runOneShard, shardById } from \"./workload-shard-runner.ts\";\nimport { WorkloadShardJournalError, type WorkloadShardStore } from \"./workload-shard-store.ts\";\n\n/**\n * Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).\n *\n * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state\n * machine: passed shards are terminal and never re-run (§13.5 step 3),\n * crash-orphaned `running` shards are recovered through `pending` re-arm\n * records, concurrency is recomputed from the CURRENT admission decision\n * (§13.5 step 6) plus the shared permit pool, and completion produces an\n * aggregate evidence receipt (§13.6) — an observation input for\n * `evaluateTask()`, never a task verdict by itself.\n *\n * Fail-closed rules (§21): a corrupt journal is quarantined and the run is\n * `blocked`; a journal written for a different plan is `blocked`; an invalid\n * plan never starts. The executor never rewrites shard commands (§12.3) —\n * it only runs what the plan's descriptors already describe via the\n * injected runner.\n */\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n\nexport interface ShardResultSummary {\n\treadonly shardId: string;\n\treadonly state: WorkloadShardState;\n\treadonly attempt: number;\n\treadonly evidenceRefs: readonly string[];\n\treadonly reasonCode?: string;\n}\n\n/** §13.6 aggregate evidence receipt; §15.1 observation kind. */\nexport interface WorkloadShardAggregateEvidence {\n\treadonly kind: \"workload_shard_result.v1\";\n\treadonly planId: string;\n\treadonly promptRunId: string;\n\treadonly commandDigest: string;\n\treadonly strategy: string;\n\treadonly verdict: \"passed\" | \"failed\" | \"aborted\" | \"blocked\";\n\treadonly reasonCodes: readonly string[];\n\treadonly shardCount: number;\n\treadonly counts: Readonly<Record<WorkloadShardState, number>>;\n\treadonly shards: readonly ShardResultSummary[];\n\treadonly effectiveConcurrency: number;\n\treadonly completedAt: string;\n}\n\nexport async function executeWorkloadShardPlan(\n\tinput: ExecuteWorkloadShardPlanInput,\n): Promise<WorkloadShardAggregateEvidence> {\n\tconst now = input.now ?? (() => new Date());\n\tconst planErrors = validateWorkloadShardPlan(input.plan);\n\tif (planErrors.length > 0) {\n\t\treturn blockedEvidence(input, now, [\"plan.invalid\", ...planErrors.slice(0, 3)]);\n\t}\n\n\tlet journal: ReturnType<WorkloadShardStore[\"load\"]>;\n\ttry {\n\t\tjournal = input.store.load();\n\t} catch (error) {\n\t\t// §21 fail closed: corrupt evidence is quarantined, never silently rebuilt.\n\t\tif (error instanceof WorkloadShardJournalError) {\n\t\t\tinput.store.quarantine();\n\t\t\treturn blockedEvidence(input, now, [`journal.${error.code}`]);\n\t\t}\n\t\tthrow error;\n\t}\n\tif (journal.plan === null) {\n\t\tinput.store.appendPlan(input.plan);\n\t} else if (journal.plan.planId !== input.plan.planId || journal.plan.commandDigest !== input.plan.commandDigest) {\n\t\treturn blockedEvidence(input, now, [\"plan.mismatch\"]);\n\t}\n\n\tconst projections = new Map<string, WorkloadShardProjection>(\n\t\tjournal.projections ?? reduceShardRecords(input.plan, []),\n\t);\n\tconst effectiveConcurrency = Math.max(1, Math.min(input.plan.maxConcurrency, input.decision.maxHeavyProcesses));\n\n\t// §13.5 steps 2-4: re-arm recoverable shards through explicit pending records.\n\tconst resume = planShardResume(input.plan, projections);\n\tconst rearm = [\n\t\t...resume.interrupted,\n\t\t...(input.retryFailed ? resume.retryable : []),\n\t\t...((input.resumeAborted ?? true) ? resume.resumable : []),\n\t];\n\tfor (const shardId of rearm) {\n\t\t// §13.5 step 2: a crash-orphaned `running` shard is first projected as\n\t\t// interrupted (running -> pending is illegal in §13.4), then re-armed.\n\t\tif (projections.get(shardId)?.state === \"running\") {\n\t\t\tapplyTransition(input, projections, shardId, \"interrupted\", { reasonCode: \"recovery.orphaned\", now });\n\t\t}\n\t\tapplyTransition(input, projections, shardId, \"pending\", { reasonCode: \"recovery.rearm\", now });\n\t}\n\n\t// Dependency-wave scheduler: launch ready shards up to the recomputed width.\n\tconst remaining = new Set(\n\t\tinput.plan.shards.map((shard) => shard.shardId).filter((id) => projections.get(id)?.state !== \"passed\"),\n\t);\n\tlet active = 0;\n\tlet wake: (() => void) | undefined;\n\tconst waitTurn = () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\twake = resolve;\n\t\t});\n\tconst running = new Map<string, Promise<void>>();\n\n\twhile (remaining.size > 0 && !input.signal?.aborted) {\n\t\tconst ready = [...remaining].filter((id) => {\n\t\t\tconst projection = projections.get(id);\n\t\t\tif (projection?.state !== \"pending\") return false;\n\t\t\tconst spec = shardById(input.plan, id);\n\t\t\treturn spec.dependencyIds.every((dep) => projections.get(dep)?.state === \"passed\");\n\t\t});\n\t\tconst launchable = ready.slice(0, Math.max(0, effectiveConcurrency - active));\n\t\tif (launchable.length === 0) {\n\t\t\tif (running.size === 0) break; // deadlock = blocked dependents; aggregate reports them\n\t\t\tawait Promise.race([...running.values(), waitTurn()]);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const shardId of launchable) {\n\t\t\tremaining.delete(shardId);\n\t\t\tactive += 1;\n\t\t\tconst task = runOneShard(input, projections, shardId, now).finally(() => {\n\t\t\t\tactive -= 1;\n\t\t\t\trunning.delete(shardId);\n\t\t\t\twake?.();\n\t\t\t});\n\t\t\trunning.set(shardId, task);\n\t\t}\n\t}\n\tawait Promise.all(running.values());\n\n\treturn aggregate(input, projections, effectiveConcurrency, now, input.signal?.aborted ? [\"run.aborted\"] : []);\n}\n\nfunction aggregate(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: ReadonlyMap<string, WorkloadShardProjection>,\n\teffectiveConcurrency: number,\n\tnow: () => Date,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: 0,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\tconst shards: ShardResultSummary[] = input.plan.shards.map((shard) => {\n\t\tconst projection = projections.get(shard.shardId);\n\t\tconst state = projection?.state ?? \"pending\";\n\t\tcounts[state] += 1;\n\t\treturn {\n\t\t\tshardId: shard.shardId,\n\t\t\tstate,\n\t\t\tattempt: projection?.attempt ?? 0,\n\t\t\tevidenceRefs: projection?.evidenceRefs ?? [],\n\t\t\t...(projection?.reasonCode !== undefined ? { reasonCode: projection.reasonCode } : {}),\n\t\t};\n\t});\n\tconst verdict = aggregateVerdict(counts, input.plan.shards.length, extraReasons);\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict,\n\t\treasonCodes: extraReasons,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards,\n\t\teffectiveConcurrency,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\nfunction blockedEvidence(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tnow: () => Date,\n\treasonCodes: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: input.plan.shards.length,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict: \"blocked\",\n\t\treasonCodes,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards: input.plan.shards.map((shard) => ({\n\t\t\tshardId: shard.shardId,\n\t\t\tstate: \"pending\" as const,\n\t\t\tattempt: 0,\n\t\t\tevidenceRefs: [],\n\t\t})),\n\t\teffectiveConcurrency: 0,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\n/** §13.6: \"passed\" requires EVERY shard to hold terminal passed evidence. */\nfunction aggregateVerdict(\n\tcounts: Readonly<Record<WorkloadShardState, number>>,\n\tshardCount: number,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence[\"verdict\"] {\n\tif (counts.passed === shardCount) return \"passed\";\n\tif (counts.aborted > 0 || extraReasons.includes(\"run.aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workload-shard-executor.js","sourceRoot":"","sources":["../../src/core/workload-shard-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner } from \"./workload-shard-execution-types.ts\";\nimport {\n\tplanShardResume,\n\treduceShardRecords,\n\tvalidateWorkloadShardPlan,\n\ttype WorkloadShardProjection,\n\ttype WorkloadShardState,\n} from \"./workload-shard-plan.ts\";\nimport { applyTransition, runOneShard, shardById } from \"./workload-shard-runner.ts\";\nimport { WorkloadShardJournalError, type WorkloadShardStore } from \"./workload-shard-store.ts\";\n\n// The contract lives in `workload-shard-execution-types.ts` so the runner can\n// name its own parameter type without importing this module back.\nexport type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner };\n\n/**\n * Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).\n *\n * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state\n * machine: passed shards are terminal and never re-run (§13.5 step 3),\n * crash-orphaned `running` shards are recovered through `pending` re-arm\n * records, concurrency is recomputed from the CURRENT admission decision\n * (§13.5 step 6) plus the shared permit pool, and completion produces an\n * aggregate evidence receipt (§13.6) — an observation input for\n * `evaluateTask()`, never a task verdict by itself.\n *\n * Fail-closed rules (§21): a corrupt journal is quarantined and the run is\n * `blocked`; a journal written for a different plan is `blocked`; an invalid\n * plan never starts. The executor never rewrites shard commands (§12.3) —\n * it only runs what the plan's descriptors already describe via the\n * injected runner.\n */\n\nexport interface ShardResultSummary {\n\treadonly shardId: string;\n\treadonly state: WorkloadShardState;\n\treadonly attempt: number;\n\treadonly evidenceRefs: readonly string[];\n\treadonly reasonCode?: string;\n}\n\n/** §13.6 aggregate evidence receipt; §15.1 observation kind. */\nexport interface WorkloadShardAggregateEvidence {\n\treadonly kind: \"workload_shard_result.v1\";\n\treadonly planId: string;\n\treadonly promptRunId: string;\n\treadonly commandDigest: string;\n\treadonly strategy: string;\n\treadonly verdict: \"passed\" | \"failed\" | \"aborted\" | \"blocked\";\n\treadonly reasonCodes: readonly string[];\n\treadonly shardCount: number;\n\treadonly counts: Readonly<Record<WorkloadShardState, number>>;\n\treadonly shards: readonly ShardResultSummary[];\n\treadonly effectiveConcurrency: number;\n\treadonly completedAt: string;\n}\n\nexport async function executeWorkloadShardPlan(\n\tinput: ExecuteWorkloadShardPlanInput,\n): Promise<WorkloadShardAggregateEvidence> {\n\tconst now = input.now ?? (() => new Date());\n\tconst planErrors = validateWorkloadShardPlan(input.plan);\n\tif (planErrors.length > 0) {\n\t\treturn blockedEvidence(input, now, [\"plan.invalid\", ...planErrors.slice(0, 3)]);\n\t}\n\n\tlet journal: ReturnType<WorkloadShardStore[\"load\"]>;\n\ttry {\n\t\tjournal = input.store.load();\n\t} catch (error) {\n\t\t// §21 fail closed: corrupt evidence is quarantined, never silently rebuilt.\n\t\tif (error instanceof WorkloadShardJournalError) {\n\t\t\tinput.store.quarantine();\n\t\t\treturn blockedEvidence(input, now, [`journal.${error.code}`]);\n\t\t}\n\t\tthrow error;\n\t}\n\tif (journal.plan === null) {\n\t\tinput.store.appendPlan(input.plan);\n\t} else if (journal.plan.planId !== input.plan.planId || journal.plan.commandDigest !== input.plan.commandDigest) {\n\t\treturn blockedEvidence(input, now, [\"plan.mismatch\"]);\n\t}\n\n\tconst projections = new Map<string, WorkloadShardProjection>(\n\t\tjournal.projections ?? reduceShardRecords(input.plan, []),\n\t);\n\tconst effectiveConcurrency = Math.max(1, Math.min(input.plan.maxConcurrency, input.decision.maxHeavyProcesses));\n\n\t// §13.5 steps 2-4: re-arm recoverable shards through explicit pending records.\n\tconst resume = planShardResume(input.plan, projections);\n\tconst rearm = [\n\t\t...resume.interrupted,\n\t\t...(input.retryFailed ? resume.retryable : []),\n\t\t...((input.resumeAborted ?? true) ? resume.resumable : []),\n\t];\n\tfor (const shardId of rearm) {\n\t\t// §13.5 step 2: a crash-orphaned `running` shard is first projected as\n\t\t// interrupted (running -> pending is illegal in §13.4), then re-armed.\n\t\tif (projections.get(shardId)?.state === \"running\") {\n\t\t\tapplyTransition(input, projections, shardId, \"interrupted\", { reasonCode: \"recovery.orphaned\", now });\n\t\t}\n\t\tapplyTransition(input, projections, shardId, \"pending\", { reasonCode: \"recovery.rearm\", now });\n\t}\n\n\t// Dependency-wave scheduler: launch ready shards up to the recomputed width.\n\tconst remaining = new Set(\n\t\tinput.plan.shards.map((shard) => shard.shardId).filter((id) => projections.get(id)?.state !== \"passed\"),\n\t);\n\tlet active = 0;\n\tlet wake: (() => void) | undefined;\n\tconst waitTurn = () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\twake = resolve;\n\t\t});\n\tconst running = new Map<string, Promise<void>>();\n\n\twhile (remaining.size > 0 && !input.signal?.aborted) {\n\t\tconst ready = [...remaining].filter((id) => {\n\t\t\tconst projection = projections.get(id);\n\t\t\tif (projection?.state !== \"pending\") return false;\n\t\t\tconst spec = shardById(input.plan, id);\n\t\t\treturn spec.dependencyIds.every((dep) => projections.get(dep)?.state === \"passed\");\n\t\t});\n\t\tconst launchable = ready.slice(0, Math.max(0, effectiveConcurrency - active));\n\t\tif (launchable.length === 0) {\n\t\t\tif (running.size === 0) break; // deadlock = blocked dependents; aggregate reports them\n\t\t\tawait Promise.race([...running.values(), waitTurn()]);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const shardId of launchable) {\n\t\t\tremaining.delete(shardId);\n\t\t\tactive += 1;\n\t\t\tconst task = runOneShard(input, projections, shardId, now).finally(() => {\n\t\t\t\tactive -= 1;\n\t\t\t\trunning.delete(shardId);\n\t\t\t\twake?.();\n\t\t\t});\n\t\t\trunning.set(shardId, task);\n\t\t}\n\t}\n\tawait Promise.all(running.values());\n\n\treturn aggregate(input, projections, effectiveConcurrency, now, input.signal?.aborted ? [\"run.aborted\"] : []);\n}\n\nfunction aggregate(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: ReadonlyMap<string, WorkloadShardProjection>,\n\teffectiveConcurrency: number,\n\tnow: () => Date,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: 0,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\tconst shards: ShardResultSummary[] = input.plan.shards.map((shard) => {\n\t\tconst projection = projections.get(shard.shardId);\n\t\tconst state = projection?.state ?? \"pending\";\n\t\tcounts[state] += 1;\n\t\treturn {\n\t\t\tshardId: shard.shardId,\n\t\t\tstate,\n\t\t\tattempt: projection?.attempt ?? 0,\n\t\t\tevidenceRefs: projection?.evidenceRefs ?? [],\n\t\t\t...(projection?.reasonCode !== undefined ? { reasonCode: projection.reasonCode } : {}),\n\t\t};\n\t});\n\tconst verdict = aggregateVerdict(counts, input.plan.shards.length, extraReasons);\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict,\n\t\treasonCodes: extraReasons,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards,\n\t\teffectiveConcurrency,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\nfunction blockedEvidence(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tnow: () => Date,\n\treasonCodes: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: input.plan.shards.length,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict: \"blocked\",\n\t\treasonCodes,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards: input.plan.shards.map((shard) => ({\n\t\t\tshardId: shard.shardId,\n\t\t\tstate: \"pending\" as const,\n\t\t\tattempt: 0,\n\t\t\tevidenceRefs: [],\n\t\t})),\n\t\teffectiveConcurrency: 0,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\n/** §13.6: \"passed\" requires EVERY shard to hold terminal passed evidence. */\nfunction aggregateVerdict(\n\tcounts: Readonly<Record<WorkloadShardState, number>>,\n\tshardCount: number,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence[\"verdict\"] {\n\tif (counts.passed === shardCount) return \"passed\";\n\tif (counts.aborted > 0 || extraReasons.includes(\"run.aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExecuteWorkloadShardPlanInput } from "./workload-shard-
|
|
1
|
+
import type { ExecuteWorkloadShardPlanInput } from "./workload-shard-execution-types.ts";
|
|
2
2
|
import type { WorkloadShardPlan, WorkloadShardProjection, WorkloadShardSpec, WorkloadShardState } from "./workload-shard-plan.ts";
|
|
3
3
|
export declare function runOneShard(input: ExecuteWorkloadShardPlanInput, projections: Map<string, WorkloadShardProjection>, shardId: string, now: () => Date): Promise<void>;
|
|
4
4
|
export declare function applyTransition(input: ExecuteWorkloadShardPlanInput, projections: Map<string, WorkloadShardProjection>, shardId: string, state: WorkloadShardState, options: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-shard-runner.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"workload-shard-runner.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,KAAK,EACX,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,0BAA0B,CAAC;AAElC,wBAAsB,WAAW,CAChC,KAAK,EAAE,6BAA6B,EACpC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,EACjD,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,IAAI,GACb,OAAO,CAAC,IAAI,CAAC,CAkDf;AAED,wBAAgB,eAAe,CAC9B,KAAK,EAAE,6BAA6B,EACpC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,EACjD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE;IACR,QAAQ,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B,GACC,IAAI,CAuBN;AAYD,wBAAgB,SAAS,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAMrF","sourcesContent":["import { WorkloadPermitError } from \"./workload-permit-pool.ts\";\nimport type { ExecuteWorkloadShardPlanInput } from \"./workload-shard-execution-types.ts\";\nimport type {\n\tWorkloadShardPlan,\n\tWorkloadShardProjection,\n\tWorkloadShardSpec,\n\tWorkloadShardState,\n} from \"./workload-shard-plan.ts\";\n\nexport async function runOneShard(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: Map<string, WorkloadShardProjection>,\n\tshardId: string,\n\tnow: () => Date,\n): Promise<void> {\n\tconst shard = shardById(input.plan, shardId);\n\tlet releasePermit: (() => void) | undefined;\n\tif (input.permitPool) {\n\t\ttry {\n\t\t\tconst permit = await input.permitPool.acquire({\n\t\t\t\trequestId: `shard-${input.plan.planId}-${shardId}`,\n\t\t\t\tpromptRunId: input.plan.promptRunId,\n\t\t\t\tworkloadClass: \"heavy\",\n\t\t\t\tweight: 1,\n\t\t\t\tsignal: input.signal,\n\t\t\t\ttimeoutMs: input.permitWaitTimeoutMs ?? 120_000,\n\t\t\t});\n\t\t\treleasePermit = () => permit.release();\n\t\t} catch (error) {\n\t\t\tconst aborted = error instanceof WorkloadPermitError && error.code === \"aborted\";\n\t\t\t// Never ran: stays pending; an aborted wait is not a shard failure.\n\t\t\tif (!aborted) {\n\t\t\t\tapplyTransition(input, projections, shardId, \"running\", { now });\n\t\t\t\tapplyTransition(input, projections, shardId, \"failed\", { reasonCode: \"permit.unavailable\", now });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n\tconst startedAt = now().toISOString();\n\tapplyTransition(input, projections, shardId, \"running\", { now, startedAt });\n\ttry {\n\t\tconst result = await input.runner({\n\t\t\tshard,\n\t\t\tattempt: projections.get(shardId)?.attempt ?? 1,\n\t\t\tsignal: input.signal,\n\t\t});\n\t\tconst state = terminalStateFor(input.signal, result.exitCode);\n\t\tapplyTransition(input, projections, shardId, state, {\n\t\t\tnow,\n\t\t\tstartedAt,\n\t\t\tevidenceRefs: [`exit-code:${result.exitCode}`, ...(result.evidenceRefs ?? [])],\n\t\t\treasonCode: terminalReasonFor(state, result.exitCode),\n\t\t});\n\t} catch (error) {\n\t\tconst state: WorkloadShardState = input.signal?.aborted ? \"aborted\" : \"failed\";\n\t\tapplyTransition(input, projections, shardId, state, {\n\t\t\tnow,\n\t\t\tstartedAt,\n\t\t\treasonCode: state === \"aborted\" ? \"run.aborted\" : \"runner.error\",\n\t\t\tevidenceRefs: [`error:${String(error).slice(0, 120)}`],\n\t\t});\n\t} finally {\n\t\treleasePermit?.();\n\t}\n}\n\nexport function applyTransition(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: Map<string, WorkloadShardProjection>,\n\tshardId: string,\n\tstate: WorkloadShardState,\n\toptions: {\n\t\treadonly now: () => Date;\n\t\treadonly startedAt?: string;\n\t\treadonly evidenceRefs?: readonly string[];\n\t\treadonly reasonCode?: string;\n\t},\n): void {\n\tconst current = projections.get(shardId);\n\tif (current === undefined) return;\n\tconst attempt = state === \"running\" ? current.attempt + 1 : current.attempt;\n\tconst terminal = state !== \"pending\" && state !== \"running\";\n\tinput.store.appendTransition({\n\t\tschemaVersion: 1,\n\t\tplanId: input.plan.planId,\n\t\tshardId,\n\t\tattempt,\n\t\tstate,\n\t\t...(options.startedAt !== undefined && state === \"running\" ? { startedAt: options.startedAt } : {}),\n\t\t...(terminal ? { finishedAt: options.now().toISOString() } : {}),\n\t\tevidenceRefs: options.evidenceRefs ?? [],\n\t\t...(options.reasonCode !== undefined ? { reasonCode: options.reasonCode } : {}),\n\t});\n\tprojections.set(shardId, {\n\t\tshardId,\n\t\tstate,\n\t\tattempt,\n\t\tevidenceRefs: options.evidenceRefs?.length ? options.evidenceRefs : current.evidenceRefs,\n\t\treasonCode: options.reasonCode ?? (state === \"pending\" ? undefined : current.reasonCode),\n\t});\n}\n\nfunction terminalStateFor(signal: AbortSignal | undefined, exitCode: number): WorkloadShardState {\n\tif (signal?.aborted) return \"aborted\";\n\treturn exitCode === 0 ? \"passed\" : \"failed\";\n}\n\nfunction terminalReasonFor(state: WorkloadShardState, exitCode: number): string | undefined {\n\tif (state === \"failed\") return `exit.${exitCode}`;\n\treturn state === \"aborted\" ? \"run.aborted\" : undefined;\n}\n\nexport function shardById(plan: WorkloadShardPlan, shardId: string): WorkloadShardSpec {\n\tconst shard = plan.shards.find((candidate) => candidate.shardId === shardId);\n\tif (shard === undefined) {\n\t\tthrow new Error(`shard ${shardId} not in plan ${plan.planId}`);\n\t}\n\treturn shard;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-shard-runner.js","sourceRoot":"","sources":["../../src/core/workload-shard-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { WorkloadPermitError } from \"./workload-permit-pool.ts\";\nimport type { ExecuteWorkloadShardPlanInput } from \"./workload-shard-
|
|
1
|
+
{"version":3,"file":"workload-shard-runner.js","sourceRoot":"","sources":["../../src/core/workload-shard-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { WorkloadPermitError } from \"./workload-permit-pool.ts\";\nimport type { ExecuteWorkloadShardPlanInput } from \"./workload-shard-execution-types.ts\";\nimport type {\n\tWorkloadShardPlan,\n\tWorkloadShardProjection,\n\tWorkloadShardSpec,\n\tWorkloadShardState,\n} from \"./workload-shard-plan.ts\";\n\nexport async function runOneShard(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: Map<string, WorkloadShardProjection>,\n\tshardId: string,\n\tnow: () => Date,\n): Promise<void> {\n\tconst shard = shardById(input.plan, shardId);\n\tlet releasePermit: (() => void) | undefined;\n\tif (input.permitPool) {\n\t\ttry {\n\t\t\tconst permit = await input.permitPool.acquire({\n\t\t\t\trequestId: `shard-${input.plan.planId}-${shardId}`,\n\t\t\t\tpromptRunId: input.plan.promptRunId,\n\t\t\t\tworkloadClass: \"heavy\",\n\t\t\t\tweight: 1,\n\t\t\t\tsignal: input.signal,\n\t\t\t\ttimeoutMs: input.permitWaitTimeoutMs ?? 120_000,\n\t\t\t});\n\t\t\treleasePermit = () => permit.release();\n\t\t} catch (error) {\n\t\t\tconst aborted = error instanceof WorkloadPermitError && error.code === \"aborted\";\n\t\t\t// Never ran: stays pending; an aborted wait is not a shard failure.\n\t\t\tif (!aborted) {\n\t\t\t\tapplyTransition(input, projections, shardId, \"running\", { now });\n\t\t\t\tapplyTransition(input, projections, shardId, \"failed\", { reasonCode: \"permit.unavailable\", now });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n\tconst startedAt = now().toISOString();\n\tapplyTransition(input, projections, shardId, \"running\", { now, startedAt });\n\ttry {\n\t\tconst result = await input.runner({\n\t\t\tshard,\n\t\t\tattempt: projections.get(shardId)?.attempt ?? 1,\n\t\t\tsignal: input.signal,\n\t\t});\n\t\tconst state = terminalStateFor(input.signal, result.exitCode);\n\t\tapplyTransition(input, projections, shardId, state, {\n\t\t\tnow,\n\t\t\tstartedAt,\n\t\t\tevidenceRefs: [`exit-code:${result.exitCode}`, ...(result.evidenceRefs ?? [])],\n\t\t\treasonCode: terminalReasonFor(state, result.exitCode),\n\t\t});\n\t} catch (error) {\n\t\tconst state: WorkloadShardState = input.signal?.aborted ? \"aborted\" : \"failed\";\n\t\tapplyTransition(input, projections, shardId, state, {\n\t\t\tnow,\n\t\t\tstartedAt,\n\t\t\treasonCode: state === \"aborted\" ? \"run.aborted\" : \"runner.error\",\n\t\t\tevidenceRefs: [`error:${String(error).slice(0, 120)}`],\n\t\t});\n\t} finally {\n\t\treleasePermit?.();\n\t}\n}\n\nexport function applyTransition(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: Map<string, WorkloadShardProjection>,\n\tshardId: string,\n\tstate: WorkloadShardState,\n\toptions: {\n\t\treadonly now: () => Date;\n\t\treadonly startedAt?: string;\n\t\treadonly evidenceRefs?: readonly string[];\n\t\treadonly reasonCode?: string;\n\t},\n): void {\n\tconst current = projections.get(shardId);\n\tif (current === undefined) return;\n\tconst attempt = state === \"running\" ? current.attempt + 1 : current.attempt;\n\tconst terminal = state !== \"pending\" && state !== \"running\";\n\tinput.store.appendTransition({\n\t\tschemaVersion: 1,\n\t\tplanId: input.plan.planId,\n\t\tshardId,\n\t\tattempt,\n\t\tstate,\n\t\t...(options.startedAt !== undefined && state === \"running\" ? { startedAt: options.startedAt } : {}),\n\t\t...(terminal ? { finishedAt: options.now().toISOString() } : {}),\n\t\tevidenceRefs: options.evidenceRefs ?? [],\n\t\t...(options.reasonCode !== undefined ? { reasonCode: options.reasonCode } : {}),\n\t});\n\tprojections.set(shardId, {\n\t\tshardId,\n\t\tstate,\n\t\tattempt,\n\t\tevidenceRefs: options.evidenceRefs?.length ? options.evidenceRefs : current.evidenceRefs,\n\t\treasonCode: options.reasonCode ?? (state === \"pending\" ? undefined : current.reasonCode),\n\t});\n}\n\nfunction terminalStateFor(signal: AbortSignal | undefined, exitCode: number): WorkloadShardState {\n\tif (signal?.aborted) return \"aborted\";\n\treturn exitCode === 0 ? \"passed\" : \"failed\";\n}\n\nfunction terminalReasonFor(state: WorkloadShardState, exitCode: number): string | undefined {\n\tif (state === \"failed\") return `exit.${exitCode}`;\n\treturn state === \"aborted\" ? \"run.aborted\" : undefined;\n}\n\nexport function shardById(plan: WorkloadShardPlan, shardId: string): WorkloadShardSpec {\n\tconst shard = plan.shards.find((candidate) => candidate.shardId === shardId);\n\tif (shard === undefined) {\n\t\tthrow new Error(`shard ${shardId} not in plan ${plan.planId}`);\n\t}\n\treturn shard;\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workload classification vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* These declarations sat in `workload-classifier.ts`, which imports the family
|
|
5
|
+
* matcher, while the matcher imported the declarations back — a two-module
|
|
6
|
+
* import cycle. Neither module was wrong to want the other: the classifier owns
|
|
7
|
+
* the decision, the matcher owns the command-family table, and both speak the
|
|
8
|
+
* same vocabulary. Giving the vocabulary its own module lets both depend on it
|
|
9
|
+
* without depending on each other.
|
|
10
|
+
*
|
|
11
|
+
* Types only, no imports: this module is the bottom of that dependency chain
|
|
12
|
+
* and must stay there.
|
|
13
|
+
*/
|
|
14
|
+
export type WorkloadClass = "light" | "io" | "cpu" | "memory" | "heavy" | "unknown";
|
|
15
|
+
export type WorkloadCommandFamily = "node-test" | "node-build" | "typescript" | "go-test" | "rust-build" | "container-build" | "monorepo" | "archive" | "generic-process" | "unknown";
|
|
16
|
+
export type WorkloadShellComplexity = "simple-argv" | "complex-shell";
|
|
17
|
+
export interface WorkloadClassification {
|
|
18
|
+
readonly workloadClass: WorkloadClass;
|
|
19
|
+
readonly commandFamily: WorkloadCommandFamily;
|
|
20
|
+
readonly complexity: WorkloadShellComplexity;
|
|
21
|
+
readonly safeToAutoShard: boolean;
|
|
22
|
+
readonly reasonCodes: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=workload-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-types.d.ts","sourceRoot":"","sources":["../../src/core/workload-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpF,MAAM,MAAM,qBAAqB,GAC9B,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,UAAU,GACV,SAAS,GACT,iBAAiB,GACjB,SAAS,CAAC;AAEb,MAAM,MAAM,uBAAuB,GAAG,aAAa,GAAG,eAAe,CAAC;AAEtE,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC;IAC7C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC","sourcesContent":["/**\n * Workload classification vocabulary.\n *\n * These declarations sat in `workload-classifier.ts`, which imports the family\n * matcher, while the matcher imported the declarations back — a two-module\n * import cycle. Neither module was wrong to want the other: the classifier owns\n * the decision, the matcher owns the command-family table, and both speak the\n * same vocabulary. Giving the vocabulary its own module lets both depend on it\n * without depending on each other.\n *\n * Types only, no imports: this module is the bottom of that dependency chain\n * and must stay there.\n */\n\nexport type WorkloadClass = \"light\" | \"io\" | \"cpu\" | \"memory\" | \"heavy\" | \"unknown\";\n\nexport type WorkloadCommandFamily =\n\t| \"node-test\"\n\t| \"node-build\"\n\t| \"typescript\"\n\t| \"go-test\"\n\t| \"rust-build\"\n\t| \"container-build\"\n\t| \"monorepo\"\n\t| \"archive\"\n\t| \"generic-process\"\n\t| \"unknown\";\n\nexport type WorkloadShellComplexity = \"simple-argv\" | \"complex-shell\";\n\nexport interface WorkloadClassification {\n\treadonly workloadClass: WorkloadClass;\n\treadonly commandFamily: WorkloadCommandFamily;\n\treadonly complexity: WorkloadShellComplexity;\n\treadonly safeToAutoShard: boolean;\n\treadonly reasonCodes: readonly string[];\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workload classification vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* These declarations sat in `workload-classifier.ts`, which imports the family
|
|
5
|
+
* matcher, while the matcher imported the declarations back — a two-module
|
|
6
|
+
* import cycle. Neither module was wrong to want the other: the classifier owns
|
|
7
|
+
* the decision, the matcher owns the command-family table, and both speak the
|
|
8
|
+
* same vocabulary. Giving the vocabulary its own module lets both depend on it
|
|
9
|
+
* without depending on each other.
|
|
10
|
+
*
|
|
11
|
+
* Types only, no imports: this module is the bottom of that dependency chain
|
|
12
|
+
* and must stay there.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=workload-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-types.js","sourceRoot":"","sources":["../../src/core/workload-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG","sourcesContent":["/**\n * Workload classification vocabulary.\n *\n * These declarations sat in `workload-classifier.ts`, which imports the family\n * matcher, while the matcher imported the declarations back — a two-module\n * import cycle. Neither module was wrong to want the other: the classifier owns\n * the decision, the matcher owns the command-family table, and both speak the\n * same vocabulary. Giving the vocabulary its own module lets both depend on it\n * without depending on each other.\n *\n * Types only, no imports: this module is the bottom of that dependency chain\n * and must stay there.\n */\n\nexport type WorkloadClass = \"light\" | \"io\" | \"cpu\" | \"memory\" | \"heavy\" | \"unknown\";\n\nexport type WorkloadCommandFamily =\n\t| \"node-test\"\n\t| \"node-build\"\n\t| \"typescript\"\n\t| \"go-test\"\n\t| \"rust-build\"\n\t| \"container-build\"\n\t| \"monorepo\"\n\t| \"archive\"\n\t| \"generic-process\"\n\t| \"unknown\";\n\nexport type WorkloadShellComplexity = \"simple-argv\" | \"complex-shell\";\n\nexport interface WorkloadClassification {\n\treadonly workloadClass: WorkloadClass;\n\treadonly commandFamily: WorkloadCommandFamily;\n\treadonly complexity: WorkloadShellComplexity;\n\treadonly safeToAutoShard: boolean;\n\treadonly reasonCodes: readonly string[];\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type Age
|
|
|
10
10
|
export { type ApiKeyCredential, type AuthCredential, type AuthStatus, AuthStorage, type AuthStorageBackend, FileAuthStorageBackend, InMemoryAuthStorageBackend, type OAuthCredential, } from "./core/auth-storage.ts";
|
|
11
11
|
export { type ApiAction, ApiBroker, type ApiMethod, type ApiOutcome, AUTOPILOT_MAX, type AutomationHarnessScoreInput, AutomationHarnessScorer, type AutomationScoreBreakdown, type AutomationTrace, type AutomationTraceAction, type AutomationTraceContextPlan, type AutomationTraceEnvApiUse, type AutonomyProfile, type BrokerFetcher, type BrokerFetchRequest, type BrokerFetchResponse, type Capability, canonicalHash, classifyEnvKey, DynamicToolPortfolioOptimizer, EnvBroker, type EnvBrokerLedger, type EnvMode, type EnvRecord, type EnvResolutionRequest, type EnvUseEvent, type EvidenceActor, type EvidenceEvent, type EvidenceEventInput, EvidenceLedger, type EvidenceOutcome, type EvidencePointer, type ExecutionStrategy, type Postcondition, PostconditionVerifier, type RiskLevel, redactForModel, type Sensitivity, strategyForRisk, ToolExecutionBroker, type ToolExecutionCandidate, type ToolExecutionChoice, type ToolExecutionNeed, type VerificationContext, type VerificationResult, } from "./core/automation/index.ts";
|
|
12
12
|
export { type BranchPreparation, type BranchSummaryResult, type CollectEntriesResult, type CompactionBarrierResult, type CompactionCommitDecision, type CompactionEnvelope, type CompactionHysteresisConfig, type CompactionHysteresisState, type CompactionResult, type CompactionTransaction, type CutPointResult, calculateContextTokens, collectEntriesForBranchSummary, compact, createCompactionEnvelope, createCompactionHysteresisConfig, createCompactionHysteresisState, createCompactionSourceIdentity, createCompactionTransaction, createSessionRevisionToken, DEFAULT_COMPACTION_SETTINGS, decideCompactionCommit, estimateTokens, evaluateCompactionBarrier, type FileOperations, findCutPoint, findTurnStartIndex, type GenerateBranchSummaryOptions, generateBranchSummary, generateSummary, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, stepCompactionHysteresis, validateCompactionEnvelope, } from "./core/compaction/index.ts";
|
|
13
|
-
export { applyContextCacheInvalidation, buildContextBudgetMaterializedRepresentationCacheKeyV2, buildContextBudgetPlanCacheKeyV2, CONTEXT_BUDGET_POLICY_VERSION_V2, type ContextBudgetCacheProviderV2, type ContextCacheInvalidationEvent, type ContextCacheInvalidationSnapshot, createContextBudgetCacheKeyBaseV2, createContextCacheInvalidationSnapshot, createDiskContextBudgetCacheProviderV2, createMemoryContextBudgetCacheProviderV2, type DiskContextBudgetCacheOptionsV2, DiskContextBudgetCacheProviderV2, planPromptContextBudgetV2, serializeContextCacheSnapshot, } from "./core/context-budget-governor-v2.ts";
|
|
13
|
+
export { applyContextCacheInvalidation, buildContextBudgetMaterializedRepresentationCacheKeyV2, buildContextBudgetPlanCacheKeyV2, CONTEXT_BUDGET_POLICY_VERSION_V2, CONTEXT_BUDGET_SELECTION_POLICY_V2, type ContextBudgetCacheProviderV2, type ContextCacheInvalidationEvent, type ContextCacheInvalidationSnapshot, createContextBudgetCacheKeyBaseV2, createContextCacheInvalidationSnapshot, createDiskContextBudgetCacheProviderV2, createMemoryContextBudgetCacheProviderV2, type DiskContextBudgetCacheOptionsV2, DiskContextBudgetCacheProviderV2, planPromptContextBudgetV2, serializeContextCacheSnapshot, } from "./core/context-budget-governor-v2.ts";
|
|
14
14
|
export { computeReservedTokenBudget, estimateToolResultReserve, ReservedTokenBudgetError, type ReservedTokenBudgetInput, type ReservedTokenBudgetResult, type ToolResultReserveRequest, } from "./core/context-budget-reserved-tokens.ts";
|
|
15
15
|
export { computeDurableGoalGeneration, createDurableGoal, DURABLE_GOAL_CHECKPOINT_SCHEMA_VERSION, DURABLE_GOAL_SCHEMA_VERSION, DURABLE_GOAL_STATUS_VALUES, type DurableGoalCheckpoint, type DurableGoalCheckpointInput, type DurableGoalCommand, DurableGoalError, type DurableGoalErrorCode, type DurableGoalEvidence, type DurableGoalRef, type DurableGoalSnapshot, type DurableGoalStatus, freshDurableGoalEvidence, } from "./core/durable-goal.ts";
|
|
16
16
|
export { createDurableGoalCheckpoint, formatDurableGoalCheckpoint, parseDurableGoalCheckpoint, parseDurableGoalCheckpointCommand, } from "./core/durable-goal-checkpoint.ts";
|