harnery 0.38.0 → 0.40.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/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +32 -8
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +97 -6
- package/dist/commands/backup.d.ts +16 -0
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +239 -33
- package/dist/commands/browse.d.ts +8 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +466 -231
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +6 -3
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +20 -4
- package/dist/commands/qa-run.d.ts.map +1 -1
- package/dist/commands/qa-run.js +26 -3
- package/dist/commands/qa-status.d.ts.map +1 -1
- package/dist/commands/qa-status.js +7 -2
- package/dist/commands/resources.d.ts.map +1 -1
- package/dist/commands/resources.js +23 -3
- package/dist/commands/review-pack.d.ts.map +1 -1
- package/dist/commands/review-pack.js +98 -23
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +2 -2
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts +3 -2
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -0
- package/dist/core/agents/cli.js +13 -6
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +5 -3
- package/dist/core/agents/live-lifecycle-v3.d.ts +2 -2
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.d.ts +7 -5
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +63 -8
- package/dist/core/agents/session-finalizer-v3.d.ts +2 -2
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.d.ts +3 -3
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +2 -1
- package/dist/core/agents/state/names.d.ts +35 -2
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +80 -5
- package/dist/core/agents/state/stale-sweep.d.ts +2 -1
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -6
- package/dist/core/agents/turn-elapsed.d.ts +51 -0
- package/dist/core/agents/turn-elapsed.d.ts.map +1 -0
- package/dist/core/agents/turn-elapsed.js +91 -0
- package/dist/core/artifacts/activity.d.ts +14 -0
- package/dist/core/artifacts/activity.d.ts.map +1 -0
- package/dist/core/artifacts/activity.js +52 -0
- package/dist/core/artifacts/delivery-card.d.ts +39 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -0
- package/dist/core/artifacts/delivery-card.js +282 -0
- package/dist/core/artifacts/index.d.ts +42 -7
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +288 -76
- package/dist/core/artifacts/mutation-lock.d.ts +2 -0
- package/dist/core/artifacts/mutation-lock.d.ts.map +1 -0
- package/dist/core/artifacts/mutation-lock.js +91 -0
- package/dist/core/backup/host-snapshot.d.ts +18 -0
- package/dist/core/backup/host-snapshot.d.ts.map +1 -0
- package/dist/core/backup/host-snapshot.js +64 -0
- package/dist/core/config.d.ts +20 -5
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +44 -10
- package/dist/core/diagnostics/advice.d.ts +38 -3
- package/dist/core/diagnostics/advice.d.ts.map +1 -1
- package/dist/core/diagnostics/advice.js +103 -99
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +111 -47
- package/dist/core/diagnostics/comparison.d.ts.map +1 -1
- package/dist/core/diagnostics/comparison.js +3 -2
- package/dist/core/diagnostics/contract.d.ts +15 -31
- package/dist/core/diagnostics/contract.d.ts.map +1 -1
- package/dist/core/diagnostics/contract.js +2 -5
- package/dist/core/diagnostics/index.d.ts +2 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -1
- package/dist/core/diagnostics/index.js +2 -0
- package/dist/core/diagnostics/pressure-contract.d.ts +260 -0
- package/dist/core/diagnostics/pressure-contract.d.ts.map +1 -0
- package/dist/core/diagnostics/pressure-contract.js +70 -0
- package/dist/core/diagnostics/pressure.d.ts +25 -0
- package/dist/core/diagnostics/pressure.d.ts.map +1 -0
- package/dist/core/diagnostics/pressure.js +1138 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -1
- package/dist/core/diagnostics/replay.js +90 -10
- package/dist/core/events/v3/adapter-id.d.ts +6 -0
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -0
- package/dist/core/events/v3/adapter-id.js +7 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -1
- package/dist/core/events/v3/archive-retention.js +3 -2
- package/dist/core/events/v3/bootstrap.d.ts +41 -4
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +120 -17
- package/dist/core/events/v3/capabilities.d.ts +16 -9
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +37 -2
- package/dist/core/events/v3/capability-drift.d.ts +2 -2
- package/dist/core/events/v3/capability-drift.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.d.ts +48 -5
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +91 -36
- package/dist/core/events/v3/control.d.ts.map +1 -1
- package/dist/core/events/v3/control.js +22 -2
- package/dist/core/events/v3/index.d.ts +2 -1
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +2 -1
- package/dist/core/events/v3/live-feed.d.ts +7 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +21 -3
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +10 -2
- package/dist/core/events/v3/producers/command-recorder.d.ts +2 -2
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +2 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +2 -2
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +2 -1
- package/dist/core/events/v3/producers/hook-base.d.ts +2 -2
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +15 -5
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +17 -4
- package/dist/core/events/v3/producers/intake.d.ts +4 -4
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +3 -2
- package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -1
- package/dist/core/events/v3/producers/producer-state-observer.js +2 -1
- package/dist/core/events/v3/producers/recorder.d.ts +16 -5
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +31 -9
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +10 -13
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-build.js +3 -2
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +2 -2
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/turn-telemetry.d.ts +2 -2
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.d.ts +16 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +36 -38
- package/dist/core/hooks/backup-schedule.d.ts +34 -0
- package/dist/core/hooks/backup-schedule.d.ts.map +1 -0
- package/dist/core/hooks/backup-schedule.js +114 -0
- package/dist/core/hooks/cli.js +61 -18
- package/dist/core/hooks/codex-wsl-bridge.d.ts +2 -0
- package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -1
- package/dist/core/hooks/codex-wsl-bridge.js +18 -4
- package/dist/core/hooks/index.d.ts +1 -0
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +1 -0
- package/dist/core/hooks/prompt-context/contract.d.ts +61 -0
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/contract.js +102 -0
- package/dist/core/hooks/prompt-context/index.d.ts +5 -0
- package/dist/core/hooks/prompt-context/index.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/index.js +2 -0
- package/dist/core/hooks/prompt-context/runner.d.ts +24 -0
- package/dist/core/hooks/prompt-context/runner.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/runner.js +249 -0
- package/dist/core/qa-artifacts.d.ts +3 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -1
- package/dist/core/qa-artifacts.js +25 -3
- package/dist/core/resources/contract.d.ts +69 -3
- package/dist/core/resources/contract.d.ts.map +1 -1
- package/dist/core/resources/contract.js +1 -1
- package/dist/core/resources/index.d.ts +1 -0
- package/dist/core/resources/index.d.ts.map +1 -1
- package/dist/core/resources/index.js +1 -0
- package/dist/core/resources/native.d.ts +36 -0
- package/dist/core/resources/native.d.ts.map +1 -0
- package/dist/core/resources/native.js +418 -0
- package/dist/core/resources/sampler.d.ts +2 -0
- package/dist/core/resources/sampler.d.ts.map +1 -1
- package/dist/core/resources/sampler.js +31 -1
- package/dist/core/resources/status.d.ts +61 -0
- package/dist/core/resources/status.d.ts.map +1 -0
- package/dist/core/resources/status.js +536 -0
- package/dist/core/resources/system.d.ts +27 -0
- package/dist/core/resources/system.d.ts.map +1 -0
- package/dist/core/resources/system.js +439 -0
- package/dist/core/semantic/contract.d.ts +13 -13
- package/dist/core/semantic/service.d.ts +2 -0
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +27 -4
- package/dist/core/storage/builtins.js +41 -0
- package/dist/core/supervisor/contract.d.ts +41 -3
- package/dist/core/supervisor/contract.d.ts.map +1 -1
- package/dist/core/supervisor/contract.js +3 -2
- package/dist/core/supervisor/findings.d.ts +3 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -1
- package/dist/core/supervisor/findings.js +88 -0
- package/dist/core/supervisor/history.d.ts.map +1 -1
- package/dist/core/supervisor/history.js +14 -0
- package/dist/core/supervisor/ledger-state.d.ts +55 -0
- package/dist/core/supervisor/ledger-state.d.ts.map +1 -0
- package/dist/core/supervisor/ledger-state.js +0 -0
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +120 -7
- package/dist/core/supervisor/storage.d.ts +3 -1
- package/dist/core/supervisor/storage.d.ts.map +1 -1
- package/dist/core/supervisor/storage.js +4 -0
- package/dist/core/workflow/admission.d.ts +3 -0
- package/dist/core/workflow/admission.d.ts.map +1 -1
- package/dist/core/workflow/admission.js +28 -16
- package/dist/core/workflow/engine.js +2 -2
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +6 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +4 -3
- package/dist/lib/browser/capture-fidelity.d.ts +7 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -1
- package/dist/lib/browser/capture-fidelity.js +17 -0
- package/dist/lib/browser/client.d.ts +9 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +85 -37
- package/dist/lib/browser/index.d.ts +3 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/page-review-budget.d.ts +13 -0
- package/dist/lib/browser/page-review-budget.d.ts.map +1 -0
- package/dist/lib/browser/page-review-budget.js +251 -0
- package/dist/lib/browser/page-review-contracts.d.ts +127 -0
- package/dist/lib/browser/page-review-contracts.d.ts.map +1 -0
- package/dist/lib/browser/page-review-contracts.js +5 -0
- package/dist/lib/browser/page-review-evidence.d.ts +48 -0
- package/dist/lib/browser/page-review-evidence.d.ts.map +1 -0
- package/dist/lib/browser/page-review-evidence.js +340 -0
- package/dist/lib/browser/page-review-judge.d.ts +1 -1
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +46 -38
- package/dist/lib/browser/page-review-pack.d.ts +44 -22
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
- package/dist/lib/browser/page-review-pack.js +116 -36
- package/dist/lib/browser/page-review-source.d.ts +12 -0
- package/dist/lib/browser/page-review-source.d.ts.map +1 -0
- package/dist/lib/browser/page-review-source.js +22 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +35 -9
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run-contracts.js +48 -14
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +215 -68
- package/dist/lib/browser/qa-snapshot.d.ts +6 -0
- package/dist/lib/browser/qa-snapshot.d.ts.map +1 -1
- package/dist/lib/browser/qa-snapshot.js +259 -48
- package/dist/lib/browser/review-capture-transaction.d.ts +13 -0
- package/dist/lib/browser/review-capture-transaction.d.ts.map +1 -0
- package/dist/lib/browser/review-capture-transaction.js +79 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.js +4 -2
- package/dist/lib/browser/thumbnail-association.d.ts +34 -0
- package/dist/lib/browser/thumbnail-association.d.ts.map +1 -0
- package/dist/lib/browser/thumbnail-association.js +158 -0
- package/dist/lib/browser/tiling.d.ts +30 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +38 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +4 -1
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +7 -1
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +1 -0
- package/dist/lib/local-file-url.d.ts +12 -0
- package/dist/lib/local-file-url.d.ts.map +1 -1
- package/dist/lib/local-file-url.js +16 -2
- package/dist/lib/tunnel/state.d.ts +19 -4
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +53 -13
- package/package.json +7 -4
- package/schemas/config.schema.json +69 -2
- package/src/commands/agents.ts +42 -9
- package/src/commands/artifacts.ts +130 -6
- package/src/commands/backup.ts +287 -34
- package/src/commands/browse.ts +564 -267
- package/src/commands/diagnostics.ts +6 -3
- package/src/commands/ledger-v3.ts +20 -3
- package/src/commands/qa-run.ts +37 -3
- package/src/commands/qa-status.ts +11 -2
- package/src/commands/resources.ts +23 -3
- package/src/commands/review-pack.ts +165 -62
- package/src/commands/tunnel.ts +2 -1
- package/src/core/agents/canonical-emit.ts +4 -2
- package/src/core/agents/cli.ts +14 -6
- package/src/core/agents/live-authority-v3.ts +7 -3
- package/src/core/agents/live-lifecycle-v3.ts +2 -2
- package/src/core/agents/render/prompt-context.ts +68 -14
- package/src/core/agents/session-finalizer-v3.ts +2 -2
- package/src/core/agents/state/live-coordination-view.ts +4 -4
- package/src/core/agents/state/names.ts +92 -7
- package/src/core/agents/state/stale-sweep.ts +22 -8
- package/src/core/agents/turn-elapsed.ts +135 -0
- package/src/core/artifacts/activity.ts +71 -0
- package/src/core/artifacts/delivery-card.ts +375 -0
- package/src/core/artifacts/index.ts +385 -91
- package/src/core/artifacts/mutation-lock.ts +106 -0
- package/src/core/backup/host-snapshot.ts +76 -0
- package/src/core/config.ts +66 -13
- package/src/core/diagnostics/advice.ts +148 -120
- package/src/core/diagnostics/bundle.ts +138 -52
- package/src/core/diagnostics/comparison.ts +6 -2
- package/src/core/diagnostics/contract.ts +39 -42
- package/src/core/diagnostics/index.ts +2 -0
- package/src/core/diagnostics/pressure-contract.ts +294 -0
- package/src/core/diagnostics/pressure.ts +1361 -0
- package/src/core/diagnostics/replay.ts +116 -11
- package/src/core/events/v3/adapter-id.ts +12 -0
- package/src/core/events/v3/archive-retention.ts +3 -6
- package/src/core/events/v3/bootstrap.ts +163 -16
- package/src/core/events/v3/capabilities.ts +75 -25
- package/src/core/events/v3/capability-drift.ts +2 -2
- package/src/core/events/v3/control-witness.ts +172 -41
- package/src/core/events/v3/control.ts +34 -2
- package/src/core/events/v3/index.ts +3 -0
- package/src/core/events/v3/live-feed.ts +23 -5
- package/src/core/events/v3/live-routing.ts +14 -2
- package/src/core/events/v3/producers/command-recorder.ts +4 -4
- package/src/core/events/v3/producers/coordination-recorder.ts +4 -4
- package/src/core/events/v3/producers/hook-base.ts +21 -16
- package/src/core/events/v3/producers/hook.ts +21 -4
- package/src/core/events/v3/producers/intake.ts +6 -6
- package/src/core/events/v3/producers/producer-state-observer.ts +2 -1
- package/src/core/events/v3/producers/recorder.ts +50 -21
- package/src/core/events/v3/reader.ts +14 -13
- package/src/core/events/v3/runtime-build.ts +3 -2
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +3 -3
- package/src/core/events/v3/turn-telemetry.ts +4 -4
- package/src/core/hooks/adapter/output.ts +50 -36
- package/src/core/hooks/backup-schedule.ts +147 -0
- package/src/core/hooks/cli.ts +65 -14
- package/src/core/hooks/codex-wsl-bridge.ts +21 -5
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/prompt-context/contract.ts +177 -0
- package/src/core/hooks/prompt-context/index.ts +22 -0
- package/src/core/hooks/prompt-context/runner.ts +303 -0
- package/src/core/qa-artifacts.ts +29 -3
- package/src/core/resources/contract.ts +76 -3
- package/src/core/resources/index.ts +1 -0
- package/src/core/resources/native.ts +481 -0
- package/src/core/resources/sampler.ts +46 -1
- package/src/core/resources/status.ts +717 -0
- package/src/core/resources/system.ts +530 -0
- package/src/core/semantic/service.ts +37 -3
- package/src/core/storage/builtins.ts +41 -0
- package/src/core/supervisor/contract.ts +45 -3
- package/src/core/supervisor/findings.ts +159 -0
- package/src/core/supervisor/history.ts +15 -0
- package/src/core/supervisor/ledger-state.ts +0 -0
- package/src/core/supervisor/service.ts +133 -5
- package/src/core/supervisor/storage.ts +7 -0
- package/src/core/workflow/admission.ts +33 -17
- package/src/core/workflow/engine.ts +2 -2
- package/src/core/workflow/live-session-v3.ts +6 -8
- package/src/core/workflow/proof.ts +4 -3
- package/src/lib/browser/capture-fidelity.ts +23 -0
- package/src/lib/browser/client.ts +96 -44
- package/src/lib/browser/index.ts +15 -1
- package/src/lib/browser/page-review-budget.ts +309 -0
- package/src/lib/browser/page-review-contracts.ts +129 -0
- package/src/lib/browser/page-review-evidence.ts +465 -0
- package/src/lib/browser/page-review-judge.ts +56 -40
- package/src/lib/browser/page-review-pack.ts +181 -43
- package/src/lib/browser/page-review-source.ts +30 -0
- package/src/lib/browser/qa-run-contracts.ts +62 -18
- package/src/lib/browser/qa-run.ts +259 -71
- package/src/lib/browser/qa-snapshot.ts +289 -48
- package/src/lib/browser/review-capture-transaction.ts +106 -0
- package/src/lib/browser/standalone-html.ts +4 -2
- package/src/lib/browser/thumbnail-association.ts +190 -0
- package/src/lib/browser/tiling.ts +63 -0
- package/src/lib/docs-metadata-managed.ts +4 -1
- package/src/lib/identities/assume.ts +12 -4
- package/src/lib/instructions/templates.ts +1 -0
- package/src/lib/local-file-url.ts +17 -2
- package/src/lib/tunnel/state.ts +70 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../../src/core/diagnostics/replay.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../../src/core/diagnostics/replay.ts"],"names":[],"mappings":"AAgCA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAE3B,KAAK,oBAAoB,EAC1B,MAAM,eAAe,CAAC;AAOvB,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAErD;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,sBAAsB,EACpC,UAAU,EAAE,oBAAoB,GAC/B,kBAAkB,CAkBpB;AAED,qEAAqE;AACrE,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,sBAAsB,EACpC,UAAU,EAAE,oBAAoB,GAC/B,kBAAkB,CAwDpB"}
|
|
@@ -5,8 +5,11 @@ import { explainSupervisorFinding } from "../supervisor/explanations.js";
|
|
|
5
5
|
import { updateSupervisorFindings } from "../supervisor/findings.js";
|
|
6
6
|
import { projectHookHealth } from "../supervisor/hook-health.js";
|
|
7
7
|
import { buildSupervisorTimeline } from "../supervisor/timeline.js";
|
|
8
|
-
import { buildDiagnosticAdvice } from "./advice.js";
|
|
8
|
+
import { buildDiagnosticAdvice, pressureHistoryFromSupervisor, unknownPressureAssessment, } from "./advice.js";
|
|
9
9
|
import { DIAGNOSTIC_EXPECTED_SCHEMA_VERSION, } from "./contract.js";
|
|
10
|
+
import { assessPressure } from "./pressure.js";
|
|
11
|
+
const PRESSURE_SOURCE = "supervisor.pressure";
|
|
12
|
+
const FINDINGS_SOURCE = "supervisor.findings";
|
|
10
13
|
export function canonicalJson(value) {
|
|
11
14
|
return JSON.stringify(sortValue(value));
|
|
12
15
|
}
|
|
@@ -19,7 +22,7 @@ export function deriveCapturedExpected(observations, thresholds) {
|
|
|
19
22
|
const findings = filterFindings(findingsProjection(sourceValue(observations, "supervisor.findings")), selection);
|
|
20
23
|
const coordination = sourceValue(observations, "coordination.health");
|
|
21
24
|
const relatedSources = coordination?.recent_events ?? [];
|
|
22
|
-
return expected(thresholds, selection, findings, findings.map((finding) => diagnosticTimeline(finding, relatedSources)), findings.map(explainSupervisorFinding), observations);
|
|
25
|
+
return expected(thresholds, selection, findings, findings.map((finding) => diagnosticTimeline(finding, relatedSources)), findings.map(explainSupervisorFinding), capturedAdvice(observations, findings));
|
|
23
26
|
}
|
|
24
27
|
/** Re-run the pure finding engine from frozen source inputs only. */
|
|
25
28
|
export function replayDiagnosticInputs(observations, thresholds) {
|
|
@@ -27,7 +30,14 @@ export function replayDiagnosticInputs(observations, thresholds) {
|
|
|
27
30
|
neutralResource(observations.captured_at);
|
|
28
31
|
const supervisor = optionalSource(observations, "supervisor.snapshot") ??
|
|
29
32
|
neutralSupervisor(observations.captured_at);
|
|
30
|
-
|
|
33
|
+
// A captured history is untrusted JSON from a bundle that may predate the
|
|
34
|
+
// current point shape. Reading it unchecked would let an older capture reach
|
|
35
|
+
// the trend projection with no pressure readings on its points. The live
|
|
36
|
+
// observer and the dashboard validate the same way.
|
|
37
|
+
const capturedHistory = optionalSource(observations, "supervisor.history");
|
|
38
|
+
const history = capturedHistory?.schema_version === SUPERVISOR_HISTORY_SCHEMA_VERSION
|
|
39
|
+
? capturedHistory
|
|
40
|
+
: neutralHistory();
|
|
31
41
|
const logFeed = optionalSource(observations, "supervisor.log-feed") ??
|
|
32
42
|
neutralLogFeed(observations.captured_at);
|
|
33
43
|
const hookHealth = projectHookHealth(logFeed, new Date(observations.captured_at));
|
|
@@ -55,7 +65,81 @@ export function replayDiagnosticInputs(observations, thresholds) {
|
|
|
55
65
|
});
|
|
56
66
|
const findings = filterFindings(findingsProjection(evaluated), observations.selection);
|
|
57
67
|
const relatedSources = coordination?.recent_events ?? [];
|
|
58
|
-
return expected(thresholds, observations.selection, findings, findings.map((finding) => diagnosticTimeline(finding, relatedSources)), findings.map(explainSupervisorFinding), observations);
|
|
68
|
+
return expected(thresholds, observations.selection, findings, findings.map((finding) => diagnosticTimeline(finding, relatedSources)), findings.map(explainSupervisorFinding), replayedAdvice(observations, resource, history, evaluated));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The live assessment, exactly as the observer published it. Nothing is
|
|
72
|
+
* recomputed here, because `expected.json` freezes what the machine actually
|
|
73
|
+
* reported at capture time.
|
|
74
|
+
*/
|
|
75
|
+
function capturedAdvice(observations, findings) {
|
|
76
|
+
const record = optionalSource(observations, PRESSURE_SOURCE);
|
|
77
|
+
const capability = capturedSourceCapability(observations, PRESSURE_SOURCE);
|
|
78
|
+
if (!record?.assessment) {
|
|
79
|
+
return unavailableAdvice(observations.captured_at, capability);
|
|
80
|
+
}
|
|
81
|
+
return buildDiagnosticAdvice({
|
|
82
|
+
assessment: record.assessment,
|
|
83
|
+
priorHysteresis: record.prior_hysteresis ?? null,
|
|
84
|
+
sourceCapability: capability,
|
|
85
|
+
activeFindingCount: openedCount(findings),
|
|
86
|
+
evaluatedAt: observations.captured_at,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Recompute the assessment from frozen inputs. `prior_hysteresis` comes from
|
|
91
|
+
* the captured record, so a transition that depended on the previous sample is
|
|
92
|
+
* reproduced instead of restarting from a cold state.
|
|
93
|
+
*/
|
|
94
|
+
function replayedAdvice(observations, resource, history, evaluated) {
|
|
95
|
+
const record = optionalSource(observations, PRESSURE_SOURCE);
|
|
96
|
+
const capability = capturedSourceCapability(observations, PRESSURE_SOURCE);
|
|
97
|
+
if (!record?.assessment) {
|
|
98
|
+
return unavailableAdvice(observations.captured_at, capability);
|
|
99
|
+
}
|
|
100
|
+
const snapshotAvailable = optionalSource(observations, "resources.snapshot");
|
|
101
|
+
const findingsCapability = capturedSourceCapability(observations, FINDINGS_SOURCE);
|
|
102
|
+
const active = [...evaluated.active, ...evaluated.transitions].filter((finding) => finding.state === "opened");
|
|
103
|
+
const assessment = assessPressure({
|
|
104
|
+
snapshot: snapshotAvailable ? resource : null,
|
|
105
|
+
snapshot_reason: snapshotAvailable ? null : "captured_source_unavailable",
|
|
106
|
+
history: pressureHistoryFromSupervisor(history.points),
|
|
107
|
+
findings: active,
|
|
108
|
+
findings_capability: {
|
|
109
|
+
source_kind: findingsCapability.source_kind,
|
|
110
|
+
state: findingsCapability.state,
|
|
111
|
+
...(findingsCapability.reason_code ? { reason_code: findingsCapability.reason_code } : {}),
|
|
112
|
+
},
|
|
113
|
+
prior: record.prior_hysteresis ?? null,
|
|
114
|
+
observer_generation: record.observer_generation,
|
|
115
|
+
// Recover the observer's exact clock. `observed_at` is the sample instant
|
|
116
|
+
// and `sample_age_ms` is how far past it the observer read, so the sum is
|
|
117
|
+
// the original `now`, which staleness and the OOM hold both depend on.
|
|
118
|
+
now_ms: Date.parse(record.assessment.observed_at) + (record.assessment.sample_age_ms ?? 0),
|
|
119
|
+
});
|
|
120
|
+
return buildDiagnosticAdvice({
|
|
121
|
+
assessment,
|
|
122
|
+
priorHysteresis: record.prior_hysteresis ?? null,
|
|
123
|
+
sourceCapability: capability,
|
|
124
|
+
activeFindingCount: openedCount(filterFindings(findingsProjection(evaluated), observations.selection)),
|
|
125
|
+
evaluatedAt: observations.captured_at,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function unavailableAdvice(capturedAt, capability) {
|
|
129
|
+
return buildDiagnosticAdvice({
|
|
130
|
+
assessment: unknownPressureAssessment({
|
|
131
|
+
observedAt: capturedAt,
|
|
132
|
+
reasonCode: "evidence_unavailable",
|
|
133
|
+
summary: `Local resource pressure cannot be determined because the published assessment is ${capability.state}${capability.reason_code ? ` (${capability.reason_code})` : ""}.`,
|
|
134
|
+
}),
|
|
135
|
+
priorHysteresis: null,
|
|
136
|
+
sourceCapability: capability,
|
|
137
|
+
activeFindingCount: 0,
|
|
138
|
+
evaluatedAt: capturedAt,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function openedCount(findings) {
|
|
142
|
+
return findings.filter((finding) => finding.state === "opened").length;
|
|
59
143
|
}
|
|
60
144
|
function diagnosticTimeline(finding, relatedSources) {
|
|
61
145
|
return buildSupervisorTimeline(finding, relatedSources.filter((source) => {
|
|
@@ -63,7 +147,7 @@ function diagnosticTimeline(finding, relatedSources) {
|
|
|
63
147
|
return Number.isFinite(delta) && delta <= 5 * 60_000;
|
|
64
148
|
}));
|
|
65
149
|
}
|
|
66
|
-
function expected(thresholds, selection, findings, timelines, explanations,
|
|
150
|
+
function expected(thresholds, selection, findings, timelines, explanations, advice) {
|
|
67
151
|
return {
|
|
68
152
|
schema_version: DIAGNOSTIC_EXPECTED_SCHEMA_VERSION,
|
|
69
153
|
threshold_digest: sha256(canonicalJson(thresholds)),
|
|
@@ -71,11 +155,7 @@ function expected(thresholds, selection, findings, timelines, explanations, obse
|
|
|
71
155
|
findings,
|
|
72
156
|
timelines: [...timelines].sort((left, right) => left.finding_id.localeCompare(right.finding_id)),
|
|
73
157
|
explanations: [...explanations].sort((left, right) => left.finding_id.localeCompare(right.finding_id)),
|
|
74
|
-
advice
|
|
75
|
-
findings,
|
|
76
|
-
sourceCapability: capturedSourceCapability(observations, "supervisor.findings"),
|
|
77
|
-
evaluatedAt: observations.captured_at,
|
|
78
|
-
}),
|
|
158
|
+
advice,
|
|
79
159
|
};
|
|
80
160
|
}
|
|
81
161
|
function capturedSourceCapability(observations, sourceKind) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Adapter } from "../../adapter.js";
|
|
2
|
+
/** Harness identities that may produce or describe Event Ledger V3 evidence. */
|
|
3
|
+
export type EventAdapterIdV3 = Adapter | "openclaw";
|
|
4
|
+
/** Canonical event-adapter census. Workflow launch adapters remain in core/adapter.ts. */
|
|
5
|
+
export declare const EVENT_ADAPTER_IDS_V3: readonly ["claude-code", "codex", "cursor", "openclaw"];
|
|
6
|
+
//# sourceMappingURL=adapter-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-id.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/adapter-id.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,gFAAgF;AAChF,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpD,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,yDAKe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-retention.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/archive-retention.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAYrE,OAAO,
|
|
1
|
+
{"version":3,"file":"archive-retention.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/archive-retention.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAYrE,OAAO,EAAE,KAAK,wBAAwB,EAA4B,MAAM,iBAAiB,CAAC;AAE1F,MAAM,MAAM,4BAA4B,GACpC,UAAU,GACV,SAAS,GACT,aAAa,GACb,mBAAmB,GACnB,WAAW,GACX,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,4BAA4B,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,6BAA6B;IAC5C,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,wBAAwB,CAAA;CAAO,GAC3D,mBAAmB,EAAE,CA4CvB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,wBAAwB,CAAA;CAAO,GAC1E,mBAAmB,EAAE,CAqCvB;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GACxB,6BAA6B,CAiC/B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Bounded retention for complete, closed Event Ledger V3 epochs. */
|
|
2
2
|
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import { basename, join, relative, resolve } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { eventLedgerArchivePolicy } from "../../config.js";
|
|
5
5
|
const ARCHIVE_PATTERN = /^epoch-[0-9]+(?:-[0-9]+)?$/;
|
|
6
6
|
const AUTO_CLEAN_STAMP = ".harnery/event-v3-archive-auto-clean.json";
|
|
7
7
|
export function eventV3ArchivesRoot(repoRoot) {
|
|
@@ -95,7 +95,8 @@ export function autoCleanEventV3Archives(repoRoot, opts = {}) {
|
|
|
95
95
|
if (!policy.autoClean)
|
|
96
96
|
return { ran: false, reason: "disabled", deleted: 0, bytes: 0 };
|
|
97
97
|
const stampPath = join(resolve(repoRoot), AUTO_CLEAN_STAMP);
|
|
98
|
-
|
|
98
|
+
// Archive cleanup remains daily, independent of short-lived working files.
|
|
99
|
+
const intervalMs = 24 * 60 * 60 * 1000;
|
|
99
100
|
try {
|
|
100
101
|
const stamp = JSON.parse(readFileSync(stampPath, "utf8"));
|
|
101
102
|
const last = Date.parse(stamp.last_run_at ?? "");
|
|
@@ -6,6 +6,16 @@ export interface InitializeEventLedgerV3Input {
|
|
|
6
6
|
configDigest: `sha256:${string}`;
|
|
7
7
|
approvalRecordId: string;
|
|
8
8
|
forceNewEpoch?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Activate a candidate epoch that was already created for this root.
|
|
11
|
+
*
|
|
12
|
+
* Unset, this activates a candidate that carries this initializer's producer
|
|
13
|
+
* identity and refuses every other one. Creation and activation are one
|
|
14
|
+
* locked step here, so such a candidate is the residue of a crash or a
|
|
15
|
+
* failed activation, never work in progress; a candidate from another
|
|
16
|
+
* producer is a deliberate cutover state. Set it explicitly to force either
|
|
17
|
+
* answer.
|
|
18
|
+
*/
|
|
9
19
|
resumeCandidate?: boolean;
|
|
10
20
|
now?: () => Date;
|
|
11
21
|
}
|
|
@@ -44,6 +54,30 @@ export declare function initializeEventLedgerV3(input: InitializeEventLedgerV3In
|
|
|
44
54
|
* explicit recovery command.
|
|
45
55
|
*/
|
|
46
56
|
export declare function refreshIncompatibleEventLedgerV3(coordRoot: string): RefreshIncompatibleEventLedgerV3Result;
|
|
57
|
+
export interface RepairStrandedEventLedgerV3CandidateResult {
|
|
58
|
+
state: "repaired" | "not_stranded" | "unavailable";
|
|
59
|
+
reason?: string;
|
|
60
|
+
control: EventV3ControlState;
|
|
61
|
+
}
|
|
62
|
+
/** The approval record every automatic stranded-candidate repair is bound to. */
|
|
63
|
+
export declare const EVENT_V3_STRANDED_CANDIDATE_APPROVAL_RECORD_ID: "harnery-runtime-v3-stranded-candidate";
|
|
64
|
+
/**
|
|
65
|
+
* Complete an epoch that was created but never activated.
|
|
66
|
+
*
|
|
67
|
+
* This initializer creates a candidate and activates it inside one lease, so a
|
|
68
|
+
* candidate carrying its producer identity is residue: some process published
|
|
69
|
+
* the genesis and died or failed before publishing the activation, and every
|
|
70
|
+
* hook afterwards served that half-built epoch with a candidate-only write
|
|
71
|
+
* gate. Finishing it is a repair, not a decision, and it is exactly as safe as
|
|
72
|
+
* the creation it completes: the same lease serializes it, the activation is
|
|
73
|
+
* derived from the immutable candidate packet, and no ledger row is edited or
|
|
74
|
+
* synthesized.
|
|
75
|
+
*
|
|
76
|
+
* A candidate from any other producer is a deliberate cutover state and is
|
|
77
|
+
* left untouched. A live bootstrap lease makes this a no-op rather than a
|
|
78
|
+
* failure, so the next boundary retries.
|
|
79
|
+
*/
|
|
80
|
+
export declare function repairStrandedEventLedgerV3Candidate(coordRoot: string): RepairStrandedEventLedgerV3CandidateResult;
|
|
47
81
|
export interface RotateOversizedEventLedgerV3Result {
|
|
48
82
|
state: "rotated" | "not_oversized" | "not_active" | "disabled";
|
|
49
83
|
active_bytes: number;
|
|
@@ -62,10 +96,13 @@ export interface RotateOversizedEventLedgerV3Result {
|
|
|
62
96
|
* (events, spool, producer states, manifests) moves whole into the V3
|
|
63
97
|
* archive, live sessions re-onboard into the new epoch on their next signal,
|
|
64
98
|
* and the writer's epoch fence keeps in-flight producers of the old epoch
|
|
65
|
-
* from ever committing into the new one.
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
99
|
+
* from ever committing into the new one. A candidate epoch rotates on the same
|
|
100
|
+
* terms as an active one: its control pair is valid, every reader still
|
|
101
|
+
* validates all of its history, and refusing to bound it is how a stranded
|
|
102
|
+
* epoch grew to 100 MB. Integrity failures stay closed for the explicit
|
|
103
|
+
* recovery command. The threshold comes from the isolated Event V3 config
|
|
104
|
+
* resolver unless the caller pins one; a non-positive threshold disables
|
|
105
|
+
* rotation.
|
|
69
106
|
*/
|
|
70
107
|
export declare function rotateOversizedEventLedgerV3(coordRoot: string, options?: {
|
|
71
108
|
thresholdBytes?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/bootstrap.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/bootstrap.ts"],"names":[],"mappings":"AAsBA,OAAO,EAOL,KAAK,mBAAmB,EAEzB,MAAM,cAAc,CAAC;AAStB,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,UAAU,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC,mBAAmB,EAAE;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,sCAAsC;IACrD,KAAK,EAAE,SAAS,GAAG,WAAW,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC,mBAAmB,EAAE;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;CAC5D;AAkBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,gBAAgB,SAAiC,GAChD,OAAO,CAAC,mBAAmB,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC,CAenD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,4BAA4B,GAClC,6BAA6B,CAE/B;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,MAAM,GAChB,sCAAsC,CAgCxC;AAED,MAAM,WAAW,0CAA0C;IACzD,KAAK,EAAE,UAAU,GAAG,cAAc,GAAG,aAAa,CAAC;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,iFAAiF;AACjF,eAAO,MAAM,8CAA8C,EACzD,uCAAgD,CAAC;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oCAAoC,CAClD,SAAS,EAAE,MAAM,GAChB,0CAA0C,CA6B5C;AAWD,MAAM,WAAW,kCAAkC;IACjD,KAAK,EAAE,SAAS,GAAG,eAAe,GAAG,YAAY,GAAG,UAAU,CAAC;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC,mBAAmB,EAAE;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,kCAAkC,CA8DpC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { chmodSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, statSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { chmodSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
4
4
|
import { hostname } from "node:os";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
6
7
|
import { fsyncParentDirectory } from "../../workflow/durable-record.js";
|
|
7
8
|
import { acquireNoClobberLease } from "../../workflow/workspaces/leases.js";
|
|
8
9
|
import { canonicalJsonV3, sha256V3 } from "./canonical.js";
|
|
@@ -15,6 +16,16 @@ import { reanchorArchivedHookProducersV3 } from "./producers/recorder.js";
|
|
|
15
16
|
import { resolveEventLedgerRotateActiveBytesV3 } from "./rotation-config.js";
|
|
16
17
|
import { currentHarneryRuntimeBuild, liveEventV3BuildId, livePlatformV3 } from "./runtime-build.js";
|
|
17
18
|
import { drainReadyEventsV3 } from "./writer.js";
|
|
19
|
+
/**
|
|
20
|
+
* The control producer every epoch created by this initializer carries.
|
|
21
|
+
*
|
|
22
|
+
* It separates a stranded epoch from a deliberate one. A candidate minted here
|
|
23
|
+
* was always meant to be activated in the same locked step, so finishing it is
|
|
24
|
+
* a repair. A candidate published by any other producer (an operator cutover or
|
|
25
|
+
* rollback rehearsal) is a state someone chose, and automatic activation would
|
|
26
|
+
* overrule them.
|
|
27
|
+
*/
|
|
28
|
+
const BOOTSTRAP_CONTROL_PRODUCER_ID = "prd_harnery-init";
|
|
18
29
|
const BOOTSTRAP_LEASE_RETRIES = 12;
|
|
19
30
|
const BOOTSTRAP_LEASE_RETRY_MS = 25;
|
|
20
31
|
const BOOTSTRAP_LEASE_STALE_MS = 10_000;
|
|
@@ -84,6 +95,56 @@ export function refreshIncompatibleEventLedgerV3(coordRoot) {
|
|
|
84
95
|
};
|
|
85
96
|
});
|
|
86
97
|
}
|
|
98
|
+
/** The approval record every automatic stranded-candidate repair is bound to. */
|
|
99
|
+
export const EVENT_V3_STRANDED_CANDIDATE_APPROVAL_RECORD_ID = "harnery-runtime-v3-stranded-candidate";
|
|
100
|
+
/**
|
|
101
|
+
* Complete an epoch that was created but never activated.
|
|
102
|
+
*
|
|
103
|
+
* This initializer creates a candidate and activates it inside one lease, so a
|
|
104
|
+
* candidate carrying its producer identity is residue: some process published
|
|
105
|
+
* the genesis and died or failed before publishing the activation, and every
|
|
106
|
+
* hook afterwards served that half-built epoch with a candidate-only write
|
|
107
|
+
* gate. Finishing it is a repair, not a decision, and it is exactly as safe as
|
|
108
|
+
* the creation it completes: the same lease serializes it, the activation is
|
|
109
|
+
* derived from the immutable candidate packet, and no ledger row is edited or
|
|
110
|
+
* synthesized.
|
|
111
|
+
*
|
|
112
|
+
* A candidate from any other producer is a deliberate cutover state and is
|
|
113
|
+
* left untouched. A live bootstrap lease makes this a no-op rather than a
|
|
114
|
+
* failure, so the next boundary retries.
|
|
115
|
+
*/
|
|
116
|
+
export function repairStrandedEventLedgerV3Candidate(coordRoot) {
|
|
117
|
+
const root = resolve(coordRoot);
|
|
118
|
+
const observed = readEventV3ControlState(root);
|
|
119
|
+
const deliberateCandidate = observed.state === "candidate";
|
|
120
|
+
if (!strandedBootstrapCandidate(observed)) {
|
|
121
|
+
return {
|
|
122
|
+
state: "not_stranded",
|
|
123
|
+
control: observed,
|
|
124
|
+
...(deliberateCandidate ? { reason: "candidate_not_bootstrap_created" } : {}),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
return withBootstrapLease(root, () => {
|
|
129
|
+
const current = readEventV3ControlState(root);
|
|
130
|
+
if (!strandedBootstrapCandidate(current))
|
|
131
|
+
return { state: "not_stranded", control: current };
|
|
132
|
+
const activated = activateCandidateEpoch(root, current.genesis, EVENT_V3_STRANDED_CANDIDATE_APPROVAL_RECORD_ID);
|
|
133
|
+
return { state: "repaired", control: activated.control };
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return {
|
|
138
|
+
state: "unavailable",
|
|
139
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
140
|
+
control: observed,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function strandedBootstrapCandidate(control) {
|
|
145
|
+
return (control.state === "candidate" &&
|
|
146
|
+
control.genesis.event.producer.producer_id === BOOTSTRAP_CONTROL_PRODUCER_ID);
|
|
147
|
+
}
|
|
87
148
|
/**
|
|
88
149
|
* Archive a valid oversized epoch intact and start a fresh one.
|
|
89
150
|
*
|
|
@@ -93,10 +154,13 @@ export function refreshIncompatibleEventLedgerV3(coordRoot) {
|
|
|
93
154
|
* (events, spool, producer states, manifests) moves whole into the V3
|
|
94
155
|
* archive, live sessions re-onboard into the new epoch on their next signal,
|
|
95
156
|
* and the writer's epoch fence keeps in-flight producers of the old epoch
|
|
96
|
-
* from ever committing into the new one.
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
157
|
+
* from ever committing into the new one. A candidate epoch rotates on the same
|
|
158
|
+
* terms as an active one: its control pair is valid, every reader still
|
|
159
|
+
* validates all of its history, and refusing to bound it is how a stranded
|
|
160
|
+
* epoch grew to 100 MB. Integrity failures stay closed for the explicit
|
|
161
|
+
* recovery command. The threshold comes from the isolated Event V3 config
|
|
162
|
+
* resolver unless the caller pins one; a non-positive threshold disables
|
|
163
|
+
* rotation.
|
|
100
164
|
*/
|
|
101
165
|
export function rotateOversizedEventLedgerV3(coordRoot, options = {}) {
|
|
102
166
|
const root = resolve(coordRoot);
|
|
@@ -122,7 +186,7 @@ export function rotateOversizedEventLedgerV3(coordRoot, options = {}) {
|
|
|
122
186
|
return { state: "not_oversized", active_bytes: activeBytes, threshold_bytes: threshold };
|
|
123
187
|
}
|
|
124
188
|
const current = readEventV3ControlState(root);
|
|
125
|
-
if (current.state !== "active") {
|
|
189
|
+
if (current.state !== "active" && current.state !== "candidate") {
|
|
126
190
|
return { state: "not_active", active_bytes: activeBytes, threshold_bytes: threshold };
|
|
127
191
|
}
|
|
128
192
|
// Flush durable ready rows into the epoch they were produced for, so the
|
|
@@ -164,13 +228,14 @@ export function rotateOversizedEventLedgerV3(coordRoot, options = {}) {
|
|
|
164
228
|
function initializeEventLedgerV3Locked(input) {
|
|
165
229
|
const root = resolve(input.coordRoot);
|
|
166
230
|
let current = readEventV3ControlState(root);
|
|
167
|
-
|
|
231
|
+
const resumeCandidate = input.resumeCandidate ?? strandedBootstrapCandidate(current);
|
|
232
|
+
if (resumeCandidate && current.state === "repairable") {
|
|
168
233
|
current = repairEventV3ControlPair(root);
|
|
169
234
|
}
|
|
170
235
|
if (!input.forceNewEpoch && current.state === "active") {
|
|
171
236
|
return { state: "active", initialized: false, control: current };
|
|
172
237
|
}
|
|
173
|
-
if (!input.forceNewEpoch &&
|
|
238
|
+
if (!input.forceNewEpoch && resumeCandidate && current.state === "candidate") {
|
|
174
239
|
return activateCandidateEpoch(root, current.genesis, input.approvalRecordId);
|
|
175
240
|
}
|
|
176
241
|
if (!input.forceNewEpoch && current.state === "candidate") {
|
|
@@ -178,11 +243,10 @@ function initializeEventLedgerV3Locked(input) {
|
|
|
178
243
|
}
|
|
179
244
|
const now = input.now ?? (() => new Date());
|
|
180
245
|
const createdAt = now().toISOString();
|
|
181
|
-
const archivedEpoch = archiveCurrentEpoch(root, createdAt);
|
|
182
246
|
const keys = loadOrCreateFingerprintKeyStoreV3(root, now);
|
|
183
247
|
const harneryBuild = safeBuild(input.harneryBuild);
|
|
184
248
|
const hostBuild = safeBuild(input.hostBuild);
|
|
185
|
-
const producerId =
|
|
249
|
+
const producerId = BOOTSTRAP_CONTROL_PRODUCER_ID;
|
|
186
250
|
const bootId = `boot_${createHash("sha256").update(`${root}\0${createdAt}`).digest("hex")}`;
|
|
187
251
|
const buildId = liveEventV3BuildId(harneryBuild);
|
|
188
252
|
const rootId = `root_${createHash("sha256").update(root).digest("hex")}`;
|
|
@@ -214,17 +278,35 @@ function initializeEventLedgerV3Locked(input) {
|
|
|
214
278
|
platform: livePlatformV3(),
|
|
215
279
|
},
|
|
216
280
|
});
|
|
281
|
+
// Mint the complete control pair before any epoch bytes move. Every approval
|
|
282
|
+
// and validation failure then happens while the current epoch is still
|
|
283
|
+
// whole, so it can never leave a replaced epoch stranded in candidate state.
|
|
284
|
+
const activation = buildActivationManifestV3(activationInput(candidate, input.approvalRecordId));
|
|
285
|
+
const archivedEpoch = archiveCurrentEpoch(root, createdAt);
|
|
217
286
|
publishControlFile(join(root, EVENT_V3_GENESIS_MANIFEST), candidate);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
287
|
+
let activated;
|
|
288
|
+
try {
|
|
289
|
+
activated = completeCandidateActivation(root, activation);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
// The epoch has already been replaced, so returning here would strand it.
|
|
293
|
+
// Retry the completion inside the same lease and, failing that, name the
|
|
294
|
+
// stranded epoch rather than reporting a successful initialization.
|
|
295
|
+
activated = completeStrandedCandidateActivation(root, activation, error);
|
|
221
296
|
}
|
|
222
|
-
const activated = activateCandidateEpoch(root, candidate, input.approvalRecordId);
|
|
223
297
|
return {
|
|
224
298
|
...activated,
|
|
225
299
|
...(archivedEpoch ? { archived_epoch: archivedEpoch } : {}),
|
|
226
300
|
};
|
|
227
301
|
}
|
|
302
|
+
function completeStrandedCandidateActivation(root, activation, cause) {
|
|
303
|
+
try {
|
|
304
|
+
return completeCandidateActivation(root, activation);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
throw new Error(`event_v3_epoch_stranded_before_activation:${cause instanceof Error ? cause.message : String(cause)}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
228
310
|
function runtimeCapabilityProfileCurrent(control) {
|
|
229
311
|
const expected = Object.values(ADAPTER_CAPABILITY_PROFILES_V3).map((profile) => sha256V3(canonicalJsonV3(profile)));
|
|
230
312
|
const approved = control.genesis.profile.adapter_capability_profile_digests;
|
|
@@ -275,8 +357,12 @@ function pidIsAlive(pid) {
|
|
|
275
357
|
}
|
|
276
358
|
}
|
|
277
359
|
function activateCandidateEpoch(root, candidate, approvalRecordId) {
|
|
360
|
+
return completeCandidateActivation(root, buildActivationManifestV3(activationInput(candidate, approvalRecordId)));
|
|
361
|
+
}
|
|
362
|
+
/** The activation packet one exact candidate deserves, derived and pure. */
|
|
363
|
+
function activationInput(candidate, approvalRecordId) {
|
|
278
364
|
const producer = candidate.event.producer;
|
|
279
|
-
|
|
365
|
+
return {
|
|
280
366
|
candidate,
|
|
281
367
|
approval_record_id: approvalRecordId,
|
|
282
368
|
activation_approved_at: candidate.profile.candidate_created_at,
|
|
@@ -288,7 +374,19 @@ function activateCandidateEpoch(root, candidate, approvalRecordId) {
|
|
|
288
374
|
platform: producer.platform,
|
|
289
375
|
...(producer.bridge ? { bridge: producer.bridge } : {}),
|
|
290
376
|
},
|
|
291
|
-
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Bring a published candidate to active: append the pre-minted genesis event
|
|
381
|
+
* if a crash left it missing, publish the activation manifest, then append its
|
|
382
|
+
* pre-minted event. Every step is idempotent, so the caller may retry it, and
|
|
383
|
+
* anything short of `active` throws with the state that blocked it.
|
|
384
|
+
*/
|
|
385
|
+
function completeCandidateActivation(root, activation) {
|
|
386
|
+
const candidateState = repairEventV3ControlPair(root);
|
|
387
|
+
if (candidateState.state !== "candidate") {
|
|
388
|
+
throw new Error(`event_v3_candidate_initialization_failed:${candidateState.state}`);
|
|
389
|
+
}
|
|
292
390
|
publishControlFile(join(root, EVENT_V3_ACTIVATION_MANIFEST), activation);
|
|
293
391
|
const active = repairEventV3ControlPair(root);
|
|
294
392
|
if (active.state !== "active") {
|
|
@@ -314,6 +412,11 @@ function archiveCurrentEpoch(root, createdAt) {
|
|
|
314
412
|
function publishControlFile(path, value) {
|
|
315
413
|
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
316
414
|
const temp = `${path}.tmp.${process.pid}`;
|
|
415
|
+
// A prior failed publish by this same pid would otherwise make every retry
|
|
416
|
+
// fail on the exclusive create, which is exactly how one transient error
|
|
417
|
+
// turns into a permanently stranded epoch.
|
|
418
|
+
if (existsSync(temp))
|
|
419
|
+
unlinkSync(temp);
|
|
317
420
|
const fd = openSync(temp, "wx", 0o600);
|
|
318
421
|
try {
|
|
319
422
|
writeFileSync(fd, `${canonicalJsonV3(value)}\n`, "utf8");
|
|
@@ -335,7 +438,7 @@ function safeBuild(value) {
|
|
|
335
438
|
.digest("hex");
|
|
336
439
|
}
|
|
337
440
|
function rootOfHarnery() {
|
|
338
|
-
return resolve(import.meta.
|
|
441
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "../../../..");
|
|
339
442
|
}
|
|
340
443
|
function repositoryBuild(root) {
|
|
341
444
|
const result = spawnSync("git", ["-C", root, "rev-parse", "HEAD"], {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EventAdapterIdV3 } from "./adapter-id.js";
|
|
2
2
|
export type CapabilitySupportV3 = "native" | "derived" | "conditional" | "unsupported";
|
|
3
|
+
export type AdapterDurationCapabilityV3 = "turn_duration" | "tool_duration";
|
|
3
4
|
export type CursorExecutionModeV3 = "local" | "cloud" | "unknown";
|
|
4
5
|
export type AdapterWaitKindV3 = "permission" | "needs_input" | "decision" | "approval" | "scheduled" | "rate_limit" | "unknown";
|
|
5
6
|
export declare const ADAPTER_WAIT_KINDS_V3: readonly AdapterWaitKindV3[];
|
|
@@ -12,27 +13,33 @@ export type AdapterSignalV3 = BaseAdapterSignalV3 | "model_usage" | "inference_t
|
|
|
12
13
|
export interface AdapterCapabilityProfileV3 {
|
|
13
14
|
format: "harnery-v3-adapter-capabilities";
|
|
14
15
|
format_version: 1;
|
|
15
|
-
adapter:
|
|
16
|
+
adapter: EventAdapterIdV3;
|
|
16
17
|
signals: Record<AdapterSignalV3, CapabilitySupportV3>;
|
|
17
18
|
}
|
|
18
|
-
export declare const ADAPTER_CAPABILITY_PROFILES_V3: Record<
|
|
19
|
-
export declare function adapterCapabilityProfileV3(adapter:
|
|
20
|
-
export declare function adapterCapabilityProfileDigestV3(adapter:
|
|
21
|
-
export declare function adapterSignalSupportV3(adapter:
|
|
19
|
+
export declare const ADAPTER_CAPABILITY_PROFILES_V3: Record<EventAdapterIdV3, AdapterCapabilityProfileV3>;
|
|
20
|
+
export declare function adapterCapabilityProfileV3(adapter: EventAdapterIdV3): AdapterCapabilityProfileV3;
|
|
21
|
+
export declare function adapterCapabilityProfileDigestV3(adapter: EventAdapterIdV3): `cap_${string}`;
|
|
22
|
+
export declare function adapterSignalSupportV3(adapter: EventAdapterIdV3, signal: AdapterSignalV3): CapabilitySupportV3;
|
|
23
|
+
/**
|
|
24
|
+
* Duration support for terminal spans. Tool duration is part of the digested
|
|
25
|
+
* adapter profile. Turn duration predates that profile dimension, so keep its
|
|
26
|
+
* compatibility-preserving classification here until the next contract major.
|
|
27
|
+
*/
|
|
28
|
+
export declare function adapterDurationSupportV3(adapter: EventAdapterIdV3, capability: AdapterDurationCapabilityV3): CapabilitySupportV3;
|
|
22
29
|
/**
|
|
23
30
|
* Adapter hooks only expose permission waits today. Other wait kinds can be
|
|
24
31
|
* authored by coordination producers, but they are not observable from an
|
|
25
32
|
* adapter's native turn channel.
|
|
26
33
|
*/
|
|
27
|
-
export declare function adapterWaitKindSupportV3(adapter:
|
|
34
|
+
export declare function adapterWaitKindSupportV3(adapter: EventAdapterIdV3, kind: AdapterWaitKindV3): CapabilitySupportV3;
|
|
28
35
|
/** No current adapter supplies an independent completed-turn wait aggregate. */
|
|
29
|
-
export declare function adapterTurnWaitCountSupportV3(_adapter:
|
|
36
|
+
export declare function adapterTurnWaitCountSupportV3(_adapter: EventAdapterIdV3): CapabilitySupportV3;
|
|
30
37
|
/**
|
|
31
38
|
* Per-kind wait matrix for native adapter turns. Span delivery and independent
|
|
32
39
|
* completed-turn completeness are deliberately separate: observing a span
|
|
33
40
|
* never proves that an absent span means zero.
|
|
34
41
|
*/
|
|
35
|
-
export declare function adapterWaitCoverageMatrixV3(adapter:
|
|
42
|
+
export declare function adapterWaitCoverageMatrixV3(adapter: EventAdapterIdV3): Record<AdapterWaitKindV3, WaitKindCapabilityV3>;
|
|
36
43
|
/**
|
|
37
44
|
* Local Cursor sessions expose the generic tool channel. Cloud/private-worker
|
|
38
45
|
* sessions cannot guarantee whole-turn delivery because hooks may start only
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,GAAG,aAAa,CAAC;AAEvF,MAAM,MAAM,2BAA2B,GAAG,eAAe,GAAG,eAAe,CAAC;AAE5E,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAElE,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,UAAU,GACV,WAAW,GACX,YAAY,GACZ,SAAS,CAAC;AAEd,eAAO,MAAM,qBAAqB,EAAE,SAAS,iBAAiB,EAQpD,CAAC;AAEX,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,mBAAmB,CAAC;IACnC,iBAAiB,EAAE,mBAAmB,CAAC;CACxC;AAED,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,aAAa,GACb,QAAQ,GACR,SAAS,GACT,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,aAAa,GACb,cAAc,GACd,cAAc,GACd,eAAe,GACf,YAAY,GACZ,UAAU,GACV,OAAO,GACP,gBAAgB,GAChB,iBAAiB,GACjB,eAAe,GACf,gBAAgB,CAAC;AAErB,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,aAAa,GACb,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,iCAAiC,CAAC;IAC1C,cAAc,EAAE,CAAC,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;CACvD;AA4FD,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,gBAAgB,EAAE,0BAA0B,CAsB7F,CAAC;AAEJ,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,0BAA0B,CAEhG;AAED,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,MAAM,EAAE,CAE3F;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,eAAe,GACtB,mBAAmB,CAErB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,2BAA2B,GACtC,mBAAmB,CAKrB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,iBAAiB,GACtB,mBAAmB,CAErB;AAED,gFAAgF;AAChF,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,CAE7F;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,CAUjD;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,qBAAqB,GAAG,mBAAmB,CAI3F"}
|
|
@@ -54,8 +54,28 @@ const BASE_SIGNAL_SUPPORT = {
|
|
|
54
54
|
post_compaction: "unsupported",
|
|
55
55
|
context_usage: "conditional",
|
|
56
56
|
},
|
|
57
|
+
openclaw: {
|
|
58
|
+
session_start: "conditional",
|
|
59
|
+
session_end: "native",
|
|
60
|
+
prompt: "native",
|
|
61
|
+
turn_id: "native",
|
|
62
|
+
turn_completion: "native",
|
|
63
|
+
assistant_reply_text: "unsupported",
|
|
64
|
+
tool_request: "native",
|
|
65
|
+
tool_result: "native",
|
|
66
|
+
tool_failure: "conditional",
|
|
67
|
+
tool_call_id: "native",
|
|
68
|
+
tool_duration: "unsupported",
|
|
69
|
+
permission: "unsupported",
|
|
70
|
+
subagent: "unsupported",
|
|
71
|
+
shell: "native",
|
|
72
|
+
pre_compaction: "unsupported",
|
|
73
|
+
post_compaction: "unsupported",
|
|
74
|
+
context_usage: "unsupported",
|
|
75
|
+
model_identity: "unsupported",
|
|
76
|
+
},
|
|
57
77
|
};
|
|
58
|
-
function profile(adapter, economics) {
|
|
78
|
+
function profile(adapter, economics, harnessTiming = "derived") {
|
|
59
79
|
return {
|
|
60
80
|
format: "harnery-v3-adapter-capabilities",
|
|
61
81
|
format_version: 1,
|
|
@@ -63,7 +83,7 @@ function profile(adapter, economics) {
|
|
|
63
83
|
signals: {
|
|
64
84
|
...BASE_SIGNAL_SUPPORT[adapter],
|
|
65
85
|
...economics,
|
|
66
|
-
harness_timing:
|
|
86
|
+
harness_timing: harnessTiming,
|
|
67
87
|
capability_drift: "derived",
|
|
68
88
|
},
|
|
69
89
|
};
|
|
@@ -81,6 +101,10 @@ export const ADAPTER_CAPABILITY_PROFILES_V3 = {
|
|
|
81
101
|
model_usage: "unsupported",
|
|
82
102
|
inference_timing: "unsupported",
|
|
83
103
|
}),
|
|
104
|
+
openclaw: profile("openclaw", {
|
|
105
|
+
model_usage: "unsupported",
|
|
106
|
+
inference_timing: "unsupported",
|
|
107
|
+
}, "unsupported"),
|
|
84
108
|
};
|
|
85
109
|
export function adapterCapabilityProfileV3(adapter) {
|
|
86
110
|
return ADAPTER_CAPABILITY_PROFILES_V3[adapter];
|
|
@@ -91,6 +115,17 @@ export function adapterCapabilityProfileDigestV3(adapter) {
|
|
|
91
115
|
export function adapterSignalSupportV3(adapter, signal) {
|
|
92
116
|
return adapterCapabilityProfileV3(adapter).signals[signal];
|
|
93
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Duration support for terminal spans. Tool duration is part of the digested
|
|
120
|
+
* adapter profile. Turn duration predates that profile dimension, so keep its
|
|
121
|
+
* compatibility-preserving classification here until the next contract major.
|
|
122
|
+
*/
|
|
123
|
+
export function adapterDurationSupportV3(adapter, capability) {
|
|
124
|
+
if (capability === "tool_duration") {
|
|
125
|
+
return adapterSignalSupportV3(adapter, "tool_duration");
|
|
126
|
+
}
|
|
127
|
+
return adapter === "openclaw" ? "unsupported" : "derived";
|
|
128
|
+
}
|
|
94
129
|
/**
|
|
95
130
|
* Adapter hooks only expose permission waits today. Other wait kinds can be
|
|
96
131
|
* authored by coordination producers, but they are not observable from an
|