harnery 0.36.0 → 0.38.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/dist/commander.d.ts +9 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +10 -1
- package/dist/commands/admission.d.ts +21 -0
- package/dist/commands/admission.d.ts.map +1 -0
- package/dist/commands/admission.js +565 -0
- package/dist/commands/agents.d.ts +7 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +148 -47
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +73 -2
- package/dist/commands/browse-ai.d.ts +2 -2
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +6 -4
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +360 -21
- package/dist/commands/diagnostics.d.ts +4 -0
- package/dist/commands/diagnostics.d.ts.map +1 -0
- package/dist/commands/diagnostics.js +229 -0
- package/dist/commands/fetch.js +1 -0
- package/dist/commands/files.d.ts +12 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -1
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +4 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +71 -2
- package/dist/commands/qa-record.d.ts +144 -0
- package/dist/commands/qa-record.d.ts.map +1 -0
- package/dist/commands/qa-record.js +0 -0
- package/dist/commands/qa-run.d.ts +8 -0
- package/dist/commands/qa-run.d.ts.map +1 -0
- package/dist/commands/qa-run.js +396 -0
- package/dist/commands/qa-status.d.ts +71 -0
- package/dist/commands/qa-status.d.ts.map +1 -0
- package/dist/commands/qa-status.js +490 -0
- package/dist/commands/qa-verify.d.ts +40 -0
- package/dist/commands/qa-verify.d.ts.map +1 -0
- package/dist/commands/qa-verify.js +180 -0
- package/dist/commands/resources.d.ts +4 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +29 -0
- package/dist/commands/review-pack.d.ts +4 -0
- package/dist/commands/review-pack.d.ts.map +1 -0
- package/dist/commands/review-pack.js +1001 -0
- package/dist/commands/supervisor.d.ts +4 -0
- package/dist/commands/supervisor.d.ts.map +1 -0
- package/dist/commands/supervisor.js +101 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +4 -0
- package/dist/core/agents/cli.js +7 -3
- package/dist/core/agents/health.d.ts +17 -0
- package/dist/core/agents/health.d.ts.map +1 -0
- package/dist/core/agents/health.js +109 -0
- package/dist/core/agents/mailbox.d.ts +92 -0
- package/dist/core/agents/mailbox.d.ts.map +1 -0
- package/dist/core/agents/mailbox.js +325 -0
- package/dist/core/agents/qa-signal.d.ts +111 -0
- package/dist/core/agents/qa-signal.d.ts.map +1 -0
- package/dist/core/agents/qa-signal.js +231 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts +44 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts.map +1 -0
- package/dist/core/agents/reconcile-coordination-v3.js +58 -0
- package/dist/core/agents/render/prompt-context.d.ts +5 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +34 -13
- package/dist/core/agents/render/session-context.d.ts +8 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +34 -3
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +50 -1
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +6 -10
- package/dist/core/agents/session-finalizer-v3.js +4 -1
- package/dist/core/agents/session-name-display.d.ts +20 -5
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +67 -7
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +11 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +17 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +5 -0
- package/dist/core/artifacts/constants.d.ts +1 -1
- package/dist/core/artifacts/constants.js +1 -1
- package/dist/core/artifacts/index.d.ts +82 -6
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +410 -15
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +59 -0
- package/dist/core/diagnostics/advice.d.ts +9 -0
- package/dist/core/diagnostics/advice.d.ts.map +1 -0
- package/dist/core/diagnostics/advice.js +112 -0
- package/dist/core/diagnostics/bundle.d.ts +51 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -0
- package/dist/core/diagnostics/bundle.js +968 -0
- package/dist/core/diagnostics/comparison.d.ts +5 -0
- package/dist/core/diagnostics/comparison.d.ts.map +1 -0
- package/dist/core/diagnostics/comparison.js +444 -0
- package/dist/core/diagnostics/contract.d.ts +245 -0
- package/dist/core/diagnostics/contract.d.ts.map +1 -0
- package/dist/core/diagnostics/contract.js +18 -0
- package/dist/core/diagnostics/identity.d.ts +3 -0
- package/dist/core/diagnostics/identity.d.ts.map +1 -0
- package/dist/core/diagnostics/identity.js +10 -0
- package/dist/core/diagnostics/index.d.ts +8 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +7 -0
- package/dist/core/diagnostics/replay.d.ts +8 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -0
- package/dist/core/diagnostics/replay.js +213 -0
- package/dist/core/diagnostics/sanitize.d.ts +9 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -0
- package/dist/core/diagnostics/sanitize.js +84 -0
- package/dist/core/events/legacy-storage/compression.d.ts +13 -0
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/compression.js +107 -0
- package/dist/core/events/legacy-storage/index.d.ts +1 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/index.js +1 -0
- package/dist/core/events/v3/archive-retention.d.ts +33 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -0
- package/dist/core/events/v3/archive-retention.js +195 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +10 -0
- package/dist/core/events/v3/capabilities.d.ts +1 -1
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +1 -0
- package/dist/core/events/v3/coordination-view.d.ts +3 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +69 -8
- package/dist/core/events/v3/index.d.ts +1 -0
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +13 -2
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +10 -2
- package/dist/core/events/v3/producers/recorder.d.ts +39 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +350 -17
- package/dist/core/hooks/adapter/output.d.ts +8 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +11 -1
- package/dist/core/hooks/cli.js +303 -219
- package/dist/core/hooks/health.d.ts +59 -0
- package/dist/core/hooks/health.d.ts.map +1 -0
- package/dist/core/hooks/health.js +84 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +10 -3
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +4 -1
- package/dist/core/qa-artifacts.d.ts +20 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -0
- package/dist/core/qa-artifacts.js +110 -0
- package/dist/core/resources/contract.d.ts +96 -0
- package/dist/core/resources/contract.d.ts.map +1 -0
- package/dist/core/resources/contract.js +2 -0
- package/dist/core/resources/index.d.ts +6 -0
- package/dist/core/resources/index.d.ts.map +1 -0
- package/dist/core/resources/index.js +5 -0
- package/dist/core/resources/sampler.d.ts +34 -0
- package/dist/core/resources/sampler.d.ts.map +1 -0
- package/dist/core/resources/sampler.js +458 -0
- package/dist/core/resources/service-status.d.ts +3 -0
- package/dist/core/resources/service-status.d.ts.map +1 -0
- package/dist/core/resources/service-status.js +48 -0
- package/dist/core/resources/service.d.ts +26 -0
- package/dist/core/resources/service.d.ts.map +1 -0
- package/dist/core/resources/service.js +292 -0
- package/dist/core/resources/storage.d.ts +13 -0
- package/dist/core/resources/storage.d.ts.map +1 -0
- package/dist/core/resources/storage.js +30 -0
- package/dist/core/storage/atomic-json.d.ts +3 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -0
- package/dist/core/storage/atomic-json.js +15 -0
- package/dist/core/storage/builtins.d.ts.map +1 -1
- package/dist/core/storage/builtins.js +45 -6
- package/dist/core/storage/logger.d.ts +2 -0
- package/dist/core/storage/logger.d.ts.map +1 -1
- package/dist/core/storage/logger.js +2 -0
- package/dist/core/storage/query.d.ts +14 -0
- package/dist/core/storage/query.d.ts.map +1 -1
- package/dist/core/storage/query.js +51 -0
- package/dist/core/supervisor/activity.d.ts +4 -0
- package/dist/core/supervisor/activity.d.ts.map +1 -0
- package/dist/core/supervisor/activity.js +141 -0
- package/dist/core/supervisor/contract.d.ts +268 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -0
- package/dist/core/supervisor/contract.js +35 -0
- package/dist/core/supervisor/explanations.d.ts +4 -0
- package/dist/core/supervisor/explanations.d.ts.map +1 -0
- package/dist/core/supervisor/explanations.js +71 -0
- package/dist/core/supervisor/findings.d.ts +20 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -0
- package/dist/core/supervisor/findings.js +399 -0
- package/dist/core/supervisor/history.d.ts +9 -0
- package/dist/core/supervisor/history.d.ts.map +1 -0
- package/dist/core/supervisor/history.js +46 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts +14 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-alerts.js +70 -0
- package/dist/core/supervisor/hook-health-storage.d.ts +5 -0
- package/dist/core/supervisor/hook-health-storage.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-storage.js +24 -0
- package/dist/core/supervisor/hook-health.d.ts +72 -0
- package/dist/core/supervisor/hook-health.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health.js +203 -0
- package/dist/core/supervisor/hooks.d.ts +10 -0
- package/dist/core/supervisor/hooks.d.ts.map +1 -0
- package/dist/core/supervisor/hooks.js +28 -0
- package/dist/core/supervisor/index.d.ts +15 -0
- package/dist/core/supervisor/index.d.ts.map +1 -0
- package/dist/core/supervisor/index.js +14 -0
- package/dist/core/supervisor/log-feed.d.ts +9 -0
- package/dist/core/supervisor/log-feed.d.ts.map +1 -0
- package/dist/core/supervisor/log-feed.js +103 -0
- package/dist/core/supervisor/service.d.ts +29 -0
- package/dist/core/supervisor/service.d.ts.map +1 -0
- package/dist/core/supervisor/service.js +450 -0
- package/dist/core/supervisor/services.d.ts +11 -0
- package/dist/core/supervisor/services.d.ts.map +1 -0
- package/dist/core/supervisor/services.js +155 -0
- package/dist/core/supervisor/status.d.ts +3 -0
- package/dist/core/supervisor/status.d.ts.map +1 -0
- package/dist/core/supervisor/status.js +48 -0
- package/dist/core/supervisor/storage.d.ts +30 -0
- package/dist/core/supervisor/storage.d.ts.map +1 -0
- package/dist/core/supervisor/storage.js +73 -0
- package/dist/core/supervisor/timeline.d.ts +3 -0
- package/dist/core/supervisor/timeline.d.ts.map +1 -0
- package/dist/core/supervisor/timeline.js +87 -0
- package/dist/core/workflow/admission.d.ts +23 -0
- package/dist/core/workflow/admission.d.ts.map +1 -0
- package/dist/core/workflow/admission.js +136 -0
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +77 -2
- package/dist/core/workflow/index.d.ts +3 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -1
- package/dist/core/workflow/proof.d.ts +2 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +39 -1
- package/dist/core/workflow/run-state.d.ts +3 -2
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +8 -1
- package/dist/core/workflow/types.d.ts +33 -1
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +2 -1
- package/dist/lib/admission.d.ts +71 -0
- package/dist/lib/admission.d.ts.map +1 -0
- package/dist/lib/admission.js +264 -0
- package/dist/lib/agent-browser/client.d.ts +1 -1
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +1 -5
- package/dist/lib/browser/capture-fidelity.d.ts +39 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -0
- package/dist/lib/browser/capture-fidelity.js +84 -0
- package/dist/lib/browser/client.d.ts +46 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +168 -9
- package/dist/lib/browser/critique.d.ts +38 -1
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +34 -6
- package/dist/lib/browser/index.d.ts +5 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +4 -0
- package/dist/lib/browser/page-review-judge.d.ts +64 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -0
- package/dist/lib/browser/page-review-judge.js +270 -0
- package/dist/lib/browser/page-review-pack.d.ts +613 -0
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -0
- package/dist/lib/browser/page-review-pack.js +1751 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +377 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
- package/dist/lib/browser/qa-run-contracts.js +361 -0
- package/dist/lib/browser/qa-run.d.ts +141 -0
- package/dist/lib/browser/qa-run.d.ts.map +1 -0
- package/dist/lib/browser/qa-run.js +1283 -0
- package/dist/lib/browser/request-diagnostics.d.ts +13 -0
- package/dist/lib/browser/request-diagnostics.d.ts.map +1 -0
- package/dist/lib/browser/request-diagnostics.js +18 -0
- package/dist/lib/browser/tiling.d.ts +19 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +28 -0
- package/dist/lib/cookies/client.d.ts +9 -0
- package/dist/lib/cookies/client.d.ts.map +1 -1
- package/dist/lib/cookies/client.js +197 -44
- package/dist/lib/cookies/extra.d.ts +18 -0
- package/dist/lib/cookies/extra.d.ts.map +1 -0
- package/dist/lib/cookies/extra.js +14 -0
- package/dist/lib/cookies/index.d.ts +2 -1
- package/dist/lib/cookies/index.d.ts.map +1 -1
- package/dist/lib/cookies/index.js +2 -1
- package/dist/lib/coord-root-id.d.ts +9 -0
- package/dist/lib/coord-root-id.d.ts.map +1 -0
- package/dist/lib/coord-root-id.js +17 -0
- package/dist/lib/durable-job.d.ts +124 -0
- package/dist/lib/durable-job.d.ts.map +1 -0
- package/dist/lib/durable-job.js +296 -0
- package/dist/lib/http/client.d.ts +7 -1
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +2 -0
- package/dist/lib/instructions/apply.d.ts +3 -1
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +74 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +11 -2
- package/package.json +19 -2
- package/src/commander.ts +75 -1
- package/src/commands/admission.ts +699 -0
- package/src/commands/agents.ts +189 -50
- package/src/commands/artifacts.ts +132 -18
- package/src/commands/browse-ai.ts +10 -5
- package/src/commands/browse.ts +496 -20
- package/src/commands/diagnostics.ts +271 -0
- package/src/commands/fetch.ts +1 -0
- package/src/commands/files.ts +102 -2
- package/src/commands/governor.ts +8 -0
- package/src/commands/ledger-v3.ts +82 -0
- package/src/commands/qa-record.ts +682 -0
- package/src/commands/qa-run.ts +503 -0
- package/src/commands/qa-status.ts +608 -0
- package/src/commands/qa-verify.ts +238 -0
- package/src/commands/resources.ts +38 -0
- package/src/commands/review-pack.ts +1281 -0
- package/src/commands/supervisor.ts +141 -0
- package/src/commands/web.ts +19 -0
- package/src/commands/workflow.ts +8 -0
- package/src/core/agents/cli.ts +7 -3
- package/src/core/agents/health.ts +142 -0
- package/src/core/agents/mailbox.ts +373 -0
- package/src/core/agents/qa-signal.ts +261 -0
- package/src/core/agents/reconcile-coordination-v3.ts +77 -0
- package/src/core/agents/render/prompt-context.ts +42 -12
- package/src/core/agents/render/session-context.ts +37 -3
- package/src/core/agents/rules/commit-conflict.ts +58 -1
- package/src/core/agents/rules/stop-hook.ts +6 -12
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/agents/session-name-display.ts +78 -7
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +23 -0
- package/src/core/agents/state/live-coordination-view.ts +1 -0
- package/src/core/agents/state/live-coordination-writer.ts +5 -0
- package/src/core/artifacts/constants.ts +1 -1
- package/src/core/artifacts/index.ts +565 -30
- package/src/core/config.ts +134 -2
- package/src/core/diagnostics/advice.ts +147 -0
- package/src/core/diagnostics/bundle.ts +1250 -0
- package/src/core/diagnostics/comparison.ts +565 -0
- package/src/core/diagnostics/contract.ts +311 -0
- package/src/core/diagnostics/identity.ts +11 -0
- package/src/core/diagnostics/index.ts +7 -0
- package/src/core/diagnostics/replay.ts +314 -0
- package/src/core/diagnostics/sanitize.ts +97 -0
- package/src/core/events/legacy-storage/compression.ts +130 -0
- package/src/core/events/legacy-storage/index.ts +1 -0
- package/src/core/events/v3/archive-retention.ts +251 -0
- package/src/core/events/v3/bootstrap.ts +10 -0
- package/src/core/events/v3/capabilities.ts +2 -0
- package/src/core/events/v3/coordination-view.ts +100 -11
- package/src/core/events/v3/index.ts +9 -0
- package/src/core/events/v3/live-routing.ts +1 -0
- package/src/core/events/v3/producers/hook-base.ts +14 -2
- package/src/core/events/v3/producers/intake.ts +10 -2
- package/src/core/events/v3/producers/recorder.ts +420 -17
- package/src/core/hooks/adapter/output.ts +12 -1
- package/src/core/hooks/cli.ts +332 -247
- package/src/core/hooks/health.ts +146 -0
- package/src/core/hooks/resolve/transcript.ts +10 -3
- package/src/core/hooks/session-name-presence.ts +6 -1
- package/src/core/qa-artifacts.ts +126 -0
- package/src/core/resources/contract.ts +105 -0
- package/src/core/resources/index.ts +5 -0
- package/src/core/resources/sampler.ts +590 -0
- package/src/core/resources/service-status.ts +62 -0
- package/src/core/resources/service.ts +337 -0
- package/src/core/resources/storage.ts +44 -0
- package/src/core/storage/atomic-json.ts +15 -0
- package/src/core/storage/builtins.ts +62 -6
- package/src/core/storage/logger.ts +2 -0
- package/src/core/storage/query.ts +58 -0
- package/src/core/supervisor/activity.ts +193 -0
- package/src/core/supervisor/contract.ts +312 -0
- package/src/core/supervisor/explanations.ts +104 -0
- package/src/core/supervisor/findings.ts +788 -0
- package/src/core/supervisor/history.ts +61 -0
- package/src/core/supervisor/hook-health-alerts.ts +108 -0
- package/src/core/supervisor/hook-health-storage.ts +25 -0
- package/src/core/supervisor/hook-health.ts +301 -0
- package/src/core/supervisor/hooks.ts +35 -0
- package/src/core/supervisor/index.ts +14 -0
- package/src/core/supervisor/log-feed.ts +131 -0
- package/src/core/supervisor/service.ts +511 -0
- package/src/core/supervisor/services.ts +203 -0
- package/src/core/supervisor/status.ts +59 -0
- package/src/core/supervisor/storage.ts +126 -0
- package/src/core/supervisor/timeline.ts +133 -0
- package/src/core/workflow/admission.ts +215 -0
- package/src/core/workflow/engine.ts +93 -1
- package/src/core/workflow/index.ts +10 -0
- package/src/core/workflow/proof.ts +54 -1
- package/src/core/workflow/run-state.ts +13 -1
- package/src/core/workflow/types.ts +39 -1
- package/src/lib/admission.ts +347 -0
- package/src/lib/agent-browser/client.ts +2 -10
- package/src/lib/browser/capture-fidelity.ts +98 -0
- package/src/lib/browser/client.ts +212 -10
- package/src/lib/browser/critique.ts +62 -7
- package/src/lib/browser/index.ts +65 -0
- package/src/lib/browser/page-review-judge.ts +360 -0
- package/src/lib/browser/page-review-pack.ts +2384 -0
- package/src/lib/browser/qa-run-contracts.ts +743 -0
- package/src/lib/browser/qa-run.ts +1462 -0
- package/src/lib/browser/request-diagnostics.ts +27 -0
- package/src/lib/browser/tiling.ts +32 -0
- package/src/lib/cookies/client.ts +228 -42
- package/src/lib/cookies/extra.ts +28 -0
- package/src/lib/cookies/index.ts +2 -0
- package/src/lib/coord-root-id.ts +23 -0
- package/src/lib/durable-job.ts +407 -0
- package/src/lib/http/client.ts +13 -1
- package/src/lib/instructions/apply.ts +81 -2
- package/src/lib/instructions/templates.ts +11 -2
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { buildDiagnosticAdvice } from "../diagnostics/advice.ts";
|
|
2
|
+
import type { DiagnosticAdvice } from "../diagnostics/contract.ts";
|
|
3
|
+
import {
|
|
4
|
+
type EnsureSupervisorResult,
|
|
5
|
+
ensureSupervisorRunning,
|
|
6
|
+
readSupervisorFindings,
|
|
7
|
+
readSupervisorStatus,
|
|
8
|
+
registerSupervisorConsumer,
|
|
9
|
+
type SupervisorCapability,
|
|
10
|
+
type SupervisorFinding,
|
|
11
|
+
type SupervisorFindings,
|
|
12
|
+
type SupervisorStatus,
|
|
13
|
+
unregisterSupervisorConsumer,
|
|
14
|
+
} from "../supervisor/index.ts";
|
|
15
|
+
import type { WorkflowDiagnosticAdmissionObservation } from "./types.ts";
|
|
16
|
+
|
|
17
|
+
const DEFAULT_FRESH_CYCLE_WAIT_MS = 4_000;
|
|
18
|
+
const POLL_INTERVAL_MS = 50;
|
|
19
|
+
|
|
20
|
+
export interface WorkflowDiagnosticAdmissionRuntime {
|
|
21
|
+
now: () => Date;
|
|
22
|
+
wait: (milliseconds: number) => Promise<void>;
|
|
23
|
+
registerConsumer: (coordRoot: string, input: { id: string; pid?: number }) => unknown;
|
|
24
|
+
unregisterConsumer: (coordRoot: string, id: string) => void;
|
|
25
|
+
ensureSupervisor: (coordRoot: string) => Promise<EnsureSupervisorResult>;
|
|
26
|
+
readStatus: (coordRoot: string, nowMs?: number) => SupervisorStatus;
|
|
27
|
+
readFindings: (coordRoot: string) => SupervisorFindings | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ObserveWorkflowDiagnosticAdmissionInput {
|
|
31
|
+
coordRoot: string;
|
|
32
|
+
runId: string;
|
|
33
|
+
freshCycleWaitMs?: number;
|
|
34
|
+
runtime?: Partial<WorkflowDiagnosticAdmissionRuntime>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function observeWorkflowDiagnosticAdmission(
|
|
38
|
+
input: ObserveWorkflowDiagnosticAdmissionInput,
|
|
39
|
+
): Promise<WorkflowDiagnosticAdmissionObservation> {
|
|
40
|
+
const runtime = admissionRuntime(input.runtime);
|
|
41
|
+
const requested = runtime.now();
|
|
42
|
+
const requestedAt = requested.toISOString();
|
|
43
|
+
const startedMs = requested.getTime();
|
|
44
|
+
const consumerId = `workflow-${input.runId}`;
|
|
45
|
+
let serviceState: WorkflowDiagnosticAdmissionObservation["service_state"] = "unavailable";
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
runtime.registerConsumer(input.coordRoot, { id: consumerId });
|
|
49
|
+
const ensured = await runtime.ensureSupervisor(input.coordRoot);
|
|
50
|
+
serviceState = ensured.state;
|
|
51
|
+
if (ensured.state === "unavailable") {
|
|
52
|
+
return unavailableObservation(
|
|
53
|
+
runtime,
|
|
54
|
+
requestedAt,
|
|
55
|
+
startedMs,
|
|
56
|
+
serviceState,
|
|
57
|
+
"error",
|
|
58
|
+
"supervisor_unavailable",
|
|
59
|
+
ensured.error,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const deadlineMs = runtime.now().getTime() + normalizeWait(input.freshCycleWaitMs);
|
|
64
|
+
while (runtime.now().getTime() <= deadlineMs) {
|
|
65
|
+
const status = runtime.readStatus(input.coordRoot, runtime.now().getTime());
|
|
66
|
+
const sampledAt = status.record?.last_cycle_at;
|
|
67
|
+
if (status.running && sampledAt && Date.parse(sampledAt) >= requested.getTime()) {
|
|
68
|
+
const report = runtime.readFindings(input.coordRoot);
|
|
69
|
+
if (!report) {
|
|
70
|
+
return unavailableObservation(
|
|
71
|
+
runtime,
|
|
72
|
+
requestedAt,
|
|
73
|
+
startedMs,
|
|
74
|
+
serviceState,
|
|
75
|
+
"unsupported",
|
|
76
|
+
"source_missing",
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
const observedAt = runtime.now().toISOString();
|
|
80
|
+
return {
|
|
81
|
+
requested_at: requestedAt,
|
|
82
|
+
observed_at: observedAt,
|
|
83
|
+
wait_ms: elapsedMs(runtime, startedMs),
|
|
84
|
+
service_state: serviceState,
|
|
85
|
+
freshness: "fresh",
|
|
86
|
+
sampled_at: sampledAt,
|
|
87
|
+
advice: buildDiagnosticAdvice({
|
|
88
|
+
findings: mergeFindings(report),
|
|
89
|
+
sourceCapability: supportedCapability(),
|
|
90
|
+
evaluatedAt: observedAt,
|
|
91
|
+
}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const remainingMs = deadlineMs - runtime.now().getTime();
|
|
95
|
+
if (remainingMs <= 0) break;
|
|
96
|
+
await runtime.wait(Math.min(POLL_INTERVAL_MS, remainingMs));
|
|
97
|
+
}
|
|
98
|
+
return unavailableObservation(
|
|
99
|
+
runtime,
|
|
100
|
+
requestedAt,
|
|
101
|
+
startedMs,
|
|
102
|
+
serviceState,
|
|
103
|
+
"expired",
|
|
104
|
+
"fresh_cycle_timeout",
|
|
105
|
+
);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
return unavailableObservation(
|
|
108
|
+
runtime,
|
|
109
|
+
requestedAt,
|
|
110
|
+
startedMs,
|
|
111
|
+
serviceState,
|
|
112
|
+
"error",
|
|
113
|
+
"observation_failed",
|
|
114
|
+
error instanceof Error ? error.message : String(error),
|
|
115
|
+
);
|
|
116
|
+
} finally {
|
|
117
|
+
try {
|
|
118
|
+
runtime.unregisterConsumer(input.coordRoot, consumerId);
|
|
119
|
+
} catch {
|
|
120
|
+
// Admission is observer-only. Cleanup failure cannot affect dispatch.
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function failedWorkflowDiagnosticAdmissionObservation(
|
|
126
|
+
error: unknown,
|
|
127
|
+
requestedAt: Date,
|
|
128
|
+
observedAt = new Date(),
|
|
129
|
+
): WorkflowDiagnosticAdmissionObservation {
|
|
130
|
+
const capability: SupervisorCapability = {
|
|
131
|
+
source_kind: "supervisor.findings",
|
|
132
|
+
state: "error",
|
|
133
|
+
reason_code: "observation_failed",
|
|
134
|
+
detail: (error instanceof Error ? error.message : String(error)).slice(0, 500),
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
requested_at: requestedAt.toISOString(),
|
|
138
|
+
observed_at: observedAt.toISOString(),
|
|
139
|
+
wait_ms: Math.max(0, observedAt.getTime() - requestedAt.getTime()),
|
|
140
|
+
service_state: "unavailable",
|
|
141
|
+
freshness: "unavailable",
|
|
142
|
+
advice: buildDiagnosticAdvice({
|
|
143
|
+
findings: [],
|
|
144
|
+
sourceCapability: capability,
|
|
145
|
+
evaluatedAt: observedAt.toISOString(),
|
|
146
|
+
}),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function unavailableObservation(
|
|
151
|
+
runtime: WorkflowDiagnosticAdmissionRuntime,
|
|
152
|
+
requestedAt: string,
|
|
153
|
+
startedMs: number,
|
|
154
|
+
serviceState: WorkflowDiagnosticAdmissionObservation["service_state"],
|
|
155
|
+
state: Exclude<SupervisorCapability["state"], "supported">,
|
|
156
|
+
reasonCode: string,
|
|
157
|
+
detail?: string,
|
|
158
|
+
): WorkflowDiagnosticAdmissionObservation {
|
|
159
|
+
const observedAt = runtime.now().toISOString();
|
|
160
|
+
const capability: SupervisorCapability = {
|
|
161
|
+
source_kind: "supervisor.findings",
|
|
162
|
+
state,
|
|
163
|
+
reason_code: reasonCode,
|
|
164
|
+
...(detail ? { detail: detail.slice(0, 500) } : {}),
|
|
165
|
+
};
|
|
166
|
+
const advice: DiagnosticAdvice = buildDiagnosticAdvice({
|
|
167
|
+
findings: [],
|
|
168
|
+
sourceCapability: capability,
|
|
169
|
+
evaluatedAt: observedAt,
|
|
170
|
+
});
|
|
171
|
+
return {
|
|
172
|
+
requested_at: requestedAt,
|
|
173
|
+
observed_at: observedAt,
|
|
174
|
+
wait_ms: elapsedMs(runtime, startedMs),
|
|
175
|
+
service_state: serviceState,
|
|
176
|
+
freshness: "unavailable",
|
|
177
|
+
advice,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function mergeFindings(report: SupervisorFindings): SupervisorFinding[] {
|
|
182
|
+
const byId = new Map<string, SupervisorFinding>();
|
|
183
|
+
for (const finding of report.transitions) byId.set(finding.id, finding);
|
|
184
|
+
for (const finding of report.active) byId.set(finding.id, finding);
|
|
185
|
+
return [...byId.values()];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function supportedCapability(): SupervisorCapability {
|
|
189
|
+
return { source_kind: "supervisor.findings", state: "supported" };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function normalizeWait(value: number | undefined): number {
|
|
193
|
+
if (value === undefined) return DEFAULT_FRESH_CYCLE_WAIT_MS;
|
|
194
|
+
if (!Number.isFinite(value) || value < 0) return DEFAULT_FRESH_CYCLE_WAIT_MS;
|
|
195
|
+
return Math.min(Math.floor(value), 30_000);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function elapsedMs(runtime: WorkflowDiagnosticAdmissionRuntime, startedMs: number): number {
|
|
199
|
+
return Math.max(0, runtime.now().getTime() - startedMs);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function admissionRuntime(
|
|
203
|
+
overrides: Partial<WorkflowDiagnosticAdmissionRuntime> | undefined,
|
|
204
|
+
): WorkflowDiagnosticAdmissionRuntime {
|
|
205
|
+
return {
|
|
206
|
+
now: () => new Date(),
|
|
207
|
+
wait: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
208
|
+
registerConsumer: registerSupervisorConsumer,
|
|
209
|
+
unregisterConsumer: unregisterSupervisorConsumer,
|
|
210
|
+
ensureSupervisor: ensureSupervisorRunning,
|
|
211
|
+
readStatus: readSupervisorStatus,
|
|
212
|
+
readFindings: readSupervisorFindings,
|
|
213
|
+
...overrides,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
@@ -35,6 +35,10 @@ import {
|
|
|
35
35
|
policyDigest,
|
|
36
36
|
summarizePolicyRequest,
|
|
37
37
|
} from "../policy/index.ts";
|
|
38
|
+
import {
|
|
39
|
+
failedWorkflowDiagnosticAdmissionObservation,
|
|
40
|
+
observeWorkflowDiagnosticAdmission,
|
|
41
|
+
} from "./admission.ts";
|
|
38
42
|
import { assertWorkflowRunId, createWorkflowApproval } from "./approvals.ts";
|
|
39
43
|
import { freezeWorkflowAttemptContext } from "./attempt-context.ts";
|
|
40
44
|
import { type BillingProbe, probeBilling } from "./billing.ts";
|
|
@@ -52,6 +56,7 @@ import {
|
|
|
52
56
|
acquireWorkflowResumeLease,
|
|
53
57
|
assertWorkflowRunResumable,
|
|
54
58
|
assertWorkflowScriptUnchanged,
|
|
59
|
+
WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION,
|
|
55
60
|
workflowScriptDigest,
|
|
56
61
|
writeWorkflowRunManifest,
|
|
57
62
|
} from "./run-state.ts";
|
|
@@ -71,12 +76,16 @@ import type {
|
|
|
71
76
|
WorkflowAgentProof,
|
|
72
77
|
WorkflowAttemptContext,
|
|
73
78
|
WorkflowContext,
|
|
79
|
+
WorkflowDiagnosticAdmissionConfig,
|
|
80
|
+
WorkflowDiagnosticAdmissionObservation,
|
|
81
|
+
WorkflowDiagnosticAdmissionProof,
|
|
74
82
|
WorkflowEvidenceRecord,
|
|
75
83
|
WorkflowModule,
|
|
76
84
|
WorkflowProof,
|
|
77
85
|
WorkflowSandboxProjectionEvidence,
|
|
78
86
|
WorkflowWorkContext,
|
|
79
87
|
} from "./types.ts";
|
|
88
|
+
import { WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION } from "./types.ts";
|
|
80
89
|
import { parseStageOutput, validateAgainstSchema } from "./validate.ts";
|
|
81
90
|
import { freezeWorkflowWorkContext } from "./work-context.ts";
|
|
82
91
|
import {
|
|
@@ -317,6 +326,11 @@ async function executeWorkflow(
|
|
|
317
326
|
const approvalAddressee = frozen?.approval_addressee ?? opts.approvalAddressee ?? "operator";
|
|
318
327
|
const subscriptionOnly = frozen?.subscription_only ?? Boolean(opts.subscriptionOnly);
|
|
319
328
|
const allowApiBilling = frozen?.allow_api_billing ?? Boolean(opts.allowApiBilling);
|
|
329
|
+
const diagnosticAdmissionConfig = frozen?.diagnostic_admission
|
|
330
|
+
? normalizeDiagnosticAdmissionConfig(frozen.diagnostic_admission)
|
|
331
|
+
: resumeState
|
|
332
|
+
? undefined
|
|
333
|
+
: normalizeDiagnosticAdmissionConfig(opts.diagnosticAdmission);
|
|
320
334
|
const startedAt = resumeState?.manifest.started_at ?? new Date().toISOString();
|
|
321
335
|
const t0 = resumeState ? Date.parse(startedAt) : Date.now();
|
|
322
336
|
const scriptSha256 = resumeState?.manifest.script.sha256 ?? workflowScriptDigest(absScript);
|
|
@@ -386,6 +400,7 @@ async function executeWorkflow(
|
|
|
386
400
|
after: resumeState.manifest.repository_before,
|
|
387
401
|
agents: [],
|
|
388
402
|
evidence: [],
|
|
403
|
+
diagnosticAdmission: initialDiagnosticAdmissionProof(diagnosticAdmissionConfig),
|
|
389
404
|
adapterEvidence: opts.adapterEvidence,
|
|
390
405
|
adapterAttestations: opts.adapterAttestations,
|
|
391
406
|
sandboxProjection: sandboxProjectionEvidence(
|
|
@@ -454,7 +469,7 @@ async function executeWorkflow(
|
|
|
454
469
|
writeWorkflowRunManifest({
|
|
455
470
|
coordRoot: opts.coordRoot,
|
|
456
471
|
manifest: {
|
|
457
|
-
schema_version:
|
|
472
|
+
schema_version: WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION,
|
|
458
473
|
run_id: runId,
|
|
459
474
|
work_item_id: opts.workItemId,
|
|
460
475
|
work_context: workContext,
|
|
@@ -468,6 +483,7 @@ async function executeWorkflow(
|
|
|
468
483
|
default_adapter: defaultAdapter,
|
|
469
484
|
max_agents: maxAgents,
|
|
470
485
|
concurrency,
|
|
486
|
+
diagnostic_admission: diagnosticAdmissionConfig,
|
|
471
487
|
subscription_only: subscriptionOnly,
|
|
472
488
|
allow_api_billing: allowApiBilling,
|
|
473
489
|
approval_mode: approvalMode,
|
|
@@ -581,6 +597,8 @@ async function executeWorkflow(
|
|
|
581
597
|
history?.policyDecisions.map((decision) => [decision.id, decision]),
|
|
582
598
|
);
|
|
583
599
|
const acceptanceIds = new Set(meta.acceptance.map((criterion) => criterion.id));
|
|
600
|
+
let diagnosticAdmission = initialDiagnosticAdmissionProof(diagnosticAdmissionConfig);
|
|
601
|
+
let diagnosticAdmissionPromise: Promise<void> | undefined;
|
|
584
602
|
|
|
585
603
|
const transcript = (event: string, data: Record<string, unknown>): void => {
|
|
586
604
|
appendWorkflowTranscriptEvent(opts.coordRoot, runId, event, { stage: currentStage, ...data });
|
|
@@ -601,6 +619,46 @@ async function executeWorkflow(
|
|
|
601
619
|
});
|
|
602
620
|
};
|
|
603
621
|
|
|
622
|
+
const ensureDiagnosticAdmissionObserved = async (): Promise<void> => {
|
|
623
|
+
if (!diagnosticAdmissionConfig) return;
|
|
624
|
+
diagnosticAdmissionPromise ??= (async () => {
|
|
625
|
+
const requestedAt = new Date();
|
|
626
|
+
let observation: WorkflowDiagnosticAdmissionObservation;
|
|
627
|
+
try {
|
|
628
|
+
observation = await (
|
|
629
|
+
opts.observeDiagnosticAdmission ??
|
|
630
|
+
((coordRoot, observationRunId) =>
|
|
631
|
+
observeWorkflowDiagnosticAdmission({
|
|
632
|
+
coordRoot,
|
|
633
|
+
runId: observationRunId,
|
|
634
|
+
}))
|
|
635
|
+
)(opts.coordRoot, runId);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
observation = failedWorkflowDiagnosticAdmissionObservation(error, requestedAt);
|
|
638
|
+
}
|
|
639
|
+
diagnosticAdmission = {
|
|
640
|
+
schema_version: WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION,
|
|
641
|
+
mode: "shadow",
|
|
642
|
+
trigger: "before-first-dispatch",
|
|
643
|
+
state: "observed",
|
|
644
|
+
action: "none",
|
|
645
|
+
observation,
|
|
646
|
+
};
|
|
647
|
+
transcript("diagnostic.admission", {
|
|
648
|
+
schema_version: diagnosticAdmission.schema_version,
|
|
649
|
+
mode: diagnosticAdmission.mode,
|
|
650
|
+
trigger: diagnosticAdmission.trigger,
|
|
651
|
+
action: diagnosticAdmission.action,
|
|
652
|
+
observation,
|
|
653
|
+
});
|
|
654
|
+
log(
|
|
655
|
+
`[admission] shadow pressure=${observation.advice.pressure} ` +
|
|
656
|
+
`recommendation=${observation.advice.fan_out_recommendation}; dispatch unchanged`,
|
|
657
|
+
);
|
|
658
|
+
})();
|
|
659
|
+
await diagnosticAdmissionPromise;
|
|
660
|
+
};
|
|
661
|
+
|
|
604
662
|
// Bounded concurrency gate shared by every spawn in the run — direct
|
|
605
663
|
// `agent()` calls and `parallel()` thunks draw from the same slot pool, so
|
|
606
664
|
// the cap holds even when a script nests parallel() inside loops.
|
|
@@ -936,6 +994,7 @@ async function executeWorkflow(
|
|
|
936
994
|
|
|
937
995
|
await acquire();
|
|
938
996
|
try {
|
|
997
|
+
await ensureDiagnosticAdmissionObserved();
|
|
939
998
|
transcript("agent.start", {
|
|
940
999
|
id,
|
|
941
1000
|
label,
|
|
@@ -1227,6 +1286,7 @@ async function executeWorkflow(
|
|
|
1227
1286
|
after: snapshotRepo(executionCwd),
|
|
1228
1287
|
agents: Array.from(agentProofs.values()),
|
|
1229
1288
|
evidence: evidenceRecords,
|
|
1289
|
+
diagnosticAdmission,
|
|
1230
1290
|
adapterEvidence: opts.adapterEvidence,
|
|
1231
1291
|
adapterAttestations: opts.adapterAttestations,
|
|
1232
1292
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
@@ -1270,6 +1330,7 @@ async function executeWorkflow(
|
|
|
1270
1330
|
mode: subscriptionOnly ? "subscription" : p.mode,
|
|
1271
1331
|
})),
|
|
1272
1332
|
policy: proof.policy?.summary,
|
|
1333
|
+
diagnosticAdmission,
|
|
1273
1334
|
workspaceBinding,
|
|
1274
1335
|
};
|
|
1275
1336
|
return report;
|
|
@@ -1308,6 +1369,7 @@ async function executeWorkflow(
|
|
|
1308
1369
|
after: snapshotRepo(executionCwd),
|
|
1309
1370
|
agents: Array.from(agentProofs.values()),
|
|
1310
1371
|
evidence: evidenceRecords,
|
|
1372
|
+
diagnosticAdmission,
|
|
1311
1373
|
adapterEvidence: opts.adapterEvidence,
|
|
1312
1374
|
adapterAttestations: opts.adapterAttestations,
|
|
1313
1375
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
@@ -1485,6 +1547,36 @@ function round4(n: number): number {
|
|
|
1485
1547
|
return Math.round(n * 10_000) / 10_000;
|
|
1486
1548
|
}
|
|
1487
1549
|
|
|
1550
|
+
function normalizeDiagnosticAdmissionConfig(
|
|
1551
|
+
value: WorkflowDiagnosticAdmissionConfig | undefined,
|
|
1552
|
+
): WorkflowDiagnosticAdmissionConfig | undefined {
|
|
1553
|
+
if (value === undefined) return undefined;
|
|
1554
|
+
if (
|
|
1555
|
+
value.schema_version !== WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION ||
|
|
1556
|
+
value.mode !== "shadow"
|
|
1557
|
+
) {
|
|
1558
|
+
throw new Error("diagnosticAdmission must use schema_version 1 and mode shadow");
|
|
1559
|
+
}
|
|
1560
|
+
return {
|
|
1561
|
+
schema_version: WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION,
|
|
1562
|
+
mode: "shadow",
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
function initialDiagnosticAdmissionProof(
|
|
1567
|
+
config: WorkflowDiagnosticAdmissionConfig | undefined,
|
|
1568
|
+
): WorkflowDiagnosticAdmissionProof | undefined {
|
|
1569
|
+
if (!config) return undefined;
|
|
1570
|
+
return {
|
|
1571
|
+
schema_version: WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION,
|
|
1572
|
+
mode: "shadow",
|
|
1573
|
+
trigger: "before-first-dispatch",
|
|
1574
|
+
state: "not-needed",
|
|
1575
|
+
action: "none",
|
|
1576
|
+
reason_code: "no-dispatch",
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1488
1580
|
function assertAgentCapacity(agentsSpawned: number, maxAgents: number): void {
|
|
1489
1581
|
if (agentsSpawned >= maxAgents) {
|
|
1490
1582
|
throw new Error(
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export {
|
|
2
|
+
failedWorkflowDiagnosticAdmissionObservation,
|
|
3
|
+
type ObserveWorkflowDiagnosticAdmissionInput,
|
|
4
|
+
observeWorkflowDiagnosticAdmission,
|
|
5
|
+
type WorkflowDiagnosticAdmissionRuntime,
|
|
6
|
+
} from "./admission.ts";
|
|
1
7
|
export type {
|
|
2
8
|
CreateWorkflowApprovalInput,
|
|
3
9
|
ResolveWorkflowApprovalInput,
|
|
@@ -72,6 +78,9 @@ export type {
|
|
|
72
78
|
WorkflowAttemptPriorContext,
|
|
73
79
|
WorkflowAttemptUnresolvedCriterion,
|
|
74
80
|
WorkflowContext,
|
|
81
|
+
WorkflowDiagnosticAdmissionConfig,
|
|
82
|
+
WorkflowDiagnosticAdmissionObservation,
|
|
83
|
+
WorkflowDiagnosticAdmissionProof,
|
|
75
84
|
WorkflowEvidenceInput,
|
|
76
85
|
WorkflowEvidenceRecord,
|
|
77
86
|
WorkflowMeta,
|
|
@@ -87,6 +96,7 @@ export type {
|
|
|
87
96
|
} from "./types.ts";
|
|
88
97
|
export {
|
|
89
98
|
WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION,
|
|
99
|
+
WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION,
|
|
90
100
|
WORKFLOW_PROOF_SCHEMA_VERSION,
|
|
91
101
|
WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION,
|
|
92
102
|
} from "./types.ts";
|
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
SpawnFailureClass,
|
|
25
25
|
WorkflowAgentProof,
|
|
26
26
|
WorkflowAttemptContext,
|
|
27
|
+
WorkflowDiagnosticAdmissionProof,
|
|
27
28
|
WorkflowEvidenceInput,
|
|
28
29
|
WorkflowEvidenceRecord,
|
|
29
30
|
WorkflowMeta,
|
|
@@ -35,7 +36,11 @@ import type {
|
|
|
35
36
|
WorkflowSandboxProjectionEvidence,
|
|
36
37
|
WorkflowWorkContext,
|
|
37
38
|
} from "./types.ts";
|
|
38
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
EVIDENCE_KINDS,
|
|
41
|
+
WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION,
|
|
42
|
+
WORKFLOW_PROOF_SCHEMA_VERSION,
|
|
43
|
+
} from "./types.ts";
|
|
39
44
|
import { isCanonicalWorkflowWorkContext } from "./work-context.ts";
|
|
40
45
|
import type {
|
|
41
46
|
WorkspaceAttestation,
|
|
@@ -84,6 +89,7 @@ export interface BuildWorkflowProofInput {
|
|
|
84
89
|
after: RepoSnapshot;
|
|
85
90
|
agents: WorkflowAgentProof[];
|
|
86
91
|
evidence: WorkflowEvidenceRecord[];
|
|
92
|
+
diagnosticAdmission?: WorkflowDiagnosticAdmissionProof;
|
|
87
93
|
adapterEvidence?: Readonly<Record<string, AdapterEvidenceCapability | undefined>>;
|
|
88
94
|
/** Filesystem policy actually projected into children (ADR 0039). */
|
|
89
95
|
sandboxProjection?: WorkflowSandboxProjectionEvidence;
|
|
@@ -299,6 +305,7 @@ export function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProo
|
|
|
299
305
|
agents,
|
|
300
306
|
evidence: input.evidence,
|
|
301
307
|
policy: input.policy ? buildPolicyProof(input.policy) : undefined,
|
|
308
|
+
...(input.diagnosticAdmission ? { diagnostic_admission: input.diagnosticAdmission } : {}),
|
|
302
309
|
execution:
|
|
303
310
|
input.workspaceBinding && input.workspaceAttestation
|
|
304
311
|
? buildExecutionEvidence(input.status, input.workspaceBinding, input.workspaceAttestation)
|
|
@@ -385,6 +392,7 @@ export function readWorkflowProof(coordRoot: string, runId: string): WorkflowPro
|
|
|
385
392
|
(!proof.run.work_item_id ||
|
|
386
393
|
!proof.run.work_context ||
|
|
387
394
|
!isCanonicalWorkflowAttemptContext(proof.run.attempt_context))) ||
|
|
395
|
+
!validDiagnosticAdmissionProof(proof.diagnostic_admission) ||
|
|
388
396
|
(proof.execution !== undefined &&
|
|
389
397
|
!isWorkspaceExecutionEvidence(proof.execution, runId, proof.run.status))
|
|
390
398
|
) {
|
|
@@ -410,6 +418,42 @@ export function readWorkflowProof(coordRoot: string, runId: string): WorkflowPro
|
|
|
410
418
|
return proof;
|
|
411
419
|
}
|
|
412
420
|
|
|
421
|
+
function validDiagnosticAdmissionProof(
|
|
422
|
+
value: WorkflowDiagnosticAdmissionProof | undefined,
|
|
423
|
+
): boolean {
|
|
424
|
+
if (value === undefined) return true;
|
|
425
|
+
if (
|
|
426
|
+
value.schema_version !== WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION ||
|
|
427
|
+
value.mode !== "shadow" ||
|
|
428
|
+
value.trigger !== "before-first-dispatch" ||
|
|
429
|
+
value.action !== "none" ||
|
|
430
|
+
(value.state !== "not-needed" && value.state !== "observed")
|
|
431
|
+
) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
if (value.state === "not-needed") {
|
|
435
|
+
return value.reason_code === "no-dispatch" && value.observation === undefined;
|
|
436
|
+
}
|
|
437
|
+
const observation = value.observation;
|
|
438
|
+
return (
|
|
439
|
+
value.reason_code === undefined &&
|
|
440
|
+
observation !== undefined &&
|
|
441
|
+
validTimestamp(observation.requested_at) &&
|
|
442
|
+
validTimestamp(observation.observed_at) &&
|
|
443
|
+
Number.isSafeInteger(observation.wait_ms) &&
|
|
444
|
+
observation.wait_ms >= 0 &&
|
|
445
|
+
["running", "started", "unavailable"].includes(observation.service_state) &&
|
|
446
|
+
["fresh", "unavailable"].includes(observation.freshness) &&
|
|
447
|
+
(observation.sampled_at === undefined || validTimestamp(observation.sampled_at)) &&
|
|
448
|
+
observation.advice?.schema_version === 1 &&
|
|
449
|
+
observation.advice.observer_only === true
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function validTimestamp(value: unknown): value is string {
|
|
454
|
+
return typeof value === "string" && value.length > 0 && Number.isFinite(Date.parse(value));
|
|
455
|
+
}
|
|
456
|
+
|
|
413
457
|
function buildExecutionEvidence(
|
|
414
458
|
workflowStatus: "succeeded" | "failed",
|
|
415
459
|
binding: WorkspaceBinding,
|
|
@@ -458,6 +502,15 @@ export function renderWorkflowProof(proof: WorkflowProof): string {
|
|
|
458
502
|
`${proof.policy.summary.denied} denied, ${proof.policy.summary.asked} asked`,
|
|
459
503
|
);
|
|
460
504
|
}
|
|
505
|
+
if (proof.diagnostic_admission) {
|
|
506
|
+
const observation = proof.diagnostic_admission.observation;
|
|
507
|
+
lines.push(
|
|
508
|
+
observation
|
|
509
|
+
? `admission: shadow ${observation.advice.pressure}; ` +
|
|
510
|
+
`${observation.advice.fan_out_recommendation}; action none`
|
|
511
|
+
: "admission: shadow not needed; no real child dispatch",
|
|
512
|
+
);
|
|
513
|
+
}
|
|
461
514
|
const repo = proof.repository;
|
|
462
515
|
const drift = repo.drift;
|
|
463
516
|
lines.push(
|
|
@@ -26,9 +26,11 @@ import { readJsonRecord, writeImmutableJson } from "./durable-record.ts";
|
|
|
26
26
|
import { normalizeWorkflowSpecialists } from "./specialists.ts";
|
|
27
27
|
import type {
|
|
28
28
|
WorkflowAttemptContext,
|
|
29
|
+
WorkflowDiagnosticAdmissionConfig,
|
|
29
30
|
WorkflowSpecialistProfile,
|
|
30
31
|
WorkflowWorkContext,
|
|
31
32
|
} from "./types.ts";
|
|
33
|
+
import { WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION } from "./types.ts";
|
|
32
34
|
import { isCanonicalWorkflowWorkContext } from "./work-context.ts";
|
|
33
35
|
import type {
|
|
34
36
|
WorkspaceAllocationRequest,
|
|
@@ -41,7 +43,7 @@ import {
|
|
|
41
43
|
isWorkspaceCompatibilityExecutionEvidence,
|
|
42
44
|
} from "./workspaces/validate.ts";
|
|
43
45
|
|
|
44
|
-
export const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION =
|
|
46
|
+
export const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION = 2 as const;
|
|
45
47
|
|
|
46
48
|
const MANIFEST_LIMIT_BYTES = 256 * 1024;
|
|
47
49
|
const FOREIGN_LEASE_STALE_MS = 24 * 60 * 60 * 1_000;
|
|
@@ -61,6 +63,7 @@ export interface WorkflowRunManifest {
|
|
|
61
63
|
default_adapter: string;
|
|
62
64
|
max_agents: number;
|
|
63
65
|
concurrency: number;
|
|
66
|
+
diagnostic_admission?: WorkflowDiagnosticAdmissionConfig;
|
|
64
67
|
subscription_only: boolean;
|
|
65
68
|
allow_api_billing: boolean;
|
|
66
69
|
approval_mode: "deny" | "park";
|
|
@@ -274,6 +277,7 @@ function validExecution(value: WorkflowRunManifest["execution"]): boolean {
|
|
|
274
277
|
value.default_adapter.length > 0 &&
|
|
275
278
|
positiveSafeInteger(value.max_agents) &&
|
|
276
279
|
positiveSafeInteger(value.concurrency) &&
|
|
280
|
+
validDiagnosticAdmission(value.diagnostic_admission) &&
|
|
277
281
|
typeof value.subscription_only === "boolean" &&
|
|
278
282
|
typeof value.allow_api_billing === "boolean" &&
|
|
279
283
|
(value.approval_mode === "deny" || value.approval_mode === "park") &&
|
|
@@ -292,6 +296,14 @@ function validExecution(value: WorkflowRunManifest["execution"]): boolean {
|
|
|
292
296
|
);
|
|
293
297
|
}
|
|
294
298
|
|
|
299
|
+
function validDiagnosticAdmission(value: WorkflowDiagnosticAdmissionConfig | undefined): boolean {
|
|
300
|
+
return (
|
|
301
|
+
value === undefined ||
|
|
302
|
+
(value.schema_version === WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION &&
|
|
303
|
+
value.mode === "shadow")
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
295
307
|
function readManifestWorkspaceRequest(
|
|
296
308
|
coordRoot: string,
|
|
297
309
|
runId: string,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Design record: decision 0015 (portable coordination-aware workflows).
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type { DiagnosticAdvice } from "../diagnostics/contract.ts";
|
|
10
11
|
import type {
|
|
11
12
|
DispatchCostEstimator,
|
|
12
13
|
ExternalMutationRequest,
|
|
@@ -24,7 +25,8 @@ import type {
|
|
|
24
25
|
WorkspaceProvider,
|
|
25
26
|
} from "./workspaces/index.ts";
|
|
26
27
|
|
|
27
|
-
export const WORKFLOW_PROOF_SCHEMA_VERSION =
|
|
28
|
+
export const WORKFLOW_PROOF_SCHEMA_VERSION = 2 as const;
|
|
29
|
+
export const WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION = 1 as const;
|
|
28
30
|
export const WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION = 1 as const;
|
|
29
31
|
export const WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION = 1 as const;
|
|
30
32
|
|
|
@@ -46,6 +48,31 @@ export type AcceptanceStatus = "satisfied" | "unsatisfied" | "unknown";
|
|
|
46
48
|
export type WorkflowRunStatus = "succeeded" | "failed";
|
|
47
49
|
export type WorkflowApprovalMode = "deny" | "park";
|
|
48
50
|
|
|
51
|
+
export interface WorkflowDiagnosticAdmissionConfig {
|
|
52
|
+
schema_version: typeof WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION;
|
|
53
|
+
mode: "shadow";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface WorkflowDiagnosticAdmissionObservation {
|
|
57
|
+
requested_at: string;
|
|
58
|
+
observed_at: string;
|
|
59
|
+
wait_ms: number;
|
|
60
|
+
service_state: "running" | "started" | "unavailable";
|
|
61
|
+
freshness: "fresh" | "unavailable";
|
|
62
|
+
sampled_at?: string;
|
|
63
|
+
advice: DiagnosticAdvice;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface WorkflowDiagnosticAdmissionProof {
|
|
67
|
+
schema_version: typeof WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION;
|
|
68
|
+
mode: "shadow";
|
|
69
|
+
trigger: "before-first-dispatch";
|
|
70
|
+
state: "not-needed" | "observed";
|
|
71
|
+
action: "none";
|
|
72
|
+
reason_code?: "no-dispatch";
|
|
73
|
+
observation?: WorkflowDiagnosticAdmissionObservation;
|
|
74
|
+
}
|
|
75
|
+
|
|
49
76
|
export interface AcceptanceCriterion {
|
|
50
77
|
/** Stable identifier referenced by evidence, for example `tests-pass`. */
|
|
51
78
|
id: string;
|
|
@@ -221,6 +248,8 @@ export interface WorkflowProof {
|
|
|
221
248
|
agents: WorkflowAgentProof[];
|
|
222
249
|
evidence: WorkflowEvidenceRecord[];
|
|
223
250
|
policy?: WorkflowPolicyProof;
|
|
251
|
+
/** Observer-only local pressure recorded before the first real child dispatch. */
|
|
252
|
+
diagnostic_admission?: WorkflowDiagnosticAdmissionProof;
|
|
224
253
|
/** Immutable terminal provider evidence for isolated execution. */
|
|
225
254
|
execution?: WorkspaceExecutionEvidence;
|
|
226
255
|
repository: WorkflowRepoEvidence;
|
|
@@ -557,6 +586,13 @@ export interface EngineOpts {
|
|
|
557
586
|
maxAgents?: number;
|
|
558
587
|
/** Concurrent-subagent cap for parallel() (default 4). */
|
|
559
588
|
concurrency?: number;
|
|
589
|
+
/** Opt-in observer-only pressure sample before the first real child dispatch. */
|
|
590
|
+
diagnosticAdmission?: WorkflowDiagnosticAdmissionConfig;
|
|
591
|
+
/** Admission observer override for tests. */
|
|
592
|
+
observeDiagnosticAdmission?: (
|
|
593
|
+
coordRoot: string,
|
|
594
|
+
runId: string,
|
|
595
|
+
) => Promise<WorkflowDiagnosticAdmissionObservation>;
|
|
560
596
|
/** Working directory children spawn in (default: coordRoot). */
|
|
561
597
|
cwd?: string;
|
|
562
598
|
/** Progress sink (default: process.stderr). */
|
|
@@ -639,6 +675,8 @@ export interface RunReport {
|
|
|
639
675
|
billing: Array<{ adapter: AdapterName; mode: BillingMode }>;
|
|
640
676
|
/** Policy verdict totals when the host supplied a policy. */
|
|
641
677
|
policy?: WorkflowPolicyProof["summary"];
|
|
678
|
+
/** Observer-only pressure sample. Never changes dispatch in shadow mode. */
|
|
679
|
+
diagnosticAdmission?: WorkflowDiagnosticAdmissionProof;
|
|
642
680
|
/** Isolated workspace binding when this run requested a provider capability. */
|
|
643
681
|
workspaceBinding?: WorkspaceBinding;
|
|
644
682
|
}
|