harnery 0.35.0 → 0.37.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 +30 -5
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +128 -96
- package/dist/commands/agents.d.ts +23 -3
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +464 -242
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +26 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +10 -10
- package/dist/commands/browse-session.d.ts.map +1 -1
- package/dist/commands/browse-session.js +12 -0
- package/dist/commands/browse.d.ts +1 -1
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +16 -4
- package/dist/commands/conversations.d.ts +10 -0
- package/dist/commands/conversations.d.ts.map +1 -0
- package/dist/commands/conversations.js +201 -0
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +5 -0
- 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/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +13 -2
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +51 -7
- package/dist/commands/fetch.js +6 -5
- package/dist/commands/files.d.ts +34 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +166 -0
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +18 -12
- package/dist/commands/inbox.d.ts +5 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +57 -0
- package/dist/commands/init.d.ts +4 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +63 -13
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +417 -2
- package/dist/commands/logs.d.ts +4 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +169 -0
- package/dist/commands/messages.d.ts +5 -0
- package/dist/commands/messages.d.ts.map +1 -0
- package/dist/commands/messages.js +45 -0
- package/dist/commands/outline.d.ts +1 -1
- package/dist/commands/outline.d.ts.map +1 -1
- package/dist/commands/outline.js +2 -2
- package/dist/commands/qa-run.d.ts +4 -0
- package/dist/commands/qa-run.d.ts.map +1 -0
- package/dist/commands/qa-run.js +141 -0
- package/dist/commands/read.d.ts +1 -1
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +2 -2
- 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/semantic.d.ts.map +1 -1
- package/dist/commands/semantic.js +54 -2
- package/dist/commands/storage.d.ts +4 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +238 -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/tunnel.d.ts +5 -1
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +44 -31
- package/dist/commands/web.d.ts +3 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +84 -7
- package/dist/commands/work.js +3 -3
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +17 -13
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/cli.js +215 -41
- 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/live-authority-v3.d.ts +47 -1
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +244 -10
- package/dist/core/agents/live-lifecycle-v3.js +6 -1
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
- package/dist/core/agents/live-observation-v3.js +6 -1
- 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/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 +14 -3
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +54 -16
- 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 +2 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +93 -16
- package/dist/core/agents/rules/verdict.d.ts +1 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -1
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +4 -0
- package/dist/core/agents/session-finalization-state-v3.js +1 -1
- package/dist/core/agents/session-finalizer-v3.js +9 -2
- package/dist/core/agents/state/activity-log.d.ts +3 -0
- package/dist/core/agents/state/activity-log.d.ts.map +1 -1
- package/dist/core/agents/state/activity-log.js +6 -3
- package/dist/core/agents/state/heartbeat-writer.d.ts +6 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +18 -0
- package/dist/core/agents/state/live-coordination-view.d.ts +5 -7
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +15 -90
- package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
- package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +92 -0
- package/dist/core/artifacts/index.d.ts +47 -1
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +191 -6
- package/dist/core/config.d.ts +74 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +141 -4
- package/dist/core/conversations/archive.d.ts +49 -0
- package/dist/core/conversations/archive.d.ts.map +1 -0
- package/dist/core/conversations/archive.js +136 -0
- package/dist/core/conversations/catalog.d.ts +10 -0
- package/dist/core/conversations/catalog.d.ts.map +1 -0
- package/dist/core/conversations/catalog.js +72 -0
- package/dist/core/conversations/context-pack.d.ts +6 -0
- package/dist/core/conversations/context-pack.d.ts.map +1 -0
- package/dist/core/conversations/context-pack.js +60 -0
- package/dist/core/conversations/contract.d.ts +155 -0
- package/dist/core/conversations/contract.d.ts.map +1 -0
- package/dist/core/conversations/contract.js +1 -0
- package/dist/core/conversations/evaluation.d.ts +16 -0
- package/dist/core/conversations/evaluation.d.ts.map +1 -0
- package/dist/core/conversations/evaluation.js +9 -0
- package/dist/core/conversations/index.d.ts +10 -0
- package/dist/core/conversations/index.d.ts.map +1 -0
- package/dist/core/conversations/index.js +9 -0
- package/dist/core/conversations/lifecycle.d.ts +28 -0
- package/dist/core/conversations/lifecycle.d.ts.map +1 -0
- package/dist/core/conversations/lifecycle.js +29 -0
- package/dist/core/conversations/normalize.d.ts +14 -0
- package/dist/core/conversations/normalize.d.ts.map +1 -0
- package/dist/core/conversations/normalize.js +82 -0
- package/dist/core/conversations/query.d.ts +8 -0
- package/dist/core/conversations/query.d.ts.map +1 -0
- package/dist/core/conversations/query.js +280 -0
- package/dist/core/conversations/search-index.d.ts +9 -0
- package/dist/core/conversations/search-index.d.ts.map +1 -0
- package/dist/core/conversations/search-index.js +29 -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 +35 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -0
- package/dist/core/diagnostics/bundle.js +874 -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/canary.d.ts +18 -0
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/canary.js +150 -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/fence.d.ts +15 -0
- package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/fence.js +115 -0
- package/dist/core/events/legacy-storage/index.d.ts +7 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/index.js +6 -0
- package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
- package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/inventory.js +40 -0
- package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
- package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/manifest.js +108 -0
- package/dist/core/events/legacy-storage/reader.d.ts +15 -0
- package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/reader.js +154 -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/authority-outbox.d.ts +7 -2
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +16 -3
- package/dist/core/events/v3/base-contract.d.ts +81 -41
- package/dist/core/events/v3/base-contract.d.ts.map +1 -1
- package/dist/core/events/v3/base-contract.js +17 -7
- package/dist/core/events/v3/bootstrap.d.ts +39 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +167 -3
- 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 +4 -3
- package/dist/core/events/v3/control-witness.d.ts +44 -0
- package/dist/core/events/v3/control-witness.d.ts.map +1 -0
- package/dist/core/events/v3/control-witness.js +233 -0
- package/dist/core/events/v3/control-writer.d.ts +4 -0
- package/dist/core/events/v3/control-writer.d.ts.map +1 -0
- package/dist/core/events/v3/control-writer.js +16 -0
- package/dist/core/events/v3/control.d.ts +8 -2
- package/dist/core/events/v3/control.d.ts.map +1 -1
- package/dist/core/events/v3/control.js +46 -18
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
- package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +16 -1
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/index.d.ts +5 -2
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +4 -1
- package/dist/core/events/v3/live-route-observer.d.ts +31 -0
- package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
- package/dist/core/events/v3/live-route-observer.js +58 -0
- package/dist/core/events/v3/live-routing.d.ts +13 -21
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +46 -41
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +76 -10
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
- package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -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 +14 -3
- package/dist/core/events/v3/producers/intake.d.ts +7 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +26 -2
- package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
- package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
- package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
- package/dist/core/events/v3/producers/recorder.d.ts +71 -1
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +441 -25
- package/dist/core/events/v3/reader.d.ts +51 -0
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +181 -1
- package/dist/core/events/v3/rotation-config.d.ts +9 -0
- package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
- package/dist/core/events/v3/rotation-config.js +91 -0
- package/dist/core/events/v3/runtime-build.d.ts +11 -0
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-build.js +39 -0
- package/dist/core/events/v3/runtime-identity.d.ts +5 -0
- package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-identity.js +18 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +6 -5
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-telemetry-capabilities.js +1 -1
- package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
- package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/classify.js +149 -0
- package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
- package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/eligibility.js +35 -0
- package/dist/core/events/v3/support-storage/index.d.ts +10 -0
- package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/index.js +9 -0
- package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/inventory.js +94 -0
- package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
- package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
- package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/maintenance.js +352 -0
- package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
- package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
- package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
- package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
- package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
- package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/recovery.js +22 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +14 -8
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/events/v3/turn-telemetry.js +32 -2
- package/dist/core/events/v3/writer.d.ts +13 -1
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +126 -12
- package/dist/core/governor/plan-read.d.ts.map +1 -1
- package/dist/core/governor/plan-read.js +5 -21
- package/dist/core/governor/planning.js +6 -8
- package/dist/core/governor/service-read.d.ts +12 -0
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +266 -2
- package/dist/core/governor/service.d.ts +1 -0
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +53 -18
- package/dist/core/guard/evidence-v3.d.ts.map +1 -1
- package/dist/core/guard/evidence-v3.js +2 -0
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +1 -0
- package/dist/core/hooks/adapter/output.d.ts +12 -2
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +23 -5
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts +27 -4
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/runtime-telemetry.js +307 -6
- package/dist/core/hooks/cli.js +380 -207
- package/dist/core/hooks/effects/image-capture.d.ts +1 -1
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +4 -2
- 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/remediation-cap.d.ts +8 -3
- package/dist/core/hooks/remediation-cap.d.ts.map +1 -1
- package/dist/core/hooks/remediation-cap.js +3 -11
- package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
- package/dist/core/hooks/resolve/coord-root.js +92 -11
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +5 -0
- package/dist/core/hooks/resolve/transcript.d.ts +8 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +11 -0
- package/dist/core/inbox/contract.d.ts +64 -0
- package/dist/core/inbox/contract.d.ts.map +1 -0
- package/dist/core/inbox/contract.js +13 -0
- package/dist/core/inbox/index.d.ts +5 -0
- package/dist/core/inbox/index.d.ts.map +1 -0
- package/dist/core/inbox/index.js +4 -0
- package/dist/core/inbox/lifecycle.d.ts +22 -0
- package/dist/core/inbox/lifecycle.d.ts.map +1 -0
- package/dist/core/inbox/lifecycle.js +41 -0
- package/dist/core/inbox/service.d.ts +36 -0
- package/dist/core/inbox/service.d.ts.map +1 -0
- package/dist/core/inbox/service.js +210 -0
- package/dist/core/inbox/watcher.d.ts +7 -0
- package/dist/core/inbox/watcher.d.ts.map +1 -0
- package/dist/core/inbox/watcher.js +26 -0
- package/dist/core/presence/codec-digest.d.ts.map +1 -1
- package/dist/core/presence/codec-digest.js +14 -3
- package/dist/core/presence/relay-client.d.ts +1 -0
- package/dist/core/presence/relay-client.d.ts.map +1 -1
- package/dist/core/presence/relay-client.js +52 -8
- package/dist/core/resources/contract.d.ts +90 -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 +27 -0
- package/dist/core/resources/sampler.d.ts.map +1 -0
- package/dist/core/resources/sampler.js +357 -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/semantic/adapters.d.ts +11 -8
- package/dist/core/semantic/adapters.d.ts.map +1 -1
- package/dist/core/semantic/adapters.js +169 -31
- package/dist/core/semantic/contract.d.ts +532 -48
- package/dist/core/semantic/contract.d.ts.map +1 -1
- package/dist/core/semantic/contract.js +104 -3
- package/dist/core/semantic/index.d.ts +7 -3
- package/dist/core/semantic/index.d.ts.map +1 -1
- package/dist/core/semantic/index.js +7 -3
- package/dist/core/semantic/once.d.ts +6 -1
- package/dist/core/semantic/once.d.ts.map +1 -1
- package/dist/core/semantic/once.js +80 -9
- package/dist/core/semantic/prompt.d.ts.map +1 -1
- package/dist/core/semantic/prompt.js +14 -1
- package/dist/core/semantic/review.d.ts +144 -0
- package/dist/core/semantic/review.d.ts.map +1 -0
- package/dist/core/semantic/review.js +544 -0
- package/dist/core/semantic/routes.d.ts +10 -0
- package/dist/core/semantic/routes.d.ts.map +1 -0
- package/dist/core/semantic/routes.js +21 -0
- package/dist/core/semantic/scheduler.d.ts +14 -3
- package/dist/core/semantic/scheduler.d.ts.map +1 -1
- package/dist/core/semantic/scheduler.js +30 -6
- package/dist/core/semantic/service-status.d.ts +20 -0
- package/dist/core/semantic/service-status.d.ts.map +1 -1
- package/dist/core/semantic/service-status.js +60 -4
- package/dist/core/semantic/service.d.ts +1 -0
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +104 -15
- package/dist/core/semantic/soak.d.ts +75 -0
- package/dist/core/semantic/soak.d.ts.map +1 -0
- package/dist/core/semantic/soak.js +476 -0
- package/dist/core/semantic/storage.d.ts +11 -1
- package/dist/core/semantic/storage.d.ts.map +1 -1
- package/dist/core/semantic/storage.js +4 -3
- package/dist/core/semantic/usage.d.ts +43 -0
- package/dist/core/semantic/usage.d.ts.map +1 -0
- package/dist/core/semantic/usage.js +193 -0
- package/dist/core/semantic/validate.d.ts +3 -1
- package/dist/core/semantic/validate.d.ts.map +1 -1
- package/dist/core/semantic/validate.js +34 -1
- 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/buffer.d.ts +28 -0
- package/dist/core/storage/buffer.d.ts.map +1 -0
- package/dist/core/storage/buffer.js +101 -0
- package/dist/core/storage/builtins.d.ts +3 -0
- package/dist/core/storage/builtins.d.ts.map +1 -0
- package/dist/core/storage/builtins.js +722 -0
- package/dist/core/storage/catalog.d.ts +19 -0
- package/dist/core/storage/catalog.d.ts.map +1 -0
- package/dist/core/storage/catalog.js +365 -0
- package/dist/core/storage/config.d.ts +16 -0
- package/dist/core/storage/config.d.ts.map +1 -0
- package/dist/core/storage/config.js +311 -0
- package/dist/core/storage/contract.d.ts +275 -0
- package/dist/core/storage/contract.d.ts.map +1 -0
- package/dist/core/storage/contract.js +3 -0
- package/dist/core/storage/durable-history.d.ts +36 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -0
- package/dist/core/storage/durable-history.js +606 -0
- package/dist/core/storage/health.d.ts +4 -0
- package/dist/core/storage/health.d.ts.map +1 -0
- package/dist/core/storage/health.js +65 -0
- package/dist/core/storage/index.d.ts +16 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +15 -0
- package/dist/core/storage/inventory.d.ts +25 -0
- package/dist/core/storage/inventory.d.ts.map +1 -0
- package/dist/core/storage/inventory.js +666 -0
- package/dist/core/storage/jsonl.d.ts +52 -0
- package/dist/core/storage/jsonl.d.ts.map +1 -0
- package/dist/core/storage/jsonl.js +156 -0
- package/dist/core/storage/log-retention.d.ts +52 -0
- package/dist/core/storage/log-retention.d.ts.map +1 -0
- package/dist/core/storage/log-retention.js +419 -0
- package/dist/core/storage/logger.d.ts +84 -0
- package/dist/core/storage/logger.d.ts.map +1 -0
- package/dist/core/storage/logger.js +413 -0
- package/dist/core/storage/maintenance-providers.d.ts +26 -0
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
- package/dist/core/storage/maintenance-providers.js +141 -0
- package/dist/core/storage/maintenance.d.ts +125 -0
- package/dist/core/storage/maintenance.d.ts.map +1 -0
- package/dist/core/storage/maintenance.js +609 -0
- package/dist/core/storage/metrics.d.ts +60 -0
- package/dist/core/storage/metrics.d.ts.map +1 -0
- package/dist/core/storage/metrics.js +134 -0
- package/dist/core/storage/policy.d.ts +7 -0
- package/dist/core/storage/policy.d.ts.map +1 -0
- package/dist/core/storage/policy.js +110 -0
- package/dist/core/storage/process-log.d.ts +38 -0
- package/dist/core/storage/process-log.d.ts.map +1 -0
- package/dist/core/storage/process-log.js +165 -0
- package/dist/core/storage/query.d.ts +48 -0
- package/dist/core/storage/query.d.ts.map +1 -0
- package/dist/core/storage/query.js +346 -0
- package/dist/core/storage/receipts.d.ts +23 -0
- package/dist/core/storage/receipts.d.ts.map +1 -0
- package/dist/core/storage/receipts.js +117 -0
- package/dist/core/storage/segments.d.ts +84 -0
- package/dist/core/storage/segments.d.ts.map +1 -0
- package/dist/core/storage/segments.js +542 -0
- package/dist/core/storage/sink-graph.d.ts +65 -0
- package/dist/core/storage/sink-graph.d.ts.map +1 -0
- package/dist/core/storage/sink-graph.js +213 -0
- package/dist/core/storage/storm-control.d.ts +23 -0
- package/dist/core/storage/storm-control.d.ts.map +1 -0
- package/dist/core/storage/storm-control.js +59 -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/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +10 -14
- 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/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lazy-commands.d.ts +26 -0
- package/dist/lazy-commands.d.ts.map +1 -0
- package/dist/lazy-commands.js +210 -0
- package/dist/lib/browser/client.d.ts +5 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +1 -0
- package/dist/lib/browser/index.d.ts +2 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +173 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
- package/dist/lib/browser/qa-run-contracts.js +226 -0
- package/dist/lib/browser/qa-run.d.ts +51 -0
- package/dist/lib/browser/qa-run.d.ts.map +1 -0
- package/dist/lib/browser/qa-run.js +684 -0
- 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/docs-lint.d.ts +2 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +45 -80
- package/dist/lib/docs-metadata-audit.d.ts +3 -0
- package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
- package/dist/lib/docs-metadata-audit.js +13 -23
- package/dist/lib/docs-metadata-sync.d.ts +1 -0
- package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
- package/dist/lib/docs-metadata-sync.js +28 -10
- package/dist/lib/docs-repository-view.d.ts +22 -0
- package/dist/lib/docs-repository-view.d.ts.map +1 -0
- package/dist/lib/docs-repository-view.js +185 -0
- package/dist/lib/http/client.d.ts +11 -5
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +22 -4
- package/dist/lib/http/index.d.ts +1 -1
- package/dist/lib/http/index.d.ts.map +1 -1
- package/dist/lib/http/index.js +1 -1
- package/dist/lib/indexer-exclusions.d.ts +27 -0
- package/dist/lib/indexer-exclusions.d.ts.map +1 -0
- package/dist/lib/indexer-exclusions.js +176 -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 -0
- package/dist/lib/local-file-url.d.ts +9 -0
- package/dist/lib/local-file-url.d.ts.map +1 -0
- package/dist/lib/local-file-url.js +20 -0
- package/dist/lib/web-performance.d.ts +118 -0
- package/dist/lib/web-performance.d.ts.map +1 -0
- package/dist/lib/web-performance.js +192 -0
- package/package.json +40 -2
- package/schemas/config.schema.json +58 -0
- package/schemas/event-v3.schema.json +324 -112
- package/src/commander.ts +488 -95
- package/src/commands/agents.ts +617 -237
- package/src/commands/artifacts.ts +40 -2
- package/src/commands/backup.ts +18 -14
- package/src/commands/browse-session.ts +12 -0
- package/src/commands/browse.ts +21 -7
- package/src/commands/conversations.ts +279 -0
- package/src/commands/deinit.ts +6 -0
- package/src/commands/diagnostics.ts +271 -0
- package/src/commands/docs.ts +25 -6
- package/src/commands/doctor.ts +75 -9
- package/src/commands/fetch.ts +7 -6
- package/src/commands/files.ts +243 -0
- package/src/commands/governor.ts +21 -12
- package/src/commands/inbox.ts +61 -0
- package/src/commands/init.ts +78 -16
- package/src/commands/ledger-v3.ts +503 -1
- package/src/commands/logs.ts +224 -0
- package/src/commands/messages.ts +61 -0
- package/src/commands/outline.ts +6 -2
- package/src/commands/qa-run.ts +184 -0
- package/src/commands/read.ts +6 -2
- package/src/commands/resources.ts +38 -0
- package/src/commands/semantic.ts +66 -1
- package/src/commands/storage.ts +310 -0
- package/src/commands/supervisor.ts +141 -0
- package/src/commands/tunnel.ts +66 -52
- package/src/commands/web.ts +96 -7
- package/src/commands/work.ts +3 -3
- package/src/commands/workflow.ts +21 -13
- package/src/core/agents/cli.ts +265 -55
- package/src/core/agents/health.ts +142 -0
- package/src/core/agents/live-authority-v3.ts +341 -10
- package/src/core/agents/live-lifecycle-v3.ts +6 -1
- package/src/core/agents/live-observation-v3.ts +6 -1
- package/src/core/agents/mailbox.ts +373 -0
- package/src/core/agents/reconcile-coordination-v3.ts +77 -0
- package/src/core/agents/render/prompt-context.ts +66 -15
- 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 +105 -20
- package/src/core/agents/rules/verdict.ts +1 -0
- package/src/core/agents/session-events.ts +4 -0
- package/src/core/agents/session-finalization-state-v3.ts +1 -1
- package/src/core/agents/session-finalizer-v3.ts +8 -2
- package/src/core/agents/state/activity-log.ts +7 -2
- package/src/core/agents/state/heartbeat-writer.ts +27 -0
- package/src/core/agents/state/live-coordination-view.ts +16 -105
- package/src/core/agents/state/live-coordination-writer.ts +141 -0
- package/src/core/artifacts/index.ts +260 -11
- package/src/core/config.ts +235 -5
- package/src/core/conversations/archive.ts +237 -0
- package/src/core/conversations/catalog.ts +79 -0
- package/src/core/conversations/context-pack.ts +72 -0
- package/src/core/conversations/contract.ts +178 -0
- package/src/core/conversations/evaluation.ts +30 -0
- package/src/core/conversations/index.ts +9 -0
- package/src/core/conversations/lifecycle.ts +63 -0
- package/src/core/conversations/normalize.ts +105 -0
- package/src/core/conversations/query.ts +318 -0
- package/src/core/conversations/search-index.ts +48 -0
- package/src/core/diagnostics/advice.ts +147 -0
- package/src/core/diagnostics/bundle.ts +1142 -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/canary.ts +177 -0
- package/src/core/events/legacy-storage/compression.ts +130 -0
- package/src/core/events/legacy-storage/fence.ts +129 -0
- package/src/core/events/legacy-storage/index.ts +6 -0
- package/src/core/events/legacy-storage/inventory.ts +51 -0
- package/src/core/events/legacy-storage/manifest.ts +136 -0
- package/src/core/events/legacy-storage/reader.ts +178 -0
- package/src/core/events/v3/archive-retention.ts +251 -0
- package/src/core/events/v3/authority-outbox.ts +22 -1
- package/src/core/events/v3/base-contract.ts +17 -7
- package/src/core/events/v3/bootstrap.ts +195 -2
- package/src/core/events/v3/capabilities.ts +5 -3
- package/src/core/events/v3/control-witness.ts +339 -0
- package/src/core/events/v3/control-writer.ts +16 -0
- package/src/core/events/v3/control.ts +54 -18
- package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
- package/src/core/events/v3/coordination-view.ts +17 -1
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/index.ts +14 -2
- package/src/core/events/v3/live-route-observer.ts +80 -0
- package/src/core/events/v3/live-routing.ts +65 -46
- package/src/core/events/v3/producers/coordination-recorder.ts +95 -10
- package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
- package/src/core/events/v3/producers/hook-base.ts +15 -3
- package/src/core/events/v3/producers/intake.ts +31 -2
- package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
- package/src/core/events/v3/producers/recorder.ts +681 -34
- package/src/core/events/v3/reader.ts +243 -2
- package/src/core/events/v3/rotation-config.ts +98 -0
- package/src/core/events/v3/runtime-build.ts +41 -0
- package/src/core/events/v3/runtime-identity.ts +16 -0
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +14 -8
- package/src/core/events/v3/support-storage/classify.ts +209 -0
- package/src/core/events/v3/support-storage/eligibility.ts +58 -0
- package/src/core/events/v3/support-storage/index.ts +9 -0
- package/src/core/events/v3/support-storage/inventory.ts +135 -0
- package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
- package/src/core/events/v3/support-storage/maintenance.ts +501 -0
- package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
- package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
- package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
- package/src/core/events/v3/support-storage/recovery.ts +43 -0
- package/src/core/events/v3/turn-telemetry.ts +58 -7
- package/src/core/events/v3/writer.ts +168 -16
- package/src/core/governor/plan-read.ts +5 -18
- package/src/core/governor/planning.ts +5 -8
- package/src/core/governor/service-read.ts +320 -2
- package/src/core/governor/service.ts +49 -22
- package/src/core/guard/evidence-v3.ts +1 -0
- package/src/core/hooks/adapter/events.ts +1 -0
- package/src/core/hooks/adapter/output.ts +23 -5
- package/src/core/hooks/adapter/runtime-telemetry.ts +408 -13
- package/src/core/hooks/cli.ts +404 -233
- package/src/core/hooks/effects/image-capture.ts +4 -1
- package/src/core/hooks/health.ts +146 -0
- package/src/core/hooks/remediation-cap.ts +12 -6
- package/src/core/hooks/resolve/coord-root.ts +91 -11
- package/src/core/hooks/resolve/owner.ts +4 -0
- package/src/core/hooks/resolve/transcript.ts +18 -0
- package/src/core/inbox/contract.ts +81 -0
- package/src/core/inbox/index.ts +4 -0
- package/src/core/inbox/lifecycle.ts +104 -0
- package/src/core/inbox/service.ts +305 -0
- package/src/core/inbox/watcher.ts +36 -0
- package/src/core/presence/codec-digest.ts +15 -9
- package/src/core/presence/relay-client.ts +55 -7
- package/src/core/resources/contract.ts +98 -0
- package/src/core/resources/index.ts +5 -0
- package/src/core/resources/sampler.ts +458 -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/semantic/adapters.ts +200 -41
- package/src/core/semantic/contract.ts +135 -3
- package/src/core/semantic/index.ts +76 -2
- package/src/core/semantic/once.ts +93 -7
- package/src/core/semantic/prompt.ts +13 -1
- package/src/core/semantic/review.ts +803 -0
- package/src/core/semantic/routes.ts +30 -0
- package/src/core/semantic/scheduler.ts +49 -5
- package/src/core/semantic/service-status.ts +99 -5
- package/src/core/semantic/service.ts +116 -15
- package/src/core/semantic/soak.ts +638 -0
- package/src/core/semantic/storage.ts +20 -6
- package/src/core/semantic/usage.ts +272 -0
- package/src/core/semantic/validate.ts +31 -0
- package/src/core/storage/atomic-json.ts +15 -0
- package/src/core/storage/buffer.ts +124 -0
- package/src/core/storage/builtins.ts +972 -0
- package/src/core/storage/catalog.ts +467 -0
- package/src/core/storage/config.ts +423 -0
- package/src/core/storage/contract.ts +342 -0
- package/src/core/storage/durable-history.ts +738 -0
- package/src/core/storage/health.ts +76 -0
- package/src/core/storage/index.ts +15 -0
- package/src/core/storage/inventory.ts +859 -0
- package/src/core/storage/jsonl.ts +213 -0
- package/src/core/storage/log-retention.ts +555 -0
- package/src/core/storage/logger.ts +548 -0
- package/src/core/storage/maintenance-providers.ts +200 -0
- package/src/core/storage/maintenance.ts +929 -0
- package/src/core/storage/metrics.ts +199 -0
- package/src/core/storage/policy.ts +141 -0
- package/src/core/storage/process-log.ts +203 -0
- package/src/core/storage/query.ts +418 -0
- package/src/core/storage/receipts.ts +162 -0
- package/src/core/storage/segments.ts +721 -0
- package/src/core/storage/sink-graph.ts +343 -0
- package/src/core/storage/storm-control.ts +91 -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/work/state.ts +12 -21
- 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/live-session-v3.ts +2 -4
- 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/index.ts +2 -0
- package/src/lazy-commands.ts +294 -0
- package/src/lib/browser/client.ts +6 -0
- package/src/lib/browser/index.ts +29 -0
- package/src/lib/browser/qa-run-contracts.ts +380 -0
- package/src/lib/browser/qa-run.ts +784 -0
- package/src/lib/coord-root-id.ts +23 -0
- package/src/lib/docs-lint.ts +58 -77
- package/src/lib/docs-metadata-audit.ts +26 -21
- package/src/lib/docs-metadata-sync.ts +32 -9
- package/src/lib/docs-repository-view.ts +220 -0
- package/src/lib/http/client.ts +44 -8
- package/src/lib/http/index.ts +6 -1
- package/src/lib/indexer-exclusions.ts +173 -0
- package/src/lib/instructions/apply.ts +81 -2
- package/src/lib/instructions/templates.ts +11 -0
- package/src/lib/local-file-url.ts +31 -0
- package/src/lib/web-performance.ts +335 -0
package/src/commands/agents.ts
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
rmSync,
|
|
24
24
|
writeFileSync,
|
|
25
25
|
} from "node:fs";
|
|
26
|
-
import {
|
|
26
|
+
import { tmpdir } from "node:os";
|
|
27
27
|
import { basename, join, resolve } from "node:path";
|
|
28
28
|
import type { Command } from "commander";
|
|
29
29
|
import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
@@ -44,7 +44,19 @@ import {
|
|
|
44
44
|
resolveOwnerWithSource,
|
|
45
45
|
sessionIdentityFromEnv,
|
|
46
46
|
} from "../core/agents/index.ts";
|
|
47
|
-
import {
|
|
47
|
+
import {
|
|
48
|
+
bootstrapLiveCoordinationAuthorityV3,
|
|
49
|
+
LiveCoordinationAuthorityV3Error,
|
|
50
|
+
reopenLiveCoordinationGenerationV3,
|
|
51
|
+
} from "../core/agents/live-authority-v3.ts";
|
|
52
|
+
import {
|
|
53
|
+
isAddressableName,
|
|
54
|
+
MailboxCapacityError,
|
|
55
|
+
type QueueResult,
|
|
56
|
+
queueMailboxMessage,
|
|
57
|
+
suggestNames,
|
|
58
|
+
} from "../core/agents/mailbox.ts";
|
|
59
|
+
import { reconcileCoordinationV3 } from "../core/agents/reconcile-coordination-v3.ts";
|
|
48
60
|
import {
|
|
49
61
|
listSessionFinalizationRequestsV3,
|
|
50
62
|
observeHostDisappearedV3,
|
|
@@ -56,6 +68,7 @@ import {
|
|
|
56
68
|
SESSION_NAME_DISPLAY_NOTE,
|
|
57
69
|
sessionNameDisplayPending,
|
|
58
70
|
} from "../core/agents/session-name-display.ts";
|
|
71
|
+
import { agentDisplayName } from "../core/agents/state/activity-log.ts";
|
|
59
72
|
import {
|
|
60
73
|
buildLifecycleSuggestedName,
|
|
61
74
|
buildSuggestedName,
|
|
@@ -80,6 +93,10 @@ import type { EventTypeV3 } from "../core/events/v3/contract.ts";
|
|
|
80
93
|
import { readEventV3ControlState } from "../core/events/v3/control.ts";
|
|
81
94
|
import { projectCoordinationViewV3 } from "../core/events/v3/coordination-view.ts";
|
|
82
95
|
import { liveInstanceIdV3 } from "../core/events/v3/live-routing.ts";
|
|
96
|
+
import {
|
|
97
|
+
countSummarizedSinceV3,
|
|
98
|
+
listDiagnosticSummariesV3,
|
|
99
|
+
} from "../core/events/v3/producers/diagnostic-summaries.ts";
|
|
83
100
|
import {
|
|
84
101
|
listHookIntakeGroupsV3,
|
|
85
102
|
listHookIntakeRecordsV3,
|
|
@@ -92,7 +109,10 @@ import { readLedgerV3 } from "../core/events/v3/reader.ts";
|
|
|
92
109
|
import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../core/events/v3/writer.ts";
|
|
93
110
|
import type { RunQualitySnapshot, RunQualityStatus } from "../core/guard/index.ts";
|
|
94
111
|
import { evaluateRunQualityIfDue } from "../core/guard/index.ts";
|
|
95
|
-
import {
|
|
112
|
+
import {
|
|
113
|
+
readRuntimeContextTelemetry,
|
|
114
|
+
readRuntimeContextUsage,
|
|
115
|
+
} from "../core/hooks/adapter/runtime-telemetry.ts";
|
|
96
116
|
import { type RemoteMachine, readRemoteMachines } from "../core/presence/index.ts";
|
|
97
117
|
import { registerContextCommand } from "./context.ts";
|
|
98
118
|
|
|
@@ -264,6 +284,7 @@ export function registerAgentsCommand(
|
|
|
264
284
|
program: Command,
|
|
265
285
|
emitParam: EmitContext,
|
|
266
286
|
programContext?: HarneryProgramContext,
|
|
287
|
+
binName = resolveBinName(),
|
|
267
288
|
): void {
|
|
268
289
|
emit = emitParam;
|
|
269
290
|
const cmd = program
|
|
@@ -385,7 +406,7 @@ export function registerAgentsCommand(
|
|
|
385
406
|
)
|
|
386
407
|
.option(
|
|
387
408
|
"--session-id <id>",
|
|
388
|
-
`Set the task on the heartbeat with this session_id directly, bypassing the ppid walk. Mirror of \`status --session-id\`: use it when the ppid walk can't resolve self (e.g. Cursor, whose shell tool calls don't descend from a pid-map-registered anchor). Discover the id via \`${
|
|
409
|
+
`Set the task on the heartbeat with this session_id directly, bypassing the ppid walk. Mirror of \`status --session-id\`: use it when the ppid walk can't resolve self (e.g. Cursor, whose shell tool calls don't descend from a pid-map-registered anchor). Discover the id via \`${binName} agents list --json\`.`,
|
|
389
410
|
)
|
|
390
411
|
.action((text: string[], opts: { sessionId?: string }) => {
|
|
391
412
|
runSetTask(text.join(" "), opts);
|
|
@@ -422,7 +443,8 @@ export function registerAgentsCommand(
|
|
|
422
443
|
cmd
|
|
423
444
|
.command("reconcile")
|
|
424
445
|
.description(
|
|
425
|
-
"
|
|
446
|
+
"Sweep the stale coordination cache, then reconcile archive, idle, parent/run " +
|
|
447
|
+
"completion, stale, superseded, and host lifecycle signals into V3 session finalization.",
|
|
426
448
|
)
|
|
427
449
|
.option("--watch", "Keep reconciling until interrupted")
|
|
428
450
|
.option("--interval-seconds <n>", "Watch interval in seconds")
|
|
@@ -472,9 +494,10 @@ export function registerAgentsCommand(
|
|
|
472
494
|
cmd
|
|
473
495
|
.command("ping <name> <message...>")
|
|
474
496
|
.description(
|
|
475
|
-
"
|
|
476
|
-
"
|
|
477
|
-
"
|
|
497
|
+
"Send a message to another agent by name. Works whether or not that agent " +
|
|
498
|
+
"is running: a live peer sees it on their next prompt, and a name with no " +
|
|
499
|
+
"live session gets it queued until a session of that name next starts. " +
|
|
500
|
+
"Only an unknown name is refused.",
|
|
478
501
|
)
|
|
479
502
|
.option("--json", "JSON output")
|
|
480
503
|
.action((name: string, message: string[], opts: { json?: boolean }) => {
|
|
@@ -484,7 +507,7 @@ export function registerAgentsCommand(
|
|
|
484
507
|
cmd
|
|
485
508
|
.command("wait <name>")
|
|
486
509
|
.description(
|
|
487
|
-
`Block until a peer agent releases files (their \`files_touched\` becomes empty, OR they exit). Pair with \`${
|
|
510
|
+
`Block until a peer agent releases files (their \`files_touched\` becomes empty, OR they exit). Pair with \`${binName} agents ping\` to coordinate hand-offs.`,
|
|
488
511
|
)
|
|
489
512
|
.option(
|
|
490
513
|
"--file <path>",
|
|
@@ -533,7 +556,7 @@ export function registerAgentsCommand(
|
|
|
533
556
|
.command("health")
|
|
534
557
|
.description(
|
|
535
558
|
"One-screen coord-layer health rollup: heal events, council activity, " +
|
|
536
|
-
"
|
|
559
|
+
"heartbeat cache issues, and findings. Designed for " +
|
|
537
560
|
"daily glance + dashboard ingestion. Reads .harnery/.",
|
|
538
561
|
)
|
|
539
562
|
.option("--since <window>", "Window (Nh | Nd). Default: 24h.", "24h")
|
|
@@ -567,12 +590,11 @@ export function registerAgentsCommand(
|
|
|
567
590
|
cmd
|
|
568
591
|
.command("heal")
|
|
569
592
|
.description(
|
|
570
|
-
"
|
|
571
|
-
"
|
|
572
|
-
"disposable V3 coordination cache from the authoritative ledger).",
|
|
593
|
+
"Repair the current session's disposable coordination cache from V3. " +
|
|
594
|
+
"Use explicit options to target another generation or repair process attribution.",
|
|
573
595
|
)
|
|
574
|
-
.
|
|
575
|
-
.
|
|
596
|
+
.option("--owner <id>", "Target agent's instance_id. Defaults to the current session.")
|
|
597
|
+
.option("--kind <kind>", "pidmap | cache. Defaults to cache.")
|
|
576
598
|
.option(
|
|
577
599
|
"--session-id <id>",
|
|
578
600
|
"(--kind cache) native session id used to join the authoritative V3 generation.",
|
|
@@ -589,14 +611,26 @@ export function registerAgentsCommand(
|
|
|
589
611
|
"when calling from outside Claude Code's Bash tool tree (e.g. " +
|
|
590
612
|
"from cron or an external script).",
|
|
591
613
|
)
|
|
614
|
+
.option(
|
|
615
|
+
"--quarantine-transaction <id>",
|
|
616
|
+
"Quarantine one irreconcilable prepared authority transaction after proving its event was never committed.",
|
|
617
|
+
)
|
|
618
|
+
.option(
|
|
619
|
+
"--approval-record-id <id>",
|
|
620
|
+
"Durable identifier for the operator approval authorizing transaction quarantine.",
|
|
621
|
+
)
|
|
622
|
+
.option("--yes", "Confirm the exact prepared transaction may be quarantined.")
|
|
592
623
|
.option("--json", "JSON envelope output")
|
|
593
624
|
.action(
|
|
594
625
|
(opts: {
|
|
595
|
-
owner
|
|
596
|
-
kind
|
|
626
|
+
owner?: string;
|
|
627
|
+
kind?: string;
|
|
597
628
|
sessionId?: string;
|
|
598
629
|
adapter?: string;
|
|
599
630
|
pid?: string;
|
|
631
|
+
quarantineTransaction?: string;
|
|
632
|
+
approvalRecordId?: string;
|
|
633
|
+
yes?: boolean;
|
|
600
634
|
json?: boolean;
|
|
601
635
|
}) => {
|
|
602
636
|
runHeal(opts);
|
|
@@ -723,7 +757,7 @@ async function runSessionReconcile(opts: {
|
|
|
723
757
|
}
|
|
724
758
|
let stopped = false;
|
|
725
759
|
do {
|
|
726
|
-
emit.data(
|
|
760
|
+
emit.data(reconcileCoordinationV3(root));
|
|
727
761
|
if (!opts.watch || stopped) return;
|
|
728
762
|
await new Promise<void>((resolvePromise) => {
|
|
729
763
|
const timer = setTimeout(resolvePromise, interval * 1_000);
|
|
@@ -935,14 +969,15 @@ function runIdentityAssume(
|
|
|
935
969
|
});
|
|
936
970
|
process.exit(1);
|
|
937
971
|
}
|
|
938
|
-
if (!opts.sessionId)
|
|
972
|
+
if (!opts.sessionId) ensureAdapterSession(root);
|
|
939
973
|
const owner = opts.sessionId ?? resolveOwner();
|
|
940
974
|
if (!owner) {
|
|
941
|
-
emit.error(
|
|
942
|
-
|
|
943
|
-
|
|
975
|
+
emit.error(
|
|
976
|
+
sessionResolutionFailure(
|
|
977
|
+
root,
|
|
944
978
|
"not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
945
|
-
|
|
979
|
+
),
|
|
980
|
+
);
|
|
946
981
|
process.exit(1);
|
|
947
982
|
}
|
|
948
983
|
try {
|
|
@@ -1214,14 +1249,13 @@ function runWhoami(opts: { json?: boolean }): void {
|
|
|
1214
1249
|
process.exit(1);
|
|
1215
1250
|
}
|
|
1216
1251
|
|
|
1217
|
-
|
|
1252
|
+
ensureAdapterSession(root);
|
|
1218
1253
|
const resolved = resolveOwnerWithSource();
|
|
1219
1254
|
const myOwner = resolved.owner;
|
|
1220
1255
|
if (!myOwner) {
|
|
1221
|
-
emit.error(
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
});
|
|
1256
|
+
emit.error(
|
|
1257
|
+
sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry"),
|
|
1258
|
+
);
|
|
1225
1259
|
process.exit(1);
|
|
1226
1260
|
}
|
|
1227
1261
|
|
|
@@ -1703,49 +1737,96 @@ function cursorEnvSessionId(): string | null {
|
|
|
1703
1737
|
return raw.startsWith("bc-") && raw.length > 3 ? raw.slice(3) : raw;
|
|
1704
1738
|
}
|
|
1705
1739
|
|
|
1706
|
-
|
|
1707
|
-
|
|
1740
|
+
interface CommandSessionBootstrap {
|
|
1741
|
+
adapter: "claude-code" | "cursor" | "codex";
|
|
1742
|
+
sessionId: string;
|
|
1708
1743
|
}
|
|
1709
1744
|
|
|
1710
|
-
function
|
|
1711
|
-
|
|
1745
|
+
function commandSessionBootstrap(): CommandSessionBootstrap | null {
|
|
1746
|
+
const cursorSessionId = cursorEnvSessionId();
|
|
1747
|
+
if (process.env.CURSOR_AGENT === "1" && cursorSessionId) {
|
|
1748
|
+
return { adapter: "cursor", sessionId: cursorSessionId };
|
|
1749
|
+
}
|
|
1750
|
+
if (process.env.HARNERY_AGENT_COORD_BRIDGE?.trim() === "codex-wsl") {
|
|
1751
|
+
const sessionId = sessionIdentityFromEnv();
|
|
1752
|
+
if (sessionId) return { adapter: "codex", sessionId };
|
|
1753
|
+
}
|
|
1754
|
+
const claudeSessionId = process.env.CLAUDE_CODE_SESSION_ID?.trim();
|
|
1755
|
+
if (claudeSessionId) {
|
|
1756
|
+
return { adapter: "claude-code", sessionId: claudeSessionId };
|
|
1757
|
+
}
|
|
1758
|
+
return null;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
function ensureAdapterSession(root: string): void {
|
|
1762
|
+
const bootstrap = commandSessionBootstrap();
|
|
1763
|
+
if (!bootstrap) return;
|
|
1764
|
+
// Claude Code owns a reliable native SessionStart hook. Its environment is
|
|
1765
|
+
// accepted by the explicit `agents heal` recovery path, but ordinary
|
|
1766
|
+
// identity and status commands must not impersonate that hook. The heal
|
|
1767
|
+
// bootstrap records derived provenance instead.
|
|
1768
|
+
if (bootstrap.adapter === "claude-code") return;
|
|
1712
1769
|
// Explicit owner override means the caller already knows who they are.
|
|
1713
1770
|
// Bootstrapping sessionStart inherits that env into the child hook, which
|
|
1714
1771
|
// re-projects a fresh heartbeat onto the override owner and can wipe an
|
|
1715
1772
|
// assumed persona agent_id (seen under Cursor integration fixtures).
|
|
1716
|
-
if (process.env.HARNERY_AGENT_COORD_OWNER?.trim()) return;
|
|
1773
|
+
if (bootstrap.adapter === "cursor" && process.env.HARNERY_AGENT_COORD_OWNER?.trim()) return;
|
|
1717
1774
|
if (resolveOwnerBySessionEnv(root)) return;
|
|
1718
1775
|
|
|
1719
|
-
const sessionId = cursorEnvSessionId();
|
|
1720
|
-
if (!sessionId) return;
|
|
1721
1776
|
const agentHook = coordBinPath("agent-hook", root);
|
|
1722
1777
|
if (!agentHook) return;
|
|
1723
1778
|
|
|
1724
1779
|
const payload = JSON.stringify({
|
|
1725
|
-
conversation_id: sessionId,
|
|
1726
|
-
session_id: sessionId,
|
|
1780
|
+
...(bootstrap.adapter === "cursor" ? { conversation_id: bootstrap.sessionId } : {}),
|
|
1781
|
+
session_id: bootstrap.sessionId,
|
|
1727
1782
|
hook_event_name: "sessionStart",
|
|
1728
1783
|
workspace_roots: [root],
|
|
1729
1784
|
cwd: root,
|
|
1730
|
-
|
|
1731
|
-
|
|
1785
|
+
...(bootstrap.adapter === "cursor"
|
|
1786
|
+
? { composer_mode: "agent", is_background_agent: false }
|
|
1787
|
+
: { source: "resume" }),
|
|
1732
1788
|
});
|
|
1733
1789
|
|
|
1734
|
-
spawnSync("bash", [agentHook, "session-start", "--adapter",
|
|
1790
|
+
spawnSync("bash", [agentHook, "session-start", "--adapter", bootstrap.adapter], {
|
|
1735
1791
|
input: payload,
|
|
1736
1792
|
cwd: root,
|
|
1737
1793
|
encoding: "utf8",
|
|
1738
1794
|
timeout: 3000,
|
|
1739
1795
|
env: {
|
|
1740
1796
|
...process.env,
|
|
1741
|
-
HARNERY_AGENT_COORD_PLATFORM:
|
|
1797
|
+
HARNERY_AGENT_COORD_PLATFORM: bootstrap.adapter,
|
|
1742
1798
|
HARNERY_COORD_ROOT_OVERRIDE: root,
|
|
1743
|
-
|
|
1744
|
-
|
|
1799
|
+
HARNERY_AGENT_COORD_SESSION_ID: bootstrap.sessionId,
|
|
1800
|
+
...(bootstrap.adapter === "cursor"
|
|
1801
|
+
? {
|
|
1802
|
+
CURSOR_SESSION_ID: bootstrap.sessionId,
|
|
1803
|
+
CURSOR_CONVERSATION_ID: bootstrap.sessionId,
|
|
1804
|
+
}
|
|
1805
|
+
: { CODEX_THREAD_ID: bootstrap.sessionId }),
|
|
1745
1806
|
},
|
|
1746
1807
|
});
|
|
1747
1808
|
}
|
|
1748
1809
|
|
|
1810
|
+
function sessionResolutionFailure(
|
|
1811
|
+
root: string,
|
|
1812
|
+
fallbackMessage: string,
|
|
1813
|
+
): { code: string; message: string } {
|
|
1814
|
+
if (!sessionIdentityFromEnv()) return { code: "no_pidmap_entry", message: fallbackMessage };
|
|
1815
|
+
const control = readEventV3ControlState(root);
|
|
1816
|
+
if (control.state !== "candidate" && control.state !== "active") {
|
|
1817
|
+
const detail = `${control.state}:${control.reason}`;
|
|
1818
|
+
return {
|
|
1819
|
+
code: "event_v3_control_unavailable",
|
|
1820
|
+
message: `the adapter session identity is present, but the V3 control state cannot accept session onboarding (${detail})`,
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
return {
|
|
1824
|
+
code: "session_generation_unavailable",
|
|
1825
|
+
message:
|
|
1826
|
+
"the adapter session identity is present, but no current V3 session generation was available after onboarding",
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1749
1830
|
function runReleaseClaim(path: string): void {
|
|
1750
1831
|
const root = monorepoRoot();
|
|
1751
1832
|
if (!root) {
|
|
@@ -1757,10 +1838,9 @@ function runReleaseClaim(path: string): void {
|
|
|
1757
1838
|
}
|
|
1758
1839
|
const myOwner = resolveOwner();
|
|
1759
1840
|
if (!myOwner) {
|
|
1760
|
-
emit.error(
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
});
|
|
1841
|
+
emit.error(
|
|
1842
|
+
sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry"),
|
|
1843
|
+
);
|
|
1764
1844
|
process.exit(1);
|
|
1765
1845
|
}
|
|
1766
1846
|
// Canonicalize: absolute paths under coordRoot get the prefix stripped;
|
|
@@ -1801,14 +1881,15 @@ function runSetTask(task: string, opts?: { sessionId?: string }): void {
|
|
|
1801
1881
|
// returns null by design, and erroring here orphans the session's first
|
|
1802
1882
|
// ritual command. The env id carries the same trust as an explicit
|
|
1803
1883
|
// --session-id, and set-task mints the heartbeat exactly as that path does.
|
|
1804
|
-
if (!opts?.sessionId)
|
|
1884
|
+
if (!opts?.sessionId) ensureAdapterSession(root);
|
|
1805
1885
|
const myOwner = opts?.sessionId ?? resolveOwner() ?? sessionIdentityFromEnv();
|
|
1806
1886
|
if (!myOwner) {
|
|
1807
|
-
emit.error(
|
|
1808
|
-
|
|
1809
|
-
|
|
1887
|
+
emit.error(
|
|
1888
|
+
sessionResolutionFailure(
|
|
1889
|
+
root,
|
|
1810
1890
|
"not in an agent session; no session-id environment identity and the ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
1811
|
-
|
|
1891
|
+
),
|
|
1892
|
+
);
|
|
1812
1893
|
process.exit(1);
|
|
1813
1894
|
}
|
|
1814
1895
|
|
|
@@ -1897,14 +1978,15 @@ function runLifecycle(rawState: string, opts: { reason?: string; sessionId?: str
|
|
|
1897
1978
|
process.exitCode = 1;
|
|
1898
1979
|
return;
|
|
1899
1980
|
}
|
|
1900
|
-
if (!opts.sessionId)
|
|
1981
|
+
if (!opts.sessionId) ensureAdapterSession(root);
|
|
1901
1982
|
const myOwner = opts.sessionId ?? resolveOwner() ?? sessionIdentityFromEnv();
|
|
1902
1983
|
if (!myOwner) {
|
|
1903
|
-
emit.error(
|
|
1904
|
-
|
|
1905
|
-
|
|
1984
|
+
emit.error(
|
|
1985
|
+
sessionResolutionFailure(
|
|
1986
|
+
root,
|
|
1906
1987
|
"not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
1907
|
-
|
|
1988
|
+
),
|
|
1989
|
+
);
|
|
1908
1990
|
process.exitCode = 1;
|
|
1909
1991
|
return;
|
|
1910
1992
|
}
|
|
@@ -2079,14 +2161,15 @@ function runSuggestName(
|
|
|
2079
2161
|
|
|
2080
2162
|
// Identity: prefer explicit --session-id (ppid-walk-free escape hatch, mirrors
|
|
2081
2163
|
// `status`/`set-task`), fall back to the ppid walk for interactive shell use.
|
|
2082
|
-
if (!opts.sessionId)
|
|
2164
|
+
if (!opts.sessionId) ensureAdapterSession(root);
|
|
2083
2165
|
const myOwner = opts.sessionId ?? resolveOwner();
|
|
2084
2166
|
if (!myOwner) {
|
|
2085
|
-
emit.error(
|
|
2086
|
-
|
|
2087
|
-
|
|
2167
|
+
emit.error(
|
|
2168
|
+
sessionResolutionFailure(
|
|
2169
|
+
root,
|
|
2088
2170
|
"not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
2089
|
-
|
|
2171
|
+
),
|
|
2172
|
+
);
|
|
2090
2173
|
process.exit(1);
|
|
2091
2174
|
}
|
|
2092
2175
|
|
|
@@ -2158,14 +2241,15 @@ function runStatus(opts: {
|
|
|
2158
2241
|
|
|
2159
2242
|
// Identity resolution: prefer explicit --session-id (hook-friendly), fall
|
|
2160
2243
|
// back to ppid walk for interactive shell usage.
|
|
2161
|
-
if (!opts.sessionId)
|
|
2244
|
+
if (!opts.sessionId) ensureAdapterSession(root);
|
|
2162
2245
|
const myOwner = opts.sessionId ?? resolveOwner();
|
|
2163
2246
|
if (!myOwner) {
|
|
2164
|
-
emit.error(
|
|
2165
|
-
|
|
2166
|
-
|
|
2247
|
+
emit.error(
|
|
2248
|
+
sessionResolutionFailure(
|
|
2249
|
+
root,
|
|
2167
2250
|
"not in an agent session; ppid walk found no pid-map entry (pass --session-id from a hook payload)",
|
|
2168
|
-
|
|
2251
|
+
),
|
|
2252
|
+
);
|
|
2169
2253
|
process.exit(1);
|
|
2170
2254
|
}
|
|
2171
2255
|
|
|
@@ -2207,7 +2291,7 @@ function runStatus(opts: {
|
|
|
2207
2291
|
}
|
|
2208
2292
|
}
|
|
2209
2293
|
|
|
2210
|
-
emitEventV3({
|
|
2294
|
+
const statusEmitted = emitEventV3({
|
|
2211
2295
|
owner: myOwner,
|
|
2212
2296
|
session: nativeSessionIdentity(hb, myOwner),
|
|
2213
2297
|
adapter: normalizeAdapter(hb.platform),
|
|
@@ -2216,6 +2300,16 @@ function runStatus(opts: {
|
|
|
2216
2300
|
status: opts.endTurn ? "end_turn_checked" : opts.json ? "json_checked" : "box_checked",
|
|
2217
2301
|
},
|
|
2218
2302
|
});
|
|
2303
|
+
// The closing box is a success artifact. Never print it when the exact
|
|
2304
|
+
// evidence enforced by the Stop hook did not reach the ledger.
|
|
2305
|
+
if (opts.endTurn && !statusEmitted) {
|
|
2306
|
+
emit.error({
|
|
2307
|
+
code: "status_event_failed",
|
|
2308
|
+
message: `the end-of-turn status event could not be recorded; no status box was issued; rerun \`${resolveBinName(root)} agents status --end-turn\``,
|
|
2309
|
+
});
|
|
2310
|
+
process.exitCode = 1;
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2219
2313
|
|
|
2220
2314
|
let sessionEnd:
|
|
2221
2315
|
| { state: "queued" | "already_requested"; request_id: string }
|
|
@@ -2285,10 +2379,7 @@ function runStatus(opts: {
|
|
|
2285
2379
|
if (!ctxUsage) {
|
|
2286
2380
|
ctxStr = "unavailable";
|
|
2287
2381
|
} else if (ctxUsage.percentOnly) {
|
|
2288
|
-
|
|
2289
|
-
// window. Show the percent + window estimate, marked as estimated.
|
|
2290
|
-
const pct = Math.round((ctxUsage.used / ctxUsage.window) * 100);
|
|
2291
|
-
ctxStr = `~${pct}% (Cursor; ${fmtTokens(ctxUsage.window)} window est.)`;
|
|
2382
|
+
ctxStr = `${Math.round(ctxUsage.usedPercent)}% (Cursor first-party)`;
|
|
2292
2383
|
} else {
|
|
2293
2384
|
ctxStr = `${fmtTokens(ctxUsage.used)} / ${fmtTokens(ctxUsage.window)} (${Math.round(
|
|
2294
2385
|
(ctxUsage.used / ctxUsage.window) * 100,
|
|
@@ -2296,7 +2387,7 @@ function runStatus(opts: {
|
|
|
2296
2387
|
}
|
|
2297
2388
|
|
|
2298
2389
|
const timeStr = formatLocalTime(new Date());
|
|
2299
|
-
const displayName =
|
|
2390
|
+
const displayName = agentDisplayName(hb.instance_id, hb.name);
|
|
2300
2391
|
|
|
2301
2392
|
// Council pending: list of council IDs where this agent is a member of an
|
|
2302
2393
|
// active council in `open` round_status without a contribution to that round.
|
|
@@ -2340,8 +2431,8 @@ function runStatus(opts: {
|
|
|
2340
2431
|
})),
|
|
2341
2432
|
})),
|
|
2342
2433
|
pending_councils: pendingCouncils,
|
|
2343
|
-
context_used: ctxUsage
|
|
2344
|
-
context_window: ctxUsage
|
|
2434
|
+
context_used: ctxUsage && "used" in ctxUsage ? ctxUsage.used : null,
|
|
2435
|
+
context_window: ctxUsage && "window" in ctxUsage ? ctxUsage.window : null,
|
|
2345
2436
|
timestamp_iso: new Date().toISOString(),
|
|
2346
2437
|
timestamp_local: timeStr,
|
|
2347
2438
|
...(quality ? { quality } : {}),
|
|
@@ -2485,15 +2576,17 @@ export function collectStatusPeerHealth(
|
|
|
2485
2576
|
root: string,
|
|
2486
2577
|
myOwner: string,
|
|
2487
2578
|
nowMs = Date.now(),
|
|
2579
|
+
readRows: (root: string) => StatusPeerHeartbeat[] = readLiveCoordinationRows,
|
|
2580
|
+
freshnessSeconds = freshnessCutoffSecs(),
|
|
2488
2581
|
): { livePeers: StatusPeerHeartbeat[]; stale: number } {
|
|
2489
2582
|
let rows: StatusPeerHeartbeat[] = [];
|
|
2490
2583
|
try {
|
|
2491
|
-
rows =
|
|
2584
|
+
rows = readRows(root);
|
|
2492
2585
|
} catch {
|
|
2493
2586
|
// V3 authority failures must not resurrect disposable cache rows.
|
|
2494
2587
|
}
|
|
2495
2588
|
|
|
2496
|
-
const cutoffMs = nowMs -
|
|
2589
|
+
const cutoffMs = nowMs - freshnessSeconds * 1000;
|
|
2497
2590
|
const livePeers: StatusPeerHeartbeat[] = [];
|
|
2498
2591
|
let stale = 0;
|
|
2499
2592
|
for (const peer of rows) {
|
|
@@ -2515,85 +2608,28 @@ function fmtTokens(n: number): string {
|
|
|
2515
2608
|
function readContextUsage(
|
|
2516
2609
|
sessionId: string,
|
|
2517
2610
|
platform?: string | null,
|
|
2518
|
-
):
|
|
2611
|
+
):
|
|
2612
|
+
| { used: number; window: number; percentOnly?: false }
|
|
2613
|
+
| { usedPercent: number; percentOnly: true }
|
|
2614
|
+
| null {
|
|
2519
2615
|
if (!sessionId) return null;
|
|
2520
2616
|
// Dispatch by platform: Codex's JSONL shape is different from Claude Code's
|
|
2521
2617
|
// (event_msg/response_item vs user/assistant), and Codex transcripts live
|
|
2522
2618
|
// under ~/.codex/sessions/YYYY/MM/DD/ rather than ~/.claude/projects/.
|
|
2523
|
-
// Cursor
|
|
2524
|
-
//
|
|
2525
|
-
// readCursorContextUsage reads that via bun:sqlite (percent-only).
|
|
2619
|
+
// Cursor stores a first-party percentage in workspaceStorage. The shared
|
|
2620
|
+
// runtime reader returns it without fabricating a token denominator.
|
|
2526
2621
|
if (platform === "codex") return readRuntimeContextUsage("codex", sessionId);
|
|
2527
|
-
if (platform === "cursor")
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
// is a JSON blob with .allComposers[].contextUsagePercent. We find the
|
|
2537
|
-
// composer matching the agent's session_id (Cursor uses session_id == composerId
|
|
2538
|
-
// for parent chats).
|
|
2539
|
-
//
|
|
2540
|
-
// Roots searched: ~/.config/Cursor/User/workspaceStorage (Linux native install)
|
|
2541
|
-
// and /mnt/c/Users/*/AppData/Roaming/Cursor/User/workspaceStorage (WSL).
|
|
2542
|
-
// We don't filter by workspace path; we scan every workspace's state.vscdb
|
|
2543
|
-
// looking for a composerId match. Cheap enough at status time (~60K per file,
|
|
2544
|
-
// <10ms typical). When a match is found, returns synthetic { used, window }
|
|
2545
|
-
// pair where the percent is what's real; absolutes are derived as
|
|
2546
|
-
// (window * percent / 100). Window hard-coded to a Cursor-typical 200K.
|
|
2547
|
-
const roots: string[] = [];
|
|
2548
|
-
const linuxRoot = resolve(homedir(), ".config", "Cursor", "User", "workspaceStorage");
|
|
2549
|
-
if (existsSync(linuxRoot)) roots.push(linuxRoot);
|
|
2550
|
-
try {
|
|
2551
|
-
if (existsSync("/mnt/c/Users")) {
|
|
2552
|
-
for (const u of readdirSync("/mnt/c/Users")) {
|
|
2553
|
-
const p = `/mnt/c/Users/${u}/AppData/Roaming/Cursor/User/workspaceStorage`;
|
|
2554
|
-
if (existsSync(p)) roots.push(p);
|
|
2555
|
-
}
|
|
2556
|
-
}
|
|
2557
|
-
} catch {
|
|
2558
|
-
// ignore
|
|
2559
|
-
}
|
|
2560
|
-
for (const root of roots) {
|
|
2561
|
-
let workspaces: string[];
|
|
2562
|
-
try {
|
|
2563
|
-
workspaces = readdirSync(root);
|
|
2564
|
-
} catch {
|
|
2565
|
-
continue;
|
|
2566
|
-
}
|
|
2567
|
-
for (const ws of workspaces) {
|
|
2568
|
-
const dbPath = `${root}/${ws}/state.vscdb`;
|
|
2569
|
-
if (!existsSync(dbPath)) continue;
|
|
2570
|
-
try {
|
|
2571
|
-
// Lazy-import bun:sqlite so non-Bun runtimes (if any) don't choke at load.
|
|
2572
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
2573
|
-
const { Database } = require("bun:sqlite");
|
|
2574
|
-
const db = new Database(dbPath, { readonly: true });
|
|
2575
|
-
const row = db
|
|
2576
|
-
.query("SELECT value FROM ItemTable WHERE key = 'composer.composerData'")
|
|
2577
|
-
.get() as { value: string | Uint8Array } | null;
|
|
2578
|
-
db.close();
|
|
2579
|
-
if (!row?.value) continue;
|
|
2580
|
-
const text =
|
|
2581
|
-
typeof row.value === "string" ? row.value : Buffer.from(row.value).toString("utf8");
|
|
2582
|
-
const parsed = JSON.parse(text);
|
|
2583
|
-
const composers = Array.isArray(parsed?.allComposers) ? parsed.allComposers : [];
|
|
2584
|
-
for (const c of composers) {
|
|
2585
|
-
if (c?.composerId === sessionId && typeof c?.contextUsagePercent === "number") {
|
|
2586
|
-
const window = 200000; // hard-coded Cursor-typical window; refine when Cursor exposes the actual ceiling
|
|
2587
|
-
const used = Math.round((window * c.contextUsagePercent) / 100);
|
|
2588
|
-
return { used, window, percentOnly: true };
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
} catch {
|
|
2592
|
-
// ignore: DB locked, schema drift, etc. Move on to the next workspace.
|
|
2593
|
-
}
|
|
2594
|
-
}
|
|
2622
|
+
if (platform === "cursor") {
|
|
2623
|
+
const telemetry = readRuntimeContextTelemetry({
|
|
2624
|
+
adapter: "cursor",
|
|
2625
|
+
session_id: sessionId,
|
|
2626
|
+
mode: "status",
|
|
2627
|
+
});
|
|
2628
|
+
return telemetry.state === "observed" && "used_percent" in telemetry
|
|
2629
|
+
? { usedPercent: telemetry.used_percent, percentOnly: true }
|
|
2630
|
+
: null;
|
|
2595
2631
|
}
|
|
2596
|
-
return
|
|
2632
|
+
return readRuntimeContextUsage("claude-code", sessionId);
|
|
2597
2633
|
}
|
|
2598
2634
|
|
|
2599
2635
|
function formatLocalTime(d: Date): string {
|
|
@@ -2993,10 +3029,10 @@ interface HealthReport {
|
|
|
2993
3029
|
lines: number;
|
|
2994
3030
|
cursor_backlog: number;
|
|
2995
3031
|
};
|
|
2996
|
-
//
|
|
2997
|
-
//
|
|
2998
|
-
//
|
|
2999
|
-
|
|
3032
|
+
// Heartbeat cache files present in active/ but stale or malformed. These are
|
|
3033
|
+
// files the sweep is not catching; a parseable old heartbeat is stale, not
|
|
3034
|
+
// evidence of an epoch-like or corrupt timestamp.
|
|
3035
|
+
heartbeat_cache_issues: {
|
|
3000
3036
|
count: number;
|
|
3001
3037
|
samples: string[];
|
|
3002
3038
|
};
|
|
@@ -3012,7 +3048,7 @@ interface HealthReport {
|
|
|
3012
3048
|
latest_at: string | null;
|
|
3013
3049
|
sessions: string[];
|
|
3014
3050
|
};
|
|
3015
|
-
|
|
3051
|
+
findings: string[];
|
|
3016
3052
|
}
|
|
3017
3053
|
|
|
3018
3054
|
/** Open-span soft watermark per producer state. The producer-state reader
|
|
@@ -3049,12 +3085,21 @@ export type EventLedgerHealthV3 =
|
|
|
3049
3085
|
groups: Array<{ adapter: string; session_hash: string; count: number }>;
|
|
3050
3086
|
};
|
|
3051
3087
|
diagnostics_spool: {
|
|
3088
|
+
/** Logical occurrences: loose files plus coalesced summary counts. */
|
|
3052
3089
|
total: number;
|
|
3090
|
+
/** Physical loose diagnostic files. */
|
|
3091
|
+
loose_total: number;
|
|
3092
|
+
/** Occurrences coalesced into summaries instead of loose files. */
|
|
3093
|
+
summarized_total: number;
|
|
3094
|
+
/** Physical summary files in `diagnostic-summaries/`. */
|
|
3095
|
+
summary_files: number;
|
|
3053
3096
|
last_24h: number;
|
|
3054
3097
|
last_1h: number;
|
|
3055
3098
|
latest_at: string | null;
|
|
3056
3099
|
by_category: Record<string, { total: number; last_24h: number }>;
|
|
3057
3100
|
recent_by_category: Record<string, { last_1h: number; latest_at: string | null }>;
|
|
3101
|
+
/** Times the summary gate failed open (loose write proceeded). */
|
|
3102
|
+
mitigation_fail_open: number;
|
|
3058
3103
|
};
|
|
3059
3104
|
span_pressure: Array<{ instance_id: string; generation_id: string; span_count: number }>;
|
|
3060
3105
|
collection_errors: string[];
|
|
@@ -3194,6 +3239,47 @@ export function collectEventLedgerHealthV3(root: string, nowMs = Date.now()): Ev
|
|
|
3194
3239
|
collectionErrors.push(`diagnostics spool unreadable: ${errorText(error)}`);
|
|
3195
3240
|
}
|
|
3196
3241
|
|
|
3242
|
+
// 4b) Coalesced diagnostic summaries: occurrences the producer bounded into
|
|
3243
|
+
// `diagnostic-summaries/` instead of loose files. Counted into the logical
|
|
3244
|
+
// totals so mitigation can never make an active fault look healthy; the
|
|
3245
|
+
// physical loose file count stays visible separately.
|
|
3246
|
+
let summarizedTotal = 0;
|
|
3247
|
+
let summaryFiles = 0;
|
|
3248
|
+
let mitigationFailOpen = 0;
|
|
3249
|
+
try {
|
|
3250
|
+
const listing = listDiagnosticSummariesV3(root);
|
|
3251
|
+
summaryFiles = listing.file_count;
|
|
3252
|
+
mitigationFailOpen = listing.mitigation_health?.fail_open_count ?? 0;
|
|
3253
|
+
if (listing.unreadable_count > 0) {
|
|
3254
|
+
collectionErrors.push(`${listing.unreadable_count} diagnostic summary file(s) unreadable`);
|
|
3255
|
+
}
|
|
3256
|
+
const dayAgoMs = nowMs - 24 * 60 * 60 * 1000;
|
|
3257
|
+
const hourAgoMs = nowMs - 60 * 60 * 1000;
|
|
3258
|
+
for (const summary of listing.summaries) {
|
|
3259
|
+
summarizedTotal += summary.summarized_count;
|
|
3260
|
+
const entry = byCategory[summary.category] ?? { total: 0, last_24h: 0 };
|
|
3261
|
+
const recent = recentByCategory[summary.category] ?? { last_1h: 0, latest_at: null };
|
|
3262
|
+
byCategory[summary.category] = entry;
|
|
3263
|
+
recentByCategory[summary.category] = recent;
|
|
3264
|
+
entry.total += summary.summarized_count;
|
|
3265
|
+
const day = countSummarizedSinceV3([summary], dayAgoMs, undefined, nowMs);
|
|
3266
|
+
const hour = countSummarizedSinceV3([summary], hourAgoMs, undefined, nowMs);
|
|
3267
|
+
entry.last_24h += day;
|
|
3268
|
+
diagnostics24h += day;
|
|
3269
|
+
recent.last_1h += hour;
|
|
3270
|
+
diagnostics1h += hour;
|
|
3271
|
+
const lastMs = summary.last_summarized_at ? Date.parse(summary.last_summarized_at) : NaN;
|
|
3272
|
+
if (Number.isFinite(lastMs)) {
|
|
3273
|
+
latestDiagnosticMs = Math.max(latestDiagnosticMs, lastMs);
|
|
3274
|
+
if (!recent.latest_at || lastMs > Date.parse(recent.latest_at)) {
|
|
3275
|
+
recent.latest_at = new Date(lastMs).toISOString();
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
}
|
|
3279
|
+
} catch (error) {
|
|
3280
|
+
collectionErrors.push(`diagnostic summaries unreadable: ${errorText(error)}`);
|
|
3281
|
+
}
|
|
3282
|
+
|
|
3197
3283
|
return {
|
|
3198
3284
|
state: "live",
|
|
3199
3285
|
mode: control.state,
|
|
@@ -3204,7 +3290,10 @@ export function collectEventLedgerHealthV3(root: string, nowMs = Date.now()): Ev
|
|
|
3204
3290
|
pending_finalizations: pending,
|
|
3205
3291
|
intake_spool: { total: intakeTotal, groups: intakeGroups },
|
|
3206
3292
|
diagnostics_spool: {
|
|
3207
|
-
total: diagnosticsTotal,
|
|
3293
|
+
total: diagnosticsTotal + summarizedTotal,
|
|
3294
|
+
loose_total: diagnosticsTotal,
|
|
3295
|
+
summarized_total: summarizedTotal,
|
|
3296
|
+
summary_files: summaryFiles,
|
|
3208
3297
|
last_24h: diagnostics24h,
|
|
3209
3298
|
last_1h: diagnostics1h,
|
|
3210
3299
|
latest_at: Number.isFinite(latestDiagnosticMs)
|
|
@@ -3212,6 +3301,7 @@ export function collectEventLedgerHealthV3(root: string, nowMs = Date.now()): Ev
|
|
|
3212
3301
|
: null,
|
|
3213
3302
|
by_category: byCategory,
|
|
3214
3303
|
recent_by_category: recentByCategory,
|
|
3304
|
+
mitigation_fail_open: mitigationFailOpen,
|
|
3215
3305
|
},
|
|
3216
3306
|
span_pressure: spanPressure,
|
|
3217
3307
|
collection_errors: collectionErrors,
|
|
@@ -3717,13 +3807,15 @@ type ActiveHealthHeartbeat = {
|
|
|
3717
3807
|
export function collectActiveAgentHealth(
|
|
3718
3808
|
root: string,
|
|
3719
3809
|
nowMs = Date.now(),
|
|
3810
|
+
readRows: (root: string) => ActiveHealthHeartbeat[] = readLiveCoordinationRows,
|
|
3811
|
+
freshnessSeconds = freshnessCutoffSecs(),
|
|
3720
3812
|
): ActiveAgentHealthSummary {
|
|
3721
3813
|
const source: ActiveAgentHealthSummary["source"] = "event-ledger-v3";
|
|
3722
3814
|
let heartbeats: ActiveHealthHeartbeat[] = [];
|
|
3723
3815
|
try {
|
|
3724
3816
|
const control = readEventV3ControlState(root);
|
|
3725
3817
|
if (control.state === "candidate" || control.state === "active") {
|
|
3726
|
-
heartbeats =
|
|
3818
|
+
heartbeats = readRows(root);
|
|
3727
3819
|
}
|
|
3728
3820
|
} catch {
|
|
3729
3821
|
// The event-ledger section reports the authority read failure. Do not
|
|
@@ -3749,7 +3841,7 @@ export function collectActiveAgentHealth(
|
|
|
3749
3841
|
const ageMs = Number.isFinite(lastObservedMs)
|
|
3750
3842
|
? nowMs - lastObservedMs
|
|
3751
3843
|
: Number.POSITIVE_INFINITY;
|
|
3752
|
-
if (ageMs >
|
|
3844
|
+
if (ageMs > freshnessSeconds * 1000) stale += 1;
|
|
3753
3845
|
}
|
|
3754
3846
|
return {
|
|
3755
3847
|
source,
|
|
@@ -3761,6 +3853,22 @@ export function collectActiveAgentHealth(
|
|
|
3761
3853
|
};
|
|
3762
3854
|
}
|
|
3763
3855
|
|
|
3856
|
+
export type HeartbeatCacheIssue = "no-name" | "invalid-heartbeat" | "stale-age";
|
|
3857
|
+
|
|
3858
|
+
/** Classify a parseable heartbeat cache file without conflating age with corruption. */
|
|
3859
|
+
export function classifyHeartbeatCacheIssue(
|
|
3860
|
+
heartbeat: Pick<Heartbeat, "name" | "last_heartbeat">,
|
|
3861
|
+
nowMs: number,
|
|
3862
|
+
staleAgeMs: number,
|
|
3863
|
+
): HeartbeatCacheIssue | null {
|
|
3864
|
+
if (!heartbeat.name || heartbeat.name === "unknown") return "no-name";
|
|
3865
|
+
const lastHeartbeatMs = heartbeat.last_heartbeat
|
|
3866
|
+
? Date.parse(heartbeat.last_heartbeat)
|
|
3867
|
+
: Number.NaN;
|
|
3868
|
+
if (!Number.isFinite(lastHeartbeatMs)) return "invalid-heartbeat";
|
|
3869
|
+
return nowMs - lastHeartbeatMs > staleAgeMs ? "stale-age" : null;
|
|
3870
|
+
}
|
|
3871
|
+
|
|
3764
3872
|
function runHealth(opts: { since: string; json?: boolean }): void {
|
|
3765
3873
|
if (opts.json) emit.config({ format: "json" });
|
|
3766
3874
|
|
|
@@ -3845,12 +3953,12 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3845
3953
|
.map(([agent, count]) => ({ agent, count }));
|
|
3846
3954
|
|
|
3847
3955
|
const activeAgents = collectActiveAgentHealth(root, nowMs);
|
|
3848
|
-
//
|
|
3849
|
-
//
|
|
3850
|
-
//
|
|
3851
|
-
let
|
|
3852
|
-
const
|
|
3853
|
-
const
|
|
3956
|
+
// Heartbeat cache issues: files in active/ that are unparseable, nameless,
|
|
3957
|
+
// invalidly timestamped, or stale. Old parseable timestamps are ordinary
|
|
3958
|
+
// staleness, not evidence of epoch-like timestamp corruption.
|
|
3959
|
+
let cacheIssueCount = 0;
|
|
3960
|
+
const cacheIssueSamples: string[] = [];
|
|
3961
|
+
const STALE_HEARTBEAT_AGE_MS = 24 * 60 * 60 * 1000;
|
|
3854
3962
|
if (existsSync(activeDir)) {
|
|
3855
3963
|
for (const file of readdirSync(activeDir)) {
|
|
3856
3964
|
if (!file.endsWith(".json")) continue;
|
|
@@ -3862,20 +3970,16 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3862
3970
|
hb = null;
|
|
3863
3971
|
}
|
|
3864
3972
|
if (!hb || typeof hb.instance_id !== "string") {
|
|
3865
|
-
|
|
3866
|
-
if (
|
|
3867
|
-
|
|
3973
|
+
cacheIssueCount++;
|
|
3974
|
+
if (cacheIssueSamples.length < 5)
|
|
3975
|
+
cacheIssueSamples.push(`${idFromFile.slice(0, 12)} (unparseable/no-id)`);
|
|
3868
3976
|
continue;
|
|
3869
3977
|
}
|
|
3870
|
-
const
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
zombieCount++;
|
|
3876
|
-
if (zombieSamples.length < 5) {
|
|
3877
|
-
const why = !hb.name || hb.name === "unknown" ? "no-name" : "epoch-age";
|
|
3878
|
-
zombieSamples.push(`${idFromFile.slice(0, 12)} (${why})`);
|
|
3978
|
+
const cacheIssue = classifyHeartbeatCacheIssue(hb, nowMs, STALE_HEARTBEAT_AGE_MS);
|
|
3979
|
+
if (cacheIssue) {
|
|
3980
|
+
cacheIssueCount++;
|
|
3981
|
+
if (cacheIssueSamples.length < 5) {
|
|
3982
|
+
cacheIssueSamples.push(`${idFromFile.slice(0, 12)} (${cacheIssue})`);
|
|
3879
3983
|
}
|
|
3880
3984
|
}
|
|
3881
3985
|
}
|
|
@@ -3891,11 +3995,11 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3891
3995
|
}
|
|
3892
3996
|
}
|
|
3893
3997
|
|
|
3894
|
-
//
|
|
3895
|
-
const
|
|
3998
|
+
// Finding detection.
|
|
3999
|
+
const findings: string[] = [];
|
|
3896
4000
|
for (const { agent, count } of healTopAgents) {
|
|
3897
4001
|
if (count >= 5) {
|
|
3898
|
-
|
|
4002
|
+
findings.push(
|
|
3899
4003
|
`${agent} self-healed ${count}x in ${opts.since}; possible idle-prune loop or PID instability`,
|
|
3900
4004
|
);
|
|
3901
4005
|
}
|
|
@@ -3906,7 +4010,7 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3906
4010
|
activeAgents.source === "event-ledger-v3"
|
|
3907
4011
|
? "lifecycle reconciliation may be delayed"
|
|
3908
4012
|
: "heal mechanism may not be firing";
|
|
3909
|
-
|
|
4013
|
+
findings.push(
|
|
3910
4014
|
`${activeAgents.stale} active ${noun}(s) without activity for ${Math.floor(freshnessCutoffSecs() / 60)}min; ${action}`,
|
|
3911
4015
|
);
|
|
3912
4016
|
}
|
|
@@ -3915,31 +4019,33 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3915
4019
|
(schema) => schema !== expectedSchema,
|
|
3916
4020
|
);
|
|
3917
4021
|
if (unexpectedSchemas.length > 0) {
|
|
3918
|
-
|
|
4022
|
+
findings.push(
|
|
3919
4023
|
`Unexpected active-agent schema versions in use: ${unexpectedSchemas.join(", ")} (expected ${expectedSchema})`,
|
|
3920
4024
|
);
|
|
3921
4025
|
}
|
|
3922
|
-
// Only recent hook failures are active
|
|
4026
|
+
// Only recent hook failures are active findings. Historical rows remain in
|
|
3923
4027
|
// the report with exact error signatures and their latest timestamp.
|
|
3924
4028
|
if (hookErrors.last1h > 0) {
|
|
3925
4029
|
const top = hookErrors.recentTopErrors[0];
|
|
3926
4030
|
const detail = top ? `: top '${top.error.slice(0, 80)}' x${top.count} (${top.phase})` : "";
|
|
3927
|
-
|
|
4031
|
+
findings.push(`agent-hook errored ${hookErrors.last1h}x in the last hour${detail}`);
|
|
3928
4032
|
}
|
|
3929
4033
|
if (stream.cursor_backlog > 500) {
|
|
3930
|
-
|
|
4034
|
+
findings.push(
|
|
3931
4035
|
`projection cursor is ${stream.cursor_backlog} events behind; drain lagging (stop projection may be failing)`,
|
|
3932
4036
|
);
|
|
3933
4037
|
}
|
|
3934
|
-
// Raw V3 stream size is not
|
|
4038
|
+
// Raw V3 stream size is not a finding; catalog rotation bounds readers.
|
|
3935
4039
|
if ((sweptByReason.unparseable ?? 0) > 0) {
|
|
3936
|
-
|
|
4040
|
+
findings.push(
|
|
3937
4041
|
`${sweptByReason.unparseable} heartbeat(s) swept as unparseable in ${opts.since}; possible corruption or a non-atomic writer`,
|
|
3938
4042
|
);
|
|
3939
4043
|
}
|
|
3940
|
-
if (
|
|
3941
|
-
|
|
3942
|
-
`${
|
|
4044
|
+
if (cacheIssueCount > 0) {
|
|
4045
|
+
findings.push(
|
|
4046
|
+
`${cacheIssueCount} heartbeat cache issue(s) in active/ (${cacheIssueSamples.join(", ")}); ` +
|
|
4047
|
+
"rows the last sweep deliberately kept (malformed but mtime-fresh, or neither audit " +
|
|
4048
|
+
"write could persist), or that aged past the freshness cutoff since it ran",
|
|
3943
4049
|
);
|
|
3944
4050
|
}
|
|
3945
4051
|
if (stopRemediation.total > 0) {
|
|
@@ -3947,7 +4053,7 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3947
4053
|
stopRemediation.sessions.length > 0
|
|
3948
4054
|
? ` (sessions: ${stopRemediation.sessions.map((s) => s.slice(0, 8)).join(", ")})`
|
|
3949
4055
|
: "";
|
|
3950
|
-
|
|
4056
|
+
findings.push(
|
|
3951
4057
|
`stop-hook remediation cap exhausted ${stopRemediation.total}x in ${opts.since}${who}; these sessions ended turns without the end-of-turn ritual — check why their evidence never lands`,
|
|
3952
4058
|
);
|
|
3953
4059
|
}
|
|
@@ -3962,17 +4068,17 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
3962
4068
|
(sum, generation) => sum + generation.span_count,
|
|
3963
4069
|
0,
|
|
3964
4070
|
);
|
|
3965
|
-
|
|
4071
|
+
findings.push(
|
|
3966
4072
|
`${orphanSpans} open tool span(s) across ${orphanGenerations.length} generation(s) with no open turn; orphaned spans block clean session end`,
|
|
3967
4073
|
);
|
|
3968
4074
|
}
|
|
3969
4075
|
for (const pressure of eventLedger.span_pressure) {
|
|
3970
|
-
|
|
4076
|
+
findings.push(
|
|
3971
4077
|
`${pressure.instance_id} (${pressure.generation_id}) holds ${pressure.span_count} open spans (soft watermark ${SPAN_PRESSURE_SOFT_WATERMARK}; the reader's 256-span cap makes the state unreadable)`,
|
|
3972
4078
|
);
|
|
3973
4079
|
}
|
|
3974
4080
|
for (const collectionError of eventLedger.collection_errors) {
|
|
3975
|
-
|
|
4081
|
+
findings.push(`event-ledger health: ${collectionError}`);
|
|
3976
4082
|
}
|
|
3977
4083
|
}
|
|
3978
4084
|
|
|
@@ -4017,14 +4123,14 @@ function runHealth(opts: { since: string; json?: boolean }): void {
|
|
|
4017
4123
|
recent_top_errors: hookErrors.recentTopErrors,
|
|
4018
4124
|
},
|
|
4019
4125
|
stream,
|
|
4020
|
-
|
|
4126
|
+
heartbeat_cache_issues: { count: cacheIssueCount, samples: cacheIssueSamples },
|
|
4021
4127
|
event_ledger: eventLedger,
|
|
4022
4128
|
stop_remediation: {
|
|
4023
4129
|
total: stopRemediation.total,
|
|
4024
4130
|
latest_at: stopRemediation.latestAt,
|
|
4025
4131
|
sessions: stopRemediation.sessions,
|
|
4026
4132
|
},
|
|
4027
|
-
|
|
4133
|
+
findings,
|
|
4028
4134
|
};
|
|
4029
4135
|
|
|
4030
4136
|
if (opts.json) {
|
|
@@ -4095,7 +4201,7 @@ function renderHealthBox(report: HealthReport): void {
|
|
|
4095
4201
|
`open spans ${ledger.open_spans.total}${orphanGenerations > 0 ? ` (${orphanGenerations} gen turn-closed)` : ""}`,
|
|
4096
4202
|
`pending ends ${ledger.pending_finalizations.length}${pendingAges ? ` (${pendingAges})` : ""}`,
|
|
4097
4203
|
`intake ${ledger.intake_spool.total}`,
|
|
4098
|
-
`diagnostics ${ledger.diagnostics_spool.total} (${ledger.diagnostics_spool.last_1h} in 1h / ${ledger.diagnostics_spool.last_24h} in 24h)`,
|
|
4204
|
+
`diagnostics ${ledger.diagnostics_spool.total}${ledger.diagnostics_spool.summarized_total > 0 ? ` (${ledger.diagnostics_spool.loose_total} loose + ${ledger.diagnostics_spool.summarized_total} summarized)` : ""} (${ledger.diagnostics_spool.last_1h} in 1h / ${ledger.diagnostics_spool.last_24h} in 24h)`,
|
|
4099
4205
|
].join(" · ");
|
|
4100
4206
|
}
|
|
4101
4207
|
|
|
@@ -4116,13 +4222,13 @@ function renderHealthBox(report: HealthReport): void {
|
|
|
4116
4222
|
["stream", streamStr],
|
|
4117
4223
|
["event ledger", ledgerStr],
|
|
4118
4224
|
[
|
|
4119
|
-
"
|
|
4120
|
-
report.
|
|
4225
|
+
"cache issues",
|
|
4226
|
+
report.heartbeat_cache_issues.count === 0
|
|
4121
4227
|
? "0"
|
|
4122
|
-
: `${report.
|
|
4228
|
+
: `${report.heartbeat_cache_issues.count} (${report.heartbeat_cache_issues.samples.join(", ")})`,
|
|
4123
4229
|
],
|
|
4124
4230
|
["councils", councilParts.join(", ")],
|
|
4125
|
-
["
|
|
4231
|
+
["findings", report.findings.length === 0 ? "(clean)" : `${report.findings.length} flagged`],
|
|
4126
4232
|
];
|
|
4127
4233
|
|
|
4128
4234
|
const localTime = formatLocalTime(new Date(report.generated_at));
|
|
@@ -4130,9 +4236,9 @@ function renderHealthBox(report: HealthReport): void {
|
|
|
4130
4236
|
|
|
4131
4237
|
process.stdout.write(`${formatBox(title, rows)}\n`); // lint-ok-emission: chat-paste path; mirrors runStatus's direct write so the box surfaces in both TTY + harn-session-teed contexts
|
|
4132
4238
|
|
|
4133
|
-
if (report.
|
|
4239
|
+
if (report.findings.length > 0) {
|
|
4134
4240
|
process.stdout.write("\n"); // lint-ok-emission: same chat-paste path
|
|
4135
|
-
for (const a of report.
|
|
4241
|
+
for (const a of report.findings) {
|
|
4136
4242
|
process.stdout.write(` ! ${a}\n`); // lint-ok-emission: same
|
|
4137
4243
|
}
|
|
4138
4244
|
}
|
|
@@ -4552,24 +4658,66 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
|
|
|
4552
4658
|
}
|
|
4553
4659
|
const myOwner = resolveOwner();
|
|
4554
4660
|
if (!myOwner) {
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4661
|
+
const root = monorepoRoot();
|
|
4662
|
+
emit.error(
|
|
4663
|
+
root
|
|
4664
|
+
? sessionResolutionFailure(
|
|
4665
|
+
root,
|
|
4666
|
+
"not in an agent session; ppid walk found no pid-map entry",
|
|
4667
|
+
)
|
|
4668
|
+
: {
|
|
4669
|
+
code: "no_pidmap_entry",
|
|
4670
|
+
message: "not in an agent session; ppid walk found no pid-map entry",
|
|
4671
|
+
},
|
|
4672
|
+
);
|
|
4559
4673
|
process.exit(1);
|
|
4560
4674
|
}
|
|
4675
|
+
const coordRoot = monorepoRoot();
|
|
4561
4676
|
const peerOwner = resolveOwnerByName(name);
|
|
4562
|
-
|
|
4677
|
+
|
|
4678
|
+
// A name with no live session is the common case, not an error: the agent it
|
|
4679
|
+
// refers to may have ended minutes ago and may come back under the same name.
|
|
4680
|
+
// Refuse only a name that no agent has ever held, which is a typo — queueing
|
|
4681
|
+
// that would swallow the message silently.
|
|
4682
|
+
if (!peerOwner && coordRoot && !isAddressableName(coordRoot, name)) {
|
|
4683
|
+
const suggestions = suggestNames(coordRoot, name);
|
|
4563
4684
|
emit.error({
|
|
4564
|
-
code: "
|
|
4565
|
-
message:
|
|
4685
|
+
code: "unknown_agent",
|
|
4686
|
+
message:
|
|
4687
|
+
`no agent has ever been named "${name}". ` +
|
|
4688
|
+
(suggestions.length > 0 ? `Did you mean ${suggestions.join(", ")}? ` : "") +
|
|
4689
|
+
`Run \`${resolveBinName()} agents list\` for live sessions.`,
|
|
4566
4690
|
});
|
|
4567
4691
|
process.exit(1);
|
|
4568
4692
|
}
|
|
4693
|
+
|
|
4569
4694
|
const myHb = readCurrentCoordinationRow(myOwner);
|
|
4570
4695
|
const fromName = myHb?.name ?? "anonymous";
|
|
4571
4696
|
const body = `from agent-${fromName}: ${message.trim()}`;
|
|
4572
|
-
|
|
4697
|
+
|
|
4698
|
+
// A live recipient gets the journal entry immediately, so a peer reading
|
|
4699
|
+
// their own journal mid-session sees it without waiting for a prompt. A
|
|
4700
|
+
// dormant recipient has no journal to write to yet; the drain writes it into
|
|
4701
|
+
// whichever session picks the message up.
|
|
4702
|
+
const doc = peerOwner ? appendEntry(peerOwner, "handoff", body) : null;
|
|
4703
|
+
|
|
4704
|
+
let queued: QueueResult;
|
|
4705
|
+
try {
|
|
4706
|
+
queued = queueMailboxMessage({
|
|
4707
|
+
coordRoot: coordRoot ?? process.cwd(),
|
|
4708
|
+
toName: name,
|
|
4709
|
+
fromName,
|
|
4710
|
+
fromInstanceId: myOwner,
|
|
4711
|
+
body: message.trim(),
|
|
4712
|
+
journaled: Boolean(peerOwner),
|
|
4713
|
+
});
|
|
4714
|
+
} catch (error) {
|
|
4715
|
+
if (error instanceof MailboxCapacityError) {
|
|
4716
|
+
emit.error({ code: `mailbox_${error.reason_code}`, message: error.message });
|
|
4717
|
+
process.exit(1);
|
|
4718
|
+
}
|
|
4719
|
+
throw error;
|
|
4720
|
+
}
|
|
4573
4721
|
|
|
4574
4722
|
// Canonical delivery record: sender is the envelope owner, recipient rides
|
|
4575
4723
|
// in data, so read-only observers can render the communication without
|
|
@@ -4581,18 +4729,21 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
|
|
|
4581
4729
|
observation: {
|
|
4582
4730
|
event_type: "coord.message_observed",
|
|
4583
4731
|
direction: "sent",
|
|
4584
|
-
subject: peerOwner
|
|
4732
|
+
subject: peerOwner ?? `name:${queued.message.to_name}`,
|
|
4585
4733
|
body: message.trim(),
|
|
4586
4734
|
},
|
|
4587
4735
|
});
|
|
4588
4736
|
|
|
4589
4737
|
const data = {
|
|
4590
|
-
peer:
|
|
4738
|
+
peer: queued.message.to_name,
|
|
4591
4739
|
peer_instance_id: peerOwner,
|
|
4740
|
+
delivery: peerOwner ? ("live" as const) : ("queued" as const),
|
|
4741
|
+
message_id: queued.message.message_id,
|
|
4742
|
+
pending: queued.pending,
|
|
4592
4743
|
from: fromName,
|
|
4593
4744
|
body,
|
|
4594
|
-
journal_path: doc
|
|
4595
|
-
journal_bytes: doc
|
|
4745
|
+
journal_path: doc?.path ?? null,
|
|
4746
|
+
journal_bytes: doc?.bytes ?? null,
|
|
4596
4747
|
};
|
|
4597
4748
|
|
|
4598
4749
|
if (opts.json) {
|
|
@@ -4601,7 +4752,11 @@ function runPing(name: string, message: string, opts: { json?: boolean }): void
|
|
|
4601
4752
|
return;
|
|
4602
4753
|
}
|
|
4603
4754
|
emit.data(data);
|
|
4604
|
-
emit.text(
|
|
4755
|
+
emit.text(
|
|
4756
|
+
peerOwner
|
|
4757
|
+
? `delivered to agent-${data.peer} (live; they see it on their next prompt): "${truncate(message.trim(), 80)}"\n`
|
|
4758
|
+
: `queued for agent-${data.peer} (no live session; delivered when a session of that name next starts): "${truncate(message.trim(), 80)}"\n`,
|
|
4759
|
+
);
|
|
4605
4760
|
}
|
|
4606
4761
|
|
|
4607
4762
|
async function runWait(
|
|
@@ -4722,21 +4877,22 @@ function emitWaitResult(
|
|
|
4722
4877
|
}
|
|
4723
4878
|
|
|
4724
4879
|
function runHeal(opts: {
|
|
4725
|
-
owner
|
|
4726
|
-
kind
|
|
4880
|
+
owner?: string;
|
|
4881
|
+
kind?: string;
|
|
4727
4882
|
sessionId?: string;
|
|
4728
4883
|
adapter?: string;
|
|
4729
4884
|
pid?: string;
|
|
4885
|
+
quarantineTransaction?: string;
|
|
4886
|
+
approvalRecordId?: string;
|
|
4887
|
+
yes?: boolean;
|
|
4730
4888
|
json?: boolean;
|
|
4731
4889
|
}): void {
|
|
4732
4890
|
if (opts.json) emit.config({ format: "json" });
|
|
4733
4891
|
|
|
4734
|
-
const
|
|
4735
|
-
const
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
process.exit(1);
|
|
4739
|
-
}
|
|
4892
|
+
const requestedOwner = opts.owner?.trim() ?? "";
|
|
4893
|
+
const quarantineTransaction = opts.quarantineTransaction?.trim() ?? "";
|
|
4894
|
+
const approvalRecordId = opts.approvalRecordId?.trim() ?? "";
|
|
4895
|
+
const kind = opts.kind?.trim() || "cache";
|
|
4740
4896
|
if (kind !== "pidmap" && kind !== "cache") {
|
|
4741
4897
|
emit.error({
|
|
4742
4898
|
code: "bad_kind",
|
|
@@ -4744,6 +4900,30 @@ function runHeal(opts: {
|
|
|
4744
4900
|
});
|
|
4745
4901
|
process.exit(1);
|
|
4746
4902
|
}
|
|
4903
|
+
if (quarantineTransaction) {
|
|
4904
|
+
if (opts.kind || opts.pid) {
|
|
4905
|
+
emit.error({
|
|
4906
|
+
code: "conflicting_recovery_options",
|
|
4907
|
+
message: "--quarantine-transaction cannot be combined with --kind or --pid",
|
|
4908
|
+
});
|
|
4909
|
+
process.exit(1);
|
|
4910
|
+
}
|
|
4911
|
+
if (!opts.yes || !approvalRecordId) {
|
|
4912
|
+
emit.error({
|
|
4913
|
+
code: "transaction_quarantine_confirmation_required",
|
|
4914
|
+
message:
|
|
4915
|
+
"--quarantine-transaction requires --approval-record-id <id> and --yes; " +
|
|
4916
|
+
"the command abandons one uncommitted authority mutation while preserving its record",
|
|
4917
|
+
});
|
|
4918
|
+
process.exit(1);
|
|
4919
|
+
}
|
|
4920
|
+
} else if (approvalRecordId || opts.yes) {
|
|
4921
|
+
emit.error({
|
|
4922
|
+
code: "transaction_quarantine_target_required",
|
|
4923
|
+
message: "--approval-record-id and --yes require --quarantine-transaction <id>",
|
|
4924
|
+
});
|
|
4925
|
+
process.exit(1);
|
|
4926
|
+
}
|
|
4747
4927
|
if (
|
|
4748
4928
|
opts.adapter &&
|
|
4749
4929
|
opts.adapter !== "claude-code" &&
|
|
@@ -4766,7 +4946,52 @@ function runHeal(opts: {
|
|
|
4766
4946
|
process.exit(1);
|
|
4767
4947
|
}
|
|
4768
4948
|
|
|
4769
|
-
const
|
|
4949
|
+
const currentSessionRepair =
|
|
4950
|
+
kind === "cache" &&
|
|
4951
|
+
opts.owner === undefined &&
|
|
4952
|
+
opts.sessionId === undefined &&
|
|
4953
|
+
opts.adapter === undefined &&
|
|
4954
|
+
!quarantineTransaction;
|
|
4955
|
+
|
|
4956
|
+
const ownerResolution = resolveOwnerWithSource();
|
|
4957
|
+
const bootstrapIdentity = currentSessionRepair ? commandSessionBootstrap() : null;
|
|
4958
|
+
const resolvedCurrentOwner =
|
|
4959
|
+
bootstrapIdentity &&
|
|
4960
|
+
(ownerResolution.source === "none" || ownerResolution.source === "active_singleton")
|
|
4961
|
+
? bootstrapIdentity.sessionId
|
|
4962
|
+
: ownerResolution.owner;
|
|
4963
|
+
const owner = requestedOwner || resolvedCurrentOwner || sessionIdentityFromEnv() || "";
|
|
4964
|
+
if (!owner) {
|
|
4965
|
+
emit.error({
|
|
4966
|
+
code: "session_identity_missing",
|
|
4967
|
+
message:
|
|
4968
|
+
`could not resolve the current session; run ${resolveBinName()} doctor, or pass ` +
|
|
4969
|
+
"--owner <instance-id> --session-id <native-session-id> --adapter <adapter>",
|
|
4970
|
+
});
|
|
4971
|
+
process.exit(1);
|
|
4972
|
+
}
|
|
4973
|
+
|
|
4974
|
+
const currentRow = readLiveCoordinationRow(root, owner);
|
|
4975
|
+
const inferredAdapter = normalizeAdapter(
|
|
4976
|
+
opts.adapter?.trim() || currentRow?.platform || commandSessionBootstrap()?.adapter,
|
|
4977
|
+
);
|
|
4978
|
+
const sessionId =
|
|
4979
|
+
opts.sessionId?.trim() ||
|
|
4980
|
+
(currentSessionRepair ? sessionIdentityFromEnv() : null) ||
|
|
4981
|
+
nativeSessionIdentity(currentRow, owner);
|
|
4982
|
+
|
|
4983
|
+
if (kind === "cache") {
|
|
4984
|
+
const refusal = cacheHealAuthorityRefusal(root, owner, sessionId, inferredAdapter, currentRow);
|
|
4985
|
+
if (refusal) {
|
|
4986
|
+
emitHealFailure(refusal.reason, refusal.message);
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
|
|
4990
|
+
const action = quarantineTransaction
|
|
4991
|
+
? "quarantine-authority-transaction"
|
|
4992
|
+
: kind === "pidmap"
|
|
4993
|
+
? "heal-pidmap"
|
|
4994
|
+
: "repair-coordination-cache";
|
|
4770
4995
|
|
|
4771
4996
|
// Refuse to materialize a V3 cache at a truncated owner id.
|
|
4772
4997
|
//
|
|
@@ -4809,23 +5034,72 @@ function runHeal(opts: {
|
|
|
4809
5034
|
// heal-pidmap <instance_id> [<pid>]
|
|
4810
5035
|
// repair-coordination-cache <instance_id> [<session_id>]
|
|
4811
5036
|
const helperArgs: string[] = [action, owner];
|
|
4812
|
-
if (
|
|
4813
|
-
|
|
4814
|
-
|
|
5037
|
+
if (quarantineTransaction) {
|
|
5038
|
+
helperArgs.push(
|
|
5039
|
+
quarantineTransaction,
|
|
5040
|
+
approvalRecordId,
|
|
5041
|
+
sessionId,
|
|
5042
|
+
`--adapter=${inferredAdapter}`,
|
|
5043
|
+
);
|
|
5044
|
+
} else {
|
|
5045
|
+
if (kind === "pidmap" && opts.pid) helperArgs.push(opts.pid);
|
|
5046
|
+
if (kind === "cache") helperArgs.push(sessionId, `--adapter=${inferredAdapter}`);
|
|
5047
|
+
}
|
|
4815
5048
|
|
|
4816
5049
|
// Both recovery actions are handled by the bundled agent-coord binary.
|
|
4817
5050
|
const helper = agentCoordOrExit(root);
|
|
4818
|
-
|
|
5051
|
+
let proc = spawnSync(helper, helperArgs, {
|
|
4819
5052
|
encoding: "utf8",
|
|
4820
5053
|
...coordHelperOpts(root),
|
|
4821
5054
|
});
|
|
4822
5055
|
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
5056
|
+
let bootstrapState: "created" | "reused" | undefined;
|
|
5057
|
+
if (
|
|
5058
|
+
proc.status !== 0 &&
|
|
5059
|
+
currentSessionRepair &&
|
|
5060
|
+
missingAuthorityForCurrentSessionBootstrap(root, owner, sessionId)
|
|
5061
|
+
) {
|
|
5062
|
+
const bootstrap = commandSessionBootstrap();
|
|
5063
|
+
if (
|
|
5064
|
+
!bootstrap ||
|
|
5065
|
+
bootstrap.sessionId !== sessionId ||
|
|
5066
|
+
bootstrap.sessionId !== owner ||
|
|
5067
|
+
bootstrap.adapter !== inferredAdapter
|
|
5068
|
+
) {
|
|
5069
|
+
emitHealFailure(
|
|
5070
|
+
"native_identity_unverified",
|
|
5071
|
+
"the current adapter did not provide one matching native session id and adapter",
|
|
5072
|
+
);
|
|
5073
|
+
}
|
|
5074
|
+
try {
|
|
5075
|
+
const bootstrapped = bootstrapLiveCoordinationAuthorityV3({
|
|
5076
|
+
coordRoot: root,
|
|
5077
|
+
owner,
|
|
5078
|
+
nativeSessionId: bootstrap.sessionId,
|
|
5079
|
+
adapter: bootstrap.adapter,
|
|
5080
|
+
});
|
|
5081
|
+
bootstrapState = bootstrapped.state;
|
|
5082
|
+
} catch (error) {
|
|
5083
|
+
const reason =
|
|
5084
|
+
error instanceof LiveCoordinationAuthorityV3Error
|
|
5085
|
+
? error.reason
|
|
5086
|
+
: "authority_bootstrap_failed";
|
|
5087
|
+
emitHealFailure(
|
|
5088
|
+
reason,
|
|
5089
|
+
"the current native session could not establish authority; no fallback cache was accepted",
|
|
5090
|
+
);
|
|
5091
|
+
}
|
|
5092
|
+
proc = spawnSync(helper, helperArgs, {
|
|
5093
|
+
encoding: "utf8",
|
|
5094
|
+
...coordHelperOpts(root),
|
|
4827
5095
|
});
|
|
4828
|
-
|
|
5096
|
+
}
|
|
5097
|
+
|
|
5098
|
+
if (proc.status !== 0) {
|
|
5099
|
+
emitHealFailure(
|
|
5100
|
+
healFailureReason(root, owner, sessionId, inferredAdapter),
|
|
5101
|
+
spawnFailureMessage(proc, `agent-coord ${action}`),
|
|
5102
|
+
);
|
|
4829
5103
|
}
|
|
4830
5104
|
|
|
4831
5105
|
// Read the derived cache to surface post-action state.
|
|
@@ -4836,8 +5110,9 @@ function runHeal(opts: {
|
|
|
4836
5110
|
after = null;
|
|
4837
5111
|
}
|
|
4838
5112
|
|
|
4839
|
-
const outcome =
|
|
4840
|
-
|
|
5113
|
+
const outcome = quarantineTransaction
|
|
5114
|
+
? "transaction_quarantined"
|
|
5115
|
+
: kind === "pidmap"
|
|
4841
5116
|
? proc.status === 0
|
|
4842
5117
|
? "ok"
|
|
4843
5118
|
: "failed"
|
|
@@ -4852,10 +5127,15 @@ function runHeal(opts: {
|
|
|
4852
5127
|
action,
|
|
4853
5128
|
outcome,
|
|
4854
5129
|
after,
|
|
5130
|
+
...(quarantineTransaction ? { recovery: JSON.parse(proc.stdout.trim()) as unknown } : {}),
|
|
4855
5131
|
},
|
|
4856
5132
|
],
|
|
4857
5133
|
meta: {
|
|
4858
5134
|
kind,
|
|
5135
|
+
automatic: currentSessionRepair && !quarantineTransaction,
|
|
5136
|
+
authority: "event-ledger-v3",
|
|
5137
|
+
adapter: kind === "cache" ? inferredAdapter : undefined,
|
|
5138
|
+
bootstrap: bootstrapState,
|
|
4859
5139
|
// The path actually spawned, not a guess at the layout: the helper is
|
|
4860
5140
|
// resolved from harnery's own package location, which differs between a
|
|
4861
5141
|
// submodule, an installed dependency, and a standalone checkout.
|
|
@@ -4863,10 +5143,18 @@ function runHeal(opts: {
|
|
|
4863
5143
|
},
|
|
4864
5144
|
});
|
|
4865
5145
|
if (!opts.json) {
|
|
4866
|
-
if (
|
|
5146
|
+
if (quarantineTransaction) {
|
|
5147
|
+
emit.text(
|
|
5148
|
+
`coordination recovered: ${quarantineTransaction} quarantined with approval ${approvalRecordId}; ` +
|
|
5149
|
+
`cache ${after ? "present" : "absent"} (${inferredAdapter})\n`,
|
|
5150
|
+
);
|
|
5151
|
+
} else if (kind === "pidmap") {
|
|
4867
5152
|
emit.text(`agent-coord ${action} ok\n`);
|
|
4868
5153
|
} else {
|
|
4869
|
-
emit.text(
|
|
5154
|
+
emit.text(
|
|
5155
|
+
`coordination repaired: V3 authority live; ${currentSessionRepair ? "current-session " : ""}` +
|
|
5156
|
+
`cache ${after ? "present" : "absent"} (${inferredAdapter})\n`,
|
|
5157
|
+
);
|
|
4870
5158
|
}
|
|
4871
5159
|
}
|
|
4872
5160
|
|
|
@@ -4877,6 +5165,98 @@ function runHeal(opts: {
|
|
|
4877
5165
|
// unconditionally on every `harn agents heal`, which over-counted no-op heals.)
|
|
4878
5166
|
}
|
|
4879
5167
|
|
|
5168
|
+
type HealAuthorityRefusal = {
|
|
5169
|
+
reason: "adapter_mismatch" | "owner_mismatch" | "session_mismatch" | "terminal_generation";
|
|
5170
|
+
message: string;
|
|
5171
|
+
};
|
|
5172
|
+
|
|
5173
|
+
function cacheHealAuthorityRefusal(
|
|
5174
|
+
root: string,
|
|
5175
|
+
owner: string,
|
|
5176
|
+
sessionId: string,
|
|
5177
|
+
adapter: "claude-code" | "cursor" | "codex",
|
|
5178
|
+
currentRow: LiveCoordinationRow | null,
|
|
5179
|
+
): HealAuthorityRefusal | null {
|
|
5180
|
+
if (currentRow && normalizeAdapter(currentRow.platform) !== adapter) {
|
|
5181
|
+
return {
|
|
5182
|
+
reason: "adapter_mismatch",
|
|
5183
|
+
message: `the live generation belongs to adapter ${normalizeAdapter(currentRow.platform)}, not ${adapter}`,
|
|
5184
|
+
};
|
|
5185
|
+
}
|
|
5186
|
+
let producer: ReturnType<typeof readHookProducerStateV3>;
|
|
5187
|
+
try {
|
|
5188
|
+
producer = readHookProducerStateV3(root, adapter, sessionId);
|
|
5189
|
+
} catch {
|
|
5190
|
+
return {
|
|
5191
|
+
reason: "session_mismatch",
|
|
5192
|
+
message: "the native session producer state could not be read safely",
|
|
5193
|
+
};
|
|
5194
|
+
}
|
|
5195
|
+
if (producer?.terminal) {
|
|
5196
|
+
return {
|
|
5197
|
+
reason: "terminal_generation",
|
|
5198
|
+
message: "the matching generation is terminal and cannot be repaired or reopened by heal",
|
|
5199
|
+
};
|
|
5200
|
+
}
|
|
5201
|
+
if (producer && producer.instance_id !== liveInstanceIdV3(owner)) {
|
|
5202
|
+
return {
|
|
5203
|
+
reason: "owner_mismatch",
|
|
5204
|
+
message: "the native session is bound to a different instance owner",
|
|
5205
|
+
};
|
|
5206
|
+
}
|
|
5207
|
+
if (currentRow && (!producer || producer.generation_id !== currentRow.v3_generation_id)) {
|
|
5208
|
+
return {
|
|
5209
|
+
reason: "session_mismatch",
|
|
5210
|
+
message: "the native session does not bind to the requested live generation",
|
|
5211
|
+
};
|
|
5212
|
+
}
|
|
5213
|
+
return null;
|
|
5214
|
+
}
|
|
5215
|
+
|
|
5216
|
+
function missingAuthorityForCurrentSessionBootstrap(
|
|
5217
|
+
root: string,
|
|
5218
|
+
owner: string,
|
|
5219
|
+
sessionId: string,
|
|
5220
|
+
): boolean {
|
|
5221
|
+
if (readLiveCoordinationRow(root, owner)) return false;
|
|
5222
|
+
try {
|
|
5223
|
+
const nativeSessionHasProducer = (["claude-code", "codex", "cursor"] as const).some(
|
|
5224
|
+
(adapter) => readHookProducerStateV3(root, adapter, sessionId) !== undefined,
|
|
5225
|
+
);
|
|
5226
|
+
if (nativeSessionHasProducer) return false;
|
|
5227
|
+
const instanceId = liveInstanceIdV3(owner);
|
|
5228
|
+
return !listHookProducerStateRecordsV3(root, { includeTerminal: true }).some(
|
|
5229
|
+
({ state }) => state.instance_id === instanceId,
|
|
5230
|
+
);
|
|
5231
|
+
} catch {
|
|
5232
|
+
return false;
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5235
|
+
|
|
5236
|
+
function healFailureReason(
|
|
5237
|
+
root: string,
|
|
5238
|
+
owner: string,
|
|
5239
|
+
sessionId: string,
|
|
5240
|
+
adapter: "claude-code" | "cursor" | "codex",
|
|
5241
|
+
): string {
|
|
5242
|
+
const refusal = cacheHealAuthorityRefusal(
|
|
5243
|
+
root,
|
|
5244
|
+
owner,
|
|
5245
|
+
sessionId,
|
|
5246
|
+
adapter,
|
|
5247
|
+
readLiveCoordinationRow(root, owner),
|
|
5248
|
+
);
|
|
5249
|
+
return refusal?.reason ?? "authority_missing";
|
|
5250
|
+
}
|
|
5251
|
+
|
|
5252
|
+
function emitHealFailure(reason: string, message: string): never {
|
|
5253
|
+
emit.error({
|
|
5254
|
+
code: "heal_failed",
|
|
5255
|
+
message: `coordination heal refused (reason=${reason}): ${message}`,
|
|
5256
|
+
});
|
|
5257
|
+
process.exit(1);
|
|
5258
|
+
}
|
|
5259
|
+
|
|
4880
5260
|
/**
|
|
4881
5261
|
* Emit one V3 council audit transition keyed to the exact durable manifest.
|
|
4882
5262
|
* Falls through silently when no live session can attest the observation.
|