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/dist/commands/agents.js
CHANGED
|
@@ -14,14 +14,17 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { spawnSync } from "node:child_process";
|
|
16
16
|
import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
|
|
17
|
-
import {
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
18
|
import { basename, join, resolve } from "node:path";
|
|
19
19
|
import { coordBinPath } from "../core/agents/coord-bin.js";
|
|
20
20
|
import { checkGitFinalization, formatGitFinalizationFailure, readSessionWriteClaims, } from "../core/agents/finalization.js";
|
|
21
21
|
import { emitEventV3, monorepoRoot, nativeSessionIdentity, normalizeAdapter, resolveOwner, resolveOwnerBySessionEnv, resolveOwnerWithSource, sessionIdentityFromEnv, } from "../core/agents/index.js";
|
|
22
|
-
import { reopenLiveCoordinationGenerationV3 } from "../core/agents/live-authority-v3.js";
|
|
22
|
+
import { bootstrapLiveCoordinationAuthorityV3, LiveCoordinationAuthorityV3Error, reopenLiveCoordinationGenerationV3, } from "../core/agents/live-authority-v3.js";
|
|
23
|
+
import { isAddressableName, MailboxCapacityError, queueMailboxMessage, suggestNames, } from "../core/agents/mailbox.js";
|
|
24
|
+
import { reconcileCoordinationV3 } from "../core/agents/reconcile-coordination-v3.js";
|
|
23
25
|
import { listSessionFinalizationRequestsV3, observeHostDisappearedV3, reconcileSessionFinalizationV3, requestSessionEndExplicitV3, } from "../core/agents/session-finalizer-v3.js";
|
|
24
26
|
import { SESSION_NAME_DISPLAY_NOTE, sessionNameDisplayPending, } from "../core/agents/session-name-display.js";
|
|
27
|
+
import { agentDisplayName } from "../core/agents/state/activity-log.js";
|
|
25
28
|
import { buildLifecycleSuggestedName, buildSuggestedName, readHeartbeat as readHeartbeatCache, } from "../core/agents/state/heartbeat-writer.js";
|
|
26
29
|
import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../core/agents/state/live-coordination-view.js";
|
|
27
30
|
import { foldSessionState, } from "../core/agents/state/session-state.js";
|
|
@@ -29,12 +32,13 @@ import { coordFreshnessSeconds, resolveBinName, sessionFinalizationConfig, } fro
|
|
|
29
32
|
import { readEventV3ControlState } from "../core/events/v3/control.js";
|
|
30
33
|
import { projectCoordinationViewV3 } from "../core/events/v3/coordination-view.js";
|
|
31
34
|
import { liveInstanceIdV3 } from "../core/events/v3/live-routing.js";
|
|
35
|
+
import { countSummarizedSinceV3, listDiagnosticSummariesV3, } from "../core/events/v3/producers/diagnostic-summaries.js";
|
|
32
36
|
import { listHookIntakeGroupsV3, listHookIntakeRecordsV3, } from "../core/events/v3/producers/intake.js";
|
|
33
37
|
import { listHookProducerStateRecordsV3, readHookProducerStateV3, } from "../core/events/v3/producers/recorder.js";
|
|
34
38
|
import { readLedgerV3 } from "../core/events/v3/reader.js";
|
|
35
39
|
import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../core/events/v3/writer.js";
|
|
36
40
|
import { evaluateRunQualityIfDue } from "../core/guard/index.js";
|
|
37
|
-
import { readRuntimeContextUsage } from "../core/hooks/adapter/runtime-telemetry.js";
|
|
41
|
+
import { readRuntimeContextTelemetry, readRuntimeContextUsage, } from "../core/hooks/adapter/runtime-telemetry.js";
|
|
38
42
|
import { readRemoteMachines } from "../core/presence/index.js";
|
|
39
43
|
import { registerContextCommand } from "./context.js";
|
|
40
44
|
function readCurrentCoordinationRow(instanceId) {
|
|
@@ -128,7 +132,7 @@ function lifecycleLabel(hb) {
|
|
|
128
132
|
return state === "blocked" && hb.task_state_reason ? `${state}: ${hb.task_state_reason}` : state;
|
|
129
133
|
}
|
|
130
134
|
let emit;
|
|
131
|
-
export function registerAgentsCommand(program, emitParam, programContext) {
|
|
135
|
+
export function registerAgentsCommand(program, emitParam, programContext, binName = resolveBinName()) {
|
|
132
136
|
emit = emitParam;
|
|
133
137
|
const cmd = program
|
|
134
138
|
.command("agents")
|
|
@@ -207,7 +211,7 @@ export function registerAgentsCommand(program, emitParam, programContext) {
|
|
|
207
211
|
.command("set-task <text...>")
|
|
208
212
|
.description("Declare what this agent is currently working on. Visible to peers in the " +
|
|
209
213
|
"per-prompt snapshot. Pass an empty string ('') to clear.")
|
|
210
|
-
.option("--session-id <id>", `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 \`${
|
|
214
|
+
.option("--session-id <id>", `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\`.`)
|
|
211
215
|
.action((text, opts) => {
|
|
212
216
|
runSetTask(text.join(" "), opts);
|
|
213
217
|
});
|
|
@@ -230,7 +234,8 @@ export function registerAgentsCommand(program, emitParam, programContext) {
|
|
|
230
234
|
});
|
|
231
235
|
cmd
|
|
232
236
|
.command("reconcile")
|
|
233
|
-
.description("
|
|
237
|
+
.description("Sweep the stale coordination cache, then reconcile archive, idle, parent/run " +
|
|
238
|
+
"completion, stale, superseded, and host lifecycle signals into V3 session finalization.")
|
|
234
239
|
.option("--watch", "Keep reconciling until interrupted")
|
|
235
240
|
.option("--interval-seconds <n>", "Watch interval in seconds")
|
|
236
241
|
.option("--json", "JSON output")
|
|
@@ -265,16 +270,17 @@ export function registerAgentsCommand(program, emitParam, programContext) {
|
|
|
265
270
|
});
|
|
266
271
|
cmd
|
|
267
272
|
.command("ping <name> <message...>")
|
|
268
|
-
.description("
|
|
269
|
-
"
|
|
270
|
-
"
|
|
273
|
+
.description("Send a message to another agent by name. Works whether or not that agent " +
|
|
274
|
+
"is running: a live peer sees it on their next prompt, and a name with no " +
|
|
275
|
+
"live session gets it queued until a session of that name next starts. " +
|
|
276
|
+
"Only an unknown name is refused.")
|
|
271
277
|
.option("--json", "JSON output")
|
|
272
278
|
.action((name, message, opts) => {
|
|
273
279
|
runPing(name, message.join(" "), opts);
|
|
274
280
|
});
|
|
275
281
|
cmd
|
|
276
282
|
.command("wait <name>")
|
|
277
|
-
.description(`Block until a peer agent releases files (their \`files_touched\` becomes empty, OR they exit). Pair with \`${
|
|
283
|
+
.description(`Block until a peer agent releases files (their \`files_touched\` becomes empty, OR they exit). Pair with \`${binName} agents ping\` to coordinate hand-offs.`)
|
|
278
284
|
.option("--file <path>", "Wait only for these specific paths (repeatable)", collectPath, [])
|
|
279
285
|
.option("--timeout <dur>", "Give up after this duration; suffix s/m/h/d is required (e.g. 30s, 5m, 1h). Default 60m.", "60m")
|
|
280
286
|
.option("--poll-secs <n>", "Poll interval in seconds (default 5)", "5")
|
|
@@ -297,7 +303,7 @@ export function registerAgentsCommand(program, emitParam, programContext) {
|
|
|
297
303
|
cmd
|
|
298
304
|
.command("health")
|
|
299
305
|
.description("One-screen coord-layer health rollup: heal events, council activity, " +
|
|
300
|
-
"
|
|
306
|
+
"heartbeat cache issues, and findings. Designed for " +
|
|
301
307
|
"daily glance + dashboard ingestion. Reads .harnery/.")
|
|
302
308
|
.option("--since <window>", "Window (Nh | Nd). Default: 24h.", "24h")
|
|
303
309
|
.option("--json", "JSON envelope output")
|
|
@@ -319,11 +325,10 @@ export function registerAgentsCommand(program, emitParam, programContext) {
|
|
|
319
325
|
});
|
|
320
326
|
cmd
|
|
321
327
|
.command("heal")
|
|
322
|
-
.description("
|
|
323
|
-
"
|
|
324
|
-
"
|
|
325
|
-
.
|
|
326
|
-
.requiredOption("--kind <kind>", "pidmap | cache")
|
|
328
|
+
.description("Repair the current session's disposable coordination cache from V3. " +
|
|
329
|
+
"Use explicit options to target another generation or repair process attribution.")
|
|
330
|
+
.option("--owner <id>", "Target agent's instance_id. Defaults to the current session.")
|
|
331
|
+
.option("--kind <kind>", "pidmap | cache. Defaults to cache.")
|
|
327
332
|
.option("--session-id <id>", "(--kind cache) native session id used to join the authoritative V3 generation.")
|
|
328
333
|
.option("--adapter <id>", "(--kind cache) adapter used to validate the authoritative V3 generation: " +
|
|
329
334
|
"claude-code | cursor | codex.")
|
|
@@ -331,6 +336,9 @@ export function registerAgentsCommand(program, emitParam, programContext) {
|
|
|
331
336
|
"this shell's ppid chain for a claude process. Pass explicitly " +
|
|
332
337
|
"when calling from outside Claude Code's Bash tool tree (e.g. " +
|
|
333
338
|
"from cron or an external script).")
|
|
339
|
+
.option("--quarantine-transaction <id>", "Quarantine one irreconcilable prepared authority transaction after proving its event was never committed.")
|
|
340
|
+
.option("--approval-record-id <id>", "Durable identifier for the operator approval authorizing transaction quarantine.")
|
|
341
|
+
.option("--yes", "Confirm the exact prepared transaction may be quarantined.")
|
|
334
342
|
.option("--json", "JSON envelope output")
|
|
335
343
|
.action((opts) => {
|
|
336
344
|
runHeal(opts);
|
|
@@ -427,7 +435,7 @@ async function runSessionReconcile(opts) {
|
|
|
427
435
|
}
|
|
428
436
|
let stopped = false;
|
|
429
437
|
do {
|
|
430
|
-
emit.data(
|
|
438
|
+
emit.data(reconcileCoordinationV3(root));
|
|
431
439
|
if (!opts.watch || stopped)
|
|
432
440
|
return;
|
|
433
441
|
await new Promise((resolvePromise) => {
|
|
@@ -605,13 +613,10 @@ function runIdentityAssume(target, opts) {
|
|
|
605
613
|
process.exit(1);
|
|
606
614
|
}
|
|
607
615
|
if (!opts.sessionId)
|
|
608
|
-
|
|
616
|
+
ensureAdapterSession(root);
|
|
609
617
|
const owner = opts.sessionId ?? resolveOwner();
|
|
610
618
|
if (!owner) {
|
|
611
|
-
emit.error(
|
|
612
|
-
code: "no_pidmap_entry",
|
|
613
|
-
message: "not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
614
|
-
});
|
|
619
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)"));
|
|
615
620
|
process.exit(1);
|
|
616
621
|
}
|
|
617
622
|
try {
|
|
@@ -791,14 +796,11 @@ function runWhoami(opts) {
|
|
|
791
796
|
});
|
|
792
797
|
process.exit(1);
|
|
793
798
|
}
|
|
794
|
-
|
|
799
|
+
ensureAdapterSession(root);
|
|
795
800
|
const resolved = resolveOwnerWithSource();
|
|
796
801
|
const myOwner = resolved.owner;
|
|
797
802
|
if (!myOwner) {
|
|
798
|
-
emit.error(
|
|
799
|
-
code: "no_pidmap_entry",
|
|
800
|
-
message: "not in an agent session; ppid walk found no pid-map entry",
|
|
801
|
-
});
|
|
803
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry"));
|
|
802
804
|
process.exit(1);
|
|
803
805
|
}
|
|
804
806
|
const hb = readLiveCoordinationRow(root, myOwner);
|
|
@@ -1231,49 +1233,88 @@ function cursorEnvSessionId() {
|
|
|
1231
1233
|
return null;
|
|
1232
1234
|
return raw.startsWith("bc-") && raw.length > 3 ? raw.slice(3) : raw;
|
|
1233
1235
|
}
|
|
1234
|
-
function
|
|
1235
|
-
|
|
1236
|
+
function commandSessionBootstrap() {
|
|
1237
|
+
const cursorSessionId = cursorEnvSessionId();
|
|
1238
|
+
if (process.env.CURSOR_AGENT === "1" && cursorSessionId) {
|
|
1239
|
+
return { adapter: "cursor", sessionId: cursorSessionId };
|
|
1240
|
+
}
|
|
1241
|
+
if (process.env.HARNERY_AGENT_COORD_BRIDGE?.trim() === "codex-wsl") {
|
|
1242
|
+
const sessionId = sessionIdentityFromEnv();
|
|
1243
|
+
if (sessionId)
|
|
1244
|
+
return { adapter: "codex", sessionId };
|
|
1245
|
+
}
|
|
1246
|
+
const claudeSessionId = process.env.CLAUDE_CODE_SESSION_ID?.trim();
|
|
1247
|
+
if (claudeSessionId) {
|
|
1248
|
+
return { adapter: "claude-code", sessionId: claudeSessionId };
|
|
1249
|
+
}
|
|
1250
|
+
return null;
|
|
1236
1251
|
}
|
|
1237
|
-
function
|
|
1238
|
-
|
|
1252
|
+
function ensureAdapterSession(root) {
|
|
1253
|
+
const bootstrap = commandSessionBootstrap();
|
|
1254
|
+
if (!bootstrap)
|
|
1255
|
+
return;
|
|
1256
|
+
// Claude Code owns a reliable native SessionStart hook. Its environment is
|
|
1257
|
+
// accepted by the explicit `agents heal` recovery path, but ordinary
|
|
1258
|
+
// identity and status commands must not impersonate that hook. The heal
|
|
1259
|
+
// bootstrap records derived provenance instead.
|
|
1260
|
+
if (bootstrap.adapter === "claude-code")
|
|
1239
1261
|
return;
|
|
1240
1262
|
// Explicit owner override means the caller already knows who they are.
|
|
1241
1263
|
// Bootstrapping sessionStart inherits that env into the child hook, which
|
|
1242
1264
|
// re-projects a fresh heartbeat onto the override owner and can wipe an
|
|
1243
1265
|
// assumed persona agent_id (seen under Cursor integration fixtures).
|
|
1244
|
-
if (process.env.HARNERY_AGENT_COORD_OWNER?.trim())
|
|
1266
|
+
if (bootstrap.adapter === "cursor" && process.env.HARNERY_AGENT_COORD_OWNER?.trim())
|
|
1245
1267
|
return;
|
|
1246
1268
|
if (resolveOwnerBySessionEnv(root))
|
|
1247
1269
|
return;
|
|
1248
|
-
const sessionId = cursorEnvSessionId();
|
|
1249
|
-
if (!sessionId)
|
|
1250
|
-
return;
|
|
1251
1270
|
const agentHook = coordBinPath("agent-hook", root);
|
|
1252
1271
|
if (!agentHook)
|
|
1253
1272
|
return;
|
|
1254
1273
|
const payload = JSON.stringify({
|
|
1255
|
-
conversation_id: sessionId,
|
|
1256
|
-
session_id: sessionId,
|
|
1274
|
+
...(bootstrap.adapter === "cursor" ? { conversation_id: bootstrap.sessionId } : {}),
|
|
1275
|
+
session_id: bootstrap.sessionId,
|
|
1257
1276
|
hook_event_name: "sessionStart",
|
|
1258
1277
|
workspace_roots: [root],
|
|
1259
1278
|
cwd: root,
|
|
1260
|
-
|
|
1261
|
-
|
|
1279
|
+
...(bootstrap.adapter === "cursor"
|
|
1280
|
+
? { composer_mode: "agent", is_background_agent: false }
|
|
1281
|
+
: { source: "resume" }),
|
|
1262
1282
|
});
|
|
1263
|
-
spawnSync("bash", [agentHook, "session-start", "--adapter",
|
|
1283
|
+
spawnSync("bash", [agentHook, "session-start", "--adapter", bootstrap.adapter], {
|
|
1264
1284
|
input: payload,
|
|
1265
1285
|
cwd: root,
|
|
1266
1286
|
encoding: "utf8",
|
|
1267
1287
|
timeout: 3000,
|
|
1268
1288
|
env: {
|
|
1269
1289
|
...process.env,
|
|
1270
|
-
HARNERY_AGENT_COORD_PLATFORM:
|
|
1290
|
+
HARNERY_AGENT_COORD_PLATFORM: bootstrap.adapter,
|
|
1271
1291
|
HARNERY_COORD_ROOT_OVERRIDE: root,
|
|
1272
|
-
|
|
1273
|
-
|
|
1292
|
+
HARNERY_AGENT_COORD_SESSION_ID: bootstrap.sessionId,
|
|
1293
|
+
...(bootstrap.adapter === "cursor"
|
|
1294
|
+
? {
|
|
1295
|
+
CURSOR_SESSION_ID: bootstrap.sessionId,
|
|
1296
|
+
CURSOR_CONVERSATION_ID: bootstrap.sessionId,
|
|
1297
|
+
}
|
|
1298
|
+
: { CODEX_THREAD_ID: bootstrap.sessionId }),
|
|
1274
1299
|
},
|
|
1275
1300
|
});
|
|
1276
1301
|
}
|
|
1302
|
+
function sessionResolutionFailure(root, fallbackMessage) {
|
|
1303
|
+
if (!sessionIdentityFromEnv())
|
|
1304
|
+
return { code: "no_pidmap_entry", message: fallbackMessage };
|
|
1305
|
+
const control = readEventV3ControlState(root);
|
|
1306
|
+
if (control.state !== "candidate" && control.state !== "active") {
|
|
1307
|
+
const detail = `${control.state}:${control.reason}`;
|
|
1308
|
+
return {
|
|
1309
|
+
code: "event_v3_control_unavailable",
|
|
1310
|
+
message: `the adapter session identity is present, but the V3 control state cannot accept session onboarding (${detail})`,
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
return {
|
|
1314
|
+
code: "session_generation_unavailable",
|
|
1315
|
+
message: "the adapter session identity is present, but no current V3 session generation was available after onboarding",
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1277
1318
|
function runReleaseClaim(path) {
|
|
1278
1319
|
const root = monorepoRoot();
|
|
1279
1320
|
if (!root) {
|
|
@@ -1285,10 +1326,7 @@ function runReleaseClaim(path) {
|
|
|
1285
1326
|
}
|
|
1286
1327
|
const myOwner = resolveOwner();
|
|
1287
1328
|
if (!myOwner) {
|
|
1288
|
-
emit.error(
|
|
1289
|
-
code: "no_pidmap_entry",
|
|
1290
|
-
message: "not in an agent session; ppid walk found no pid-map entry",
|
|
1291
|
-
});
|
|
1329
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry"));
|
|
1292
1330
|
process.exit(1);
|
|
1293
1331
|
}
|
|
1294
1332
|
// Canonicalize: absolute paths under coordRoot get the prefix stripped;
|
|
@@ -1329,13 +1367,10 @@ function runSetTask(task, opts) {
|
|
|
1329
1367
|
// ritual command. The env id carries the same trust as an explicit
|
|
1330
1368
|
// --session-id, and set-task mints the heartbeat exactly as that path does.
|
|
1331
1369
|
if (!opts?.sessionId)
|
|
1332
|
-
|
|
1370
|
+
ensureAdapterSession(root);
|
|
1333
1371
|
const myOwner = opts?.sessionId ?? resolveOwner() ?? sessionIdentityFromEnv();
|
|
1334
1372
|
if (!myOwner) {
|
|
1335
|
-
emit.error(
|
|
1336
|
-
code: "no_pidmap_entry",
|
|
1337
|
-
message: "not in an agent session; no session-id environment identity and the ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
1338
|
-
});
|
|
1373
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; no session-id environment identity and the ppid walk found no pid-map entry (pass --session-id to bypass)"));
|
|
1339
1374
|
process.exit(1);
|
|
1340
1375
|
}
|
|
1341
1376
|
// Snapshot BEFORE the mutation: the writer stamps `suggested_session_name`
|
|
@@ -1416,13 +1451,10 @@ function runLifecycle(rawState, opts) {
|
|
|
1416
1451
|
return;
|
|
1417
1452
|
}
|
|
1418
1453
|
if (!opts.sessionId)
|
|
1419
|
-
|
|
1454
|
+
ensureAdapterSession(root);
|
|
1420
1455
|
const myOwner = opts.sessionId ?? resolveOwner() ?? sessionIdentityFromEnv();
|
|
1421
1456
|
if (!myOwner) {
|
|
1422
|
-
emit.error(
|
|
1423
|
-
code: "no_pidmap_entry",
|
|
1424
|
-
message: "not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
1425
|
-
});
|
|
1457
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)"));
|
|
1426
1458
|
process.exitCode = 1;
|
|
1427
1459
|
return;
|
|
1428
1460
|
}
|
|
@@ -1581,13 +1613,10 @@ function runSuggestName(descriptionParts, opts) {
|
|
|
1581
1613
|
// Identity: prefer explicit --session-id (ppid-walk-free escape hatch, mirrors
|
|
1582
1614
|
// `status`/`set-task`), fall back to the ppid walk for interactive shell use.
|
|
1583
1615
|
if (!opts.sessionId)
|
|
1584
|
-
|
|
1616
|
+
ensureAdapterSession(root);
|
|
1585
1617
|
const myOwner = opts.sessionId ?? resolveOwner();
|
|
1586
1618
|
if (!myOwner) {
|
|
1587
|
-
emit.error(
|
|
1588
|
-
code: "no_pidmap_entry",
|
|
1589
|
-
message: "not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)",
|
|
1590
|
-
});
|
|
1619
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry (pass --session-id to bypass)"));
|
|
1591
1620
|
process.exit(1);
|
|
1592
1621
|
}
|
|
1593
1622
|
const hb = readCurrentCoordinationRow(myOwner);
|
|
@@ -1648,13 +1677,10 @@ function runStatus(opts) {
|
|
|
1648
1677
|
// Identity resolution: prefer explicit --session-id (hook-friendly), fall
|
|
1649
1678
|
// back to ppid walk for interactive shell usage.
|
|
1650
1679
|
if (!opts.sessionId)
|
|
1651
|
-
|
|
1680
|
+
ensureAdapterSession(root);
|
|
1652
1681
|
const myOwner = opts.sessionId ?? resolveOwner();
|
|
1653
1682
|
if (!myOwner) {
|
|
1654
|
-
emit.error(
|
|
1655
|
-
code: "no_pidmap_entry",
|
|
1656
|
-
message: "not in an agent session; ppid walk found no pid-map entry (pass --session-id from a hook payload)",
|
|
1657
|
-
});
|
|
1683
|
+
emit.error(sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry (pass --session-id from a hook payload)"));
|
|
1658
1684
|
process.exit(1);
|
|
1659
1685
|
}
|
|
1660
1686
|
const hb = readCurrentCoordinationRow(myOwner);
|
|
@@ -1685,7 +1711,7 @@ function runStatus(opts) {
|
|
|
1685
1711
|
return;
|
|
1686
1712
|
}
|
|
1687
1713
|
}
|
|
1688
|
-
emitEventV3({
|
|
1714
|
+
const statusEmitted = emitEventV3({
|
|
1689
1715
|
owner: myOwner,
|
|
1690
1716
|
session: nativeSessionIdentity(hb, myOwner),
|
|
1691
1717
|
adapter: normalizeAdapter(hb.platform),
|
|
@@ -1694,6 +1720,16 @@ function runStatus(opts) {
|
|
|
1694
1720
|
status: opts.endTurn ? "end_turn_checked" : opts.json ? "json_checked" : "box_checked",
|
|
1695
1721
|
},
|
|
1696
1722
|
});
|
|
1723
|
+
// The closing box is a success artifact. Never print it when the exact
|
|
1724
|
+
// evidence enforced by the Stop hook did not reach the ledger.
|
|
1725
|
+
if (opts.endTurn && !statusEmitted) {
|
|
1726
|
+
emit.error({
|
|
1727
|
+
code: "status_event_failed",
|
|
1728
|
+
message: `the end-of-turn status event could not be recorded; no status box was issued; rerun \`${resolveBinName(root)} agents status --end-turn\``,
|
|
1729
|
+
});
|
|
1730
|
+
process.exitCode = 1;
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1697
1733
|
let sessionEnd;
|
|
1698
1734
|
if (opts.endSession) {
|
|
1699
1735
|
const canonicalInstanceId = liveInstanceIdV3(hb.instance_id);
|
|
@@ -1753,16 +1789,13 @@ function runStatus(opts) {
|
|
|
1753
1789
|
ctxStr = "unavailable";
|
|
1754
1790
|
}
|
|
1755
1791
|
else if (ctxUsage.percentOnly) {
|
|
1756
|
-
|
|
1757
|
-
// window. Show the percent + window estimate, marked as estimated.
|
|
1758
|
-
const pct = Math.round((ctxUsage.used / ctxUsage.window) * 100);
|
|
1759
|
-
ctxStr = `~${pct}% (Cursor; ${fmtTokens(ctxUsage.window)} window est.)`;
|
|
1792
|
+
ctxStr = `${Math.round(ctxUsage.usedPercent)}% (Cursor first-party)`;
|
|
1760
1793
|
}
|
|
1761
1794
|
else {
|
|
1762
1795
|
ctxStr = `${fmtTokens(ctxUsage.used)} / ${fmtTokens(ctxUsage.window)} (${Math.round((ctxUsage.used / ctxUsage.window) * 100)}%)`;
|
|
1763
1796
|
}
|
|
1764
1797
|
const timeStr = formatLocalTime(new Date());
|
|
1765
|
-
const displayName =
|
|
1798
|
+
const displayName = agentDisplayName(hb.instance_id, hb.name);
|
|
1766
1799
|
// Council pending: list of council IDs where this agent is a member of an
|
|
1767
1800
|
// active council in `open` round_status without a contribution to that round.
|
|
1768
1801
|
// Best-effort: fails silently if .harnery/councils/ doesn't exist.
|
|
@@ -1805,8 +1838,8 @@ function runStatus(opts) {
|
|
|
1805
1838
|
})),
|
|
1806
1839
|
})),
|
|
1807
1840
|
pending_councils: pendingCouncils,
|
|
1808
|
-
context_used: ctxUsage
|
|
1809
|
-
context_window: ctxUsage
|
|
1841
|
+
context_used: ctxUsage && "used" in ctxUsage ? ctxUsage.used : null,
|
|
1842
|
+
context_window: ctxUsage && "window" in ctxUsage ? ctxUsage.window : null,
|
|
1810
1843
|
timestamp_iso: new Date().toISOString(),
|
|
1811
1844
|
timestamp_local: timeStr,
|
|
1812
1845
|
...(quality ? { quality } : {}),
|
|
@@ -1924,15 +1957,15 @@ function formatPeers(peers, cap, staleCount, remoteMachines = []) {
|
|
|
1924
1957
|
}
|
|
1925
1958
|
return main;
|
|
1926
1959
|
}
|
|
1927
|
-
export function collectStatusPeerHealth(root, myOwner, nowMs = Date.now()) {
|
|
1960
|
+
export function collectStatusPeerHealth(root, myOwner, nowMs = Date.now(), readRows = readLiveCoordinationRows, freshnessSeconds = freshnessCutoffSecs()) {
|
|
1928
1961
|
let rows = [];
|
|
1929
1962
|
try {
|
|
1930
|
-
rows =
|
|
1963
|
+
rows = readRows(root);
|
|
1931
1964
|
}
|
|
1932
1965
|
catch {
|
|
1933
1966
|
// V3 authority failures must not resurrect disposable cache rows.
|
|
1934
1967
|
}
|
|
1935
|
-
const cutoffMs = nowMs -
|
|
1968
|
+
const cutoffMs = nowMs - freshnessSeconds * 1000;
|
|
1936
1969
|
const livePeers = [];
|
|
1937
1970
|
let stale = 0;
|
|
1938
1971
|
for (const peer of rows) {
|
|
@@ -1960,85 +1993,21 @@ function readContextUsage(sessionId, platform) {
|
|
|
1960
1993
|
// Dispatch by platform: Codex's JSONL shape is different from Claude Code's
|
|
1961
1994
|
// (event_msg/response_item vs user/assistant), and Codex transcripts live
|
|
1962
1995
|
// under ~/.codex/sessions/YYYY/MM/DD/ rather than ~/.claude/projects/.
|
|
1963
|
-
// Cursor
|
|
1964
|
-
//
|
|
1965
|
-
// readCursorContextUsage reads that via bun:sqlite (percent-only).
|
|
1996
|
+
// Cursor stores a first-party percentage in workspaceStorage. The shared
|
|
1997
|
+
// runtime reader returns it without fabricating a token denominator.
|
|
1966
1998
|
if (platform === "codex")
|
|
1967
1999
|
return readRuntimeContextUsage("codex", sessionId);
|
|
1968
|
-
if (platform === "cursor")
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
// for parent chats).
|
|
1978
|
-
//
|
|
1979
|
-
// Roots searched: ~/.config/Cursor/User/workspaceStorage (Linux native install)
|
|
1980
|
-
// and /mnt/c/Users/*/AppData/Roaming/Cursor/User/workspaceStorage (WSL).
|
|
1981
|
-
// We don't filter by workspace path; we scan every workspace's state.vscdb
|
|
1982
|
-
// looking for a composerId match. Cheap enough at status time (~60K per file,
|
|
1983
|
-
// <10ms typical). When a match is found, returns synthetic { used, window }
|
|
1984
|
-
// pair where the percent is what's real; absolutes are derived as
|
|
1985
|
-
// (window * percent / 100). Window hard-coded to a Cursor-typical 200K.
|
|
1986
|
-
const roots = [];
|
|
1987
|
-
const linuxRoot = resolve(homedir(), ".config", "Cursor", "User", "workspaceStorage");
|
|
1988
|
-
if (existsSync(linuxRoot))
|
|
1989
|
-
roots.push(linuxRoot);
|
|
1990
|
-
try {
|
|
1991
|
-
if (existsSync("/mnt/c/Users")) {
|
|
1992
|
-
for (const u of readdirSync("/mnt/c/Users")) {
|
|
1993
|
-
const p = `/mnt/c/Users/${u}/AppData/Roaming/Cursor/User/workspaceStorage`;
|
|
1994
|
-
if (existsSync(p))
|
|
1995
|
-
roots.push(p);
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
catch {
|
|
2000
|
-
// ignore
|
|
2001
|
-
}
|
|
2002
|
-
for (const root of roots) {
|
|
2003
|
-
let workspaces;
|
|
2004
|
-
try {
|
|
2005
|
-
workspaces = readdirSync(root);
|
|
2006
|
-
}
|
|
2007
|
-
catch {
|
|
2008
|
-
continue;
|
|
2009
|
-
}
|
|
2010
|
-
for (const ws of workspaces) {
|
|
2011
|
-
const dbPath = `${root}/${ws}/state.vscdb`;
|
|
2012
|
-
if (!existsSync(dbPath))
|
|
2013
|
-
continue;
|
|
2014
|
-
try {
|
|
2015
|
-
// Lazy-import bun:sqlite so non-Bun runtimes (if any) don't choke at load.
|
|
2016
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
2017
|
-
const { Database } = require("bun:sqlite");
|
|
2018
|
-
const db = new Database(dbPath, { readonly: true });
|
|
2019
|
-
const row = db
|
|
2020
|
-
.query("SELECT value FROM ItemTable WHERE key = 'composer.composerData'")
|
|
2021
|
-
.get();
|
|
2022
|
-
db.close();
|
|
2023
|
-
if (!row?.value)
|
|
2024
|
-
continue;
|
|
2025
|
-
const text = typeof row.value === "string" ? row.value : Buffer.from(row.value).toString("utf8");
|
|
2026
|
-
const parsed = JSON.parse(text);
|
|
2027
|
-
const composers = Array.isArray(parsed?.allComposers) ? parsed.allComposers : [];
|
|
2028
|
-
for (const c of composers) {
|
|
2029
|
-
if (c?.composerId === sessionId && typeof c?.contextUsagePercent === "number") {
|
|
2030
|
-
const window = 200000; // hard-coded Cursor-typical window; refine when Cursor exposes the actual ceiling
|
|
2031
|
-
const used = Math.round((window * c.contextUsagePercent) / 100);
|
|
2032
|
-
return { used, window, percentOnly: true };
|
|
2033
|
-
}
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
catch {
|
|
2037
|
-
// ignore: DB locked, schema drift, etc. Move on to the next workspace.
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2000
|
+
if (platform === "cursor") {
|
|
2001
|
+
const telemetry = readRuntimeContextTelemetry({
|
|
2002
|
+
adapter: "cursor",
|
|
2003
|
+
session_id: sessionId,
|
|
2004
|
+
mode: "status",
|
|
2005
|
+
});
|
|
2006
|
+
return telemetry.state === "observed" && "used_percent" in telemetry
|
|
2007
|
+
? { usedPercent: telemetry.used_percent, percentOnly: true }
|
|
2008
|
+
: null;
|
|
2040
2009
|
}
|
|
2041
|
-
return
|
|
2010
|
+
return readRuntimeContextUsage("claude-code", sessionId);
|
|
2042
2011
|
}
|
|
2043
2012
|
function formatLocalTime(d) {
|
|
2044
2013
|
// "Sat, May 9, 2026, 3:48 AM CDT", rendered in the Chicago timezone.
|
|
@@ -2475,6 +2444,47 @@ export function collectEventLedgerHealthV3(root, nowMs = Date.now()) {
|
|
|
2475
2444
|
catch (error) {
|
|
2476
2445
|
collectionErrors.push(`diagnostics spool unreadable: ${errorText(error)}`);
|
|
2477
2446
|
}
|
|
2447
|
+
// 4b) Coalesced diagnostic summaries: occurrences the producer bounded into
|
|
2448
|
+
// `diagnostic-summaries/` instead of loose files. Counted into the logical
|
|
2449
|
+
// totals so mitigation can never make an active fault look healthy; the
|
|
2450
|
+
// physical loose file count stays visible separately.
|
|
2451
|
+
let summarizedTotal = 0;
|
|
2452
|
+
let summaryFiles = 0;
|
|
2453
|
+
let mitigationFailOpen = 0;
|
|
2454
|
+
try {
|
|
2455
|
+
const listing = listDiagnosticSummariesV3(root);
|
|
2456
|
+
summaryFiles = listing.file_count;
|
|
2457
|
+
mitigationFailOpen = listing.mitigation_health?.fail_open_count ?? 0;
|
|
2458
|
+
if (listing.unreadable_count > 0) {
|
|
2459
|
+
collectionErrors.push(`${listing.unreadable_count} diagnostic summary file(s) unreadable`);
|
|
2460
|
+
}
|
|
2461
|
+
const dayAgoMs = nowMs - 24 * 60 * 60 * 1000;
|
|
2462
|
+
const hourAgoMs = nowMs - 60 * 60 * 1000;
|
|
2463
|
+
for (const summary of listing.summaries) {
|
|
2464
|
+
summarizedTotal += summary.summarized_count;
|
|
2465
|
+
const entry = byCategory[summary.category] ?? { total: 0, last_24h: 0 };
|
|
2466
|
+
const recent = recentByCategory[summary.category] ?? { last_1h: 0, latest_at: null };
|
|
2467
|
+
byCategory[summary.category] = entry;
|
|
2468
|
+
recentByCategory[summary.category] = recent;
|
|
2469
|
+
entry.total += summary.summarized_count;
|
|
2470
|
+
const day = countSummarizedSinceV3([summary], dayAgoMs, undefined, nowMs);
|
|
2471
|
+
const hour = countSummarizedSinceV3([summary], hourAgoMs, undefined, nowMs);
|
|
2472
|
+
entry.last_24h += day;
|
|
2473
|
+
diagnostics24h += day;
|
|
2474
|
+
recent.last_1h += hour;
|
|
2475
|
+
diagnostics1h += hour;
|
|
2476
|
+
const lastMs = summary.last_summarized_at ? Date.parse(summary.last_summarized_at) : NaN;
|
|
2477
|
+
if (Number.isFinite(lastMs)) {
|
|
2478
|
+
latestDiagnosticMs = Math.max(latestDiagnosticMs, lastMs);
|
|
2479
|
+
if (!recent.latest_at || lastMs > Date.parse(recent.latest_at)) {
|
|
2480
|
+
recent.latest_at = new Date(lastMs).toISOString();
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
catch (error) {
|
|
2486
|
+
collectionErrors.push(`diagnostic summaries unreadable: ${errorText(error)}`);
|
|
2487
|
+
}
|
|
2478
2488
|
return {
|
|
2479
2489
|
state: "live",
|
|
2480
2490
|
mode: control.state,
|
|
@@ -2485,7 +2495,10 @@ export function collectEventLedgerHealthV3(root, nowMs = Date.now()) {
|
|
|
2485
2495
|
pending_finalizations: pending,
|
|
2486
2496
|
intake_spool: { total: intakeTotal, groups: intakeGroups },
|
|
2487
2497
|
diagnostics_spool: {
|
|
2488
|
-
total: diagnosticsTotal,
|
|
2498
|
+
total: diagnosticsTotal + summarizedTotal,
|
|
2499
|
+
loose_total: diagnosticsTotal,
|
|
2500
|
+
summarized_total: summarizedTotal,
|
|
2501
|
+
summary_files: summaryFiles,
|
|
2489
2502
|
last_24h: diagnostics24h,
|
|
2490
2503
|
last_1h: diagnostics1h,
|
|
2491
2504
|
latest_at: Number.isFinite(latestDiagnosticMs)
|
|
@@ -2493,6 +2506,7 @@ export function collectEventLedgerHealthV3(root, nowMs = Date.now()) {
|
|
|
2493
2506
|
: null,
|
|
2494
2507
|
by_category: byCategory,
|
|
2495
2508
|
recent_by_category: recentByCategory,
|
|
2509
|
+
mitigation_fail_open: mitigationFailOpen,
|
|
2496
2510
|
},
|
|
2497
2511
|
span_pressure: spanPressure,
|
|
2498
2512
|
collection_errors: collectionErrors,
|
|
@@ -2943,13 +2957,13 @@ function runTrace(name, opts) {
|
|
|
2943
2957
|
/**
|
|
2944
2958
|
* V3 generations, not disposable heartbeat caches, are the active-agent authority.
|
|
2945
2959
|
*/
|
|
2946
|
-
export function collectActiveAgentHealth(root, nowMs = Date.now()) {
|
|
2960
|
+
export function collectActiveAgentHealth(root, nowMs = Date.now(), readRows = readLiveCoordinationRows, freshnessSeconds = freshnessCutoffSecs()) {
|
|
2947
2961
|
const source = "event-ledger-v3";
|
|
2948
2962
|
let heartbeats = [];
|
|
2949
2963
|
try {
|
|
2950
2964
|
const control = readEventV3ControlState(root);
|
|
2951
2965
|
if (control.state === "candidate" || control.state === "active") {
|
|
2952
|
-
heartbeats =
|
|
2966
|
+
heartbeats = readRows(root);
|
|
2953
2967
|
}
|
|
2954
2968
|
}
|
|
2955
2969
|
catch {
|
|
@@ -2975,7 +2989,7 @@ export function collectActiveAgentHealth(root, nowMs = Date.now()) {
|
|
|
2975
2989
|
const ageMs = Number.isFinite(lastObservedMs)
|
|
2976
2990
|
? nowMs - lastObservedMs
|
|
2977
2991
|
: Number.POSITIVE_INFINITY;
|
|
2978
|
-
if (ageMs >
|
|
2992
|
+
if (ageMs > freshnessSeconds * 1000)
|
|
2979
2993
|
stale += 1;
|
|
2980
2994
|
}
|
|
2981
2995
|
return {
|
|
@@ -2987,6 +3001,17 @@ export function collectActiveAgentHealth(root, nowMs = Date.now()) {
|
|
|
2987
3001
|
stale,
|
|
2988
3002
|
};
|
|
2989
3003
|
}
|
|
3004
|
+
/** Classify a parseable heartbeat cache file without conflating age with corruption. */
|
|
3005
|
+
export function classifyHeartbeatCacheIssue(heartbeat, nowMs, staleAgeMs) {
|
|
3006
|
+
if (!heartbeat.name || heartbeat.name === "unknown")
|
|
3007
|
+
return "no-name";
|
|
3008
|
+
const lastHeartbeatMs = heartbeat.last_heartbeat
|
|
3009
|
+
? Date.parse(heartbeat.last_heartbeat)
|
|
3010
|
+
: Number.NaN;
|
|
3011
|
+
if (!Number.isFinite(lastHeartbeatMs))
|
|
3012
|
+
return "invalid-heartbeat";
|
|
3013
|
+
return nowMs - lastHeartbeatMs > staleAgeMs ? "stale-age" : null;
|
|
3014
|
+
}
|
|
2990
3015
|
function runHealth(opts) {
|
|
2991
3016
|
if (opts.json)
|
|
2992
3017
|
emit.config({ format: "json" });
|
|
@@ -3067,12 +3092,12 @@ function runHealth(opts) {
|
|
|
3067
3092
|
.slice(0, 5)
|
|
3068
3093
|
.map(([agent, count]) => ({ agent, count }));
|
|
3069
3094
|
const activeAgents = collectActiveAgentHealth(root, nowMs);
|
|
3070
|
-
//
|
|
3071
|
-
//
|
|
3072
|
-
//
|
|
3073
|
-
let
|
|
3074
|
-
const
|
|
3075
|
-
const
|
|
3095
|
+
// Heartbeat cache issues: files in active/ that are unparseable, nameless,
|
|
3096
|
+
// invalidly timestamped, or stale. Old parseable timestamps are ordinary
|
|
3097
|
+
// staleness, not evidence of epoch-like timestamp corruption.
|
|
3098
|
+
let cacheIssueCount = 0;
|
|
3099
|
+
const cacheIssueSamples = [];
|
|
3100
|
+
const STALE_HEARTBEAT_AGE_MS = 24 * 60 * 60 * 1000;
|
|
3076
3101
|
if (existsSync(activeDir)) {
|
|
3077
3102
|
for (const file of readdirSync(activeDir)) {
|
|
3078
3103
|
if (!file.endsWith(".json"))
|
|
@@ -3086,20 +3111,16 @@ function runHealth(opts) {
|
|
|
3086
3111
|
hb = null;
|
|
3087
3112
|
}
|
|
3088
3113
|
if (!hb || typeof hb.instance_id !== "string") {
|
|
3089
|
-
|
|
3090
|
-
if (
|
|
3091
|
-
|
|
3114
|
+
cacheIssueCount++;
|
|
3115
|
+
if (cacheIssueSamples.length < 5)
|
|
3116
|
+
cacheIssueSamples.push(`${idFromFile.slice(0, 12)} (unparseable/no-id)`);
|
|
3092
3117
|
continue;
|
|
3093
3118
|
}
|
|
3094
|
-
const
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
zombieCount++;
|
|
3100
|
-
if (zombieSamples.length < 5) {
|
|
3101
|
-
const why = !hb.name || hb.name === "unknown" ? "no-name" : "epoch-age";
|
|
3102
|
-
zombieSamples.push(`${idFromFile.slice(0, 12)} (${why})`);
|
|
3119
|
+
const cacheIssue = classifyHeartbeatCacheIssue(hb, nowMs, STALE_HEARTBEAT_AGE_MS);
|
|
3120
|
+
if (cacheIssue) {
|
|
3121
|
+
cacheIssueCount++;
|
|
3122
|
+
if (cacheIssueSamples.length < 5) {
|
|
3123
|
+
cacheIssueSamples.push(`${idFromFile.slice(0, 12)} (${cacheIssue})`);
|
|
3103
3124
|
}
|
|
3104
3125
|
}
|
|
3105
3126
|
}
|
|
@@ -3115,11 +3136,11 @@ function runHealth(opts) {
|
|
|
3115
3136
|
activeCouncils++;
|
|
3116
3137
|
}
|
|
3117
3138
|
}
|
|
3118
|
-
//
|
|
3119
|
-
const
|
|
3139
|
+
// Finding detection.
|
|
3140
|
+
const findings = [];
|
|
3120
3141
|
for (const { agent, count } of healTopAgents) {
|
|
3121
3142
|
if (count >= 5) {
|
|
3122
|
-
|
|
3143
|
+
findings.push(`${agent} self-healed ${count}x in ${opts.since}; possible idle-prune loop or PID instability`);
|
|
3123
3144
|
}
|
|
3124
3145
|
}
|
|
3125
3146
|
if (activeAgents.stale > 0) {
|
|
@@ -3127,35 +3148,37 @@ function runHealth(opts) {
|
|
|
3127
3148
|
const action = activeAgents.source === "event-ledger-v3"
|
|
3128
3149
|
? "lifecycle reconciliation may be delayed"
|
|
3129
3150
|
: "heal mechanism may not be firing";
|
|
3130
|
-
|
|
3151
|
+
findings.push(`${activeAgents.stale} active ${noun}(s) without activity for ${Math.floor(freshnessCutoffSecs() / 60)}min; ${action}`);
|
|
3131
3152
|
}
|
|
3132
3153
|
const expectedSchema = "v3";
|
|
3133
3154
|
const unexpectedSchemas = Object.keys(activeAgents.by_schema_version).filter((schema) => schema !== expectedSchema);
|
|
3134
3155
|
if (unexpectedSchemas.length > 0) {
|
|
3135
|
-
|
|
3156
|
+
findings.push(`Unexpected active-agent schema versions in use: ${unexpectedSchemas.join(", ")} (expected ${expectedSchema})`);
|
|
3136
3157
|
}
|
|
3137
|
-
// Only recent hook failures are active
|
|
3158
|
+
// Only recent hook failures are active findings. Historical rows remain in
|
|
3138
3159
|
// the report with exact error signatures and their latest timestamp.
|
|
3139
3160
|
if (hookErrors.last1h > 0) {
|
|
3140
3161
|
const top = hookErrors.recentTopErrors[0];
|
|
3141
3162
|
const detail = top ? `: top '${top.error.slice(0, 80)}' x${top.count} (${top.phase})` : "";
|
|
3142
|
-
|
|
3163
|
+
findings.push(`agent-hook errored ${hookErrors.last1h}x in the last hour${detail}`);
|
|
3143
3164
|
}
|
|
3144
3165
|
if (stream.cursor_backlog > 500) {
|
|
3145
|
-
|
|
3166
|
+
findings.push(`projection cursor is ${stream.cursor_backlog} events behind; drain lagging (stop projection may be failing)`);
|
|
3146
3167
|
}
|
|
3147
|
-
// Raw V3 stream size is not
|
|
3168
|
+
// Raw V3 stream size is not a finding; catalog rotation bounds readers.
|
|
3148
3169
|
if ((sweptByReason.unparseable ?? 0) > 0) {
|
|
3149
|
-
|
|
3170
|
+
findings.push(`${sweptByReason.unparseable} heartbeat(s) swept as unparseable in ${opts.since}; possible corruption or a non-atomic writer`);
|
|
3150
3171
|
}
|
|
3151
|
-
if (
|
|
3152
|
-
|
|
3172
|
+
if (cacheIssueCount > 0) {
|
|
3173
|
+
findings.push(`${cacheIssueCount} heartbeat cache issue(s) in active/ (${cacheIssueSamples.join(", ")}); ` +
|
|
3174
|
+
"rows the last sweep deliberately kept (malformed but mtime-fresh, or neither audit " +
|
|
3175
|
+
"write could persist), or that aged past the freshness cutoff since it ran");
|
|
3153
3176
|
}
|
|
3154
3177
|
if (stopRemediation.total > 0) {
|
|
3155
3178
|
const who = stopRemediation.sessions.length > 0
|
|
3156
3179
|
? ` (sessions: ${stopRemediation.sessions.map((s) => s.slice(0, 8)).join(", ")})`
|
|
3157
3180
|
: "";
|
|
3158
|
-
|
|
3181
|
+
findings.push(`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`);
|
|
3159
3182
|
}
|
|
3160
3183
|
if (eventLedger.state === "live") {
|
|
3161
3184
|
// Open spans whose generation has no open turn: the turn ended without its
|
|
@@ -3163,13 +3186,13 @@ function runHealth(opts) {
|
|
|
3163
3186
|
const orphanGenerations = eventLedger.open_spans.generations.filter((generation) => !generation.turn_open);
|
|
3164
3187
|
if (orphanGenerations.length > 0) {
|
|
3165
3188
|
const orphanSpans = orphanGenerations.reduce((sum, generation) => sum + generation.span_count, 0);
|
|
3166
|
-
|
|
3189
|
+
findings.push(`${orphanSpans} open tool span(s) across ${orphanGenerations.length} generation(s) with no open turn; orphaned spans block clean session end`);
|
|
3167
3190
|
}
|
|
3168
3191
|
for (const pressure of eventLedger.span_pressure) {
|
|
3169
|
-
|
|
3192
|
+
findings.push(`${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)`);
|
|
3170
3193
|
}
|
|
3171
3194
|
for (const collectionError of eventLedger.collection_errors) {
|
|
3172
|
-
|
|
3195
|
+
findings.push(`event-ledger health: ${collectionError}`);
|
|
3173
3196
|
}
|
|
3174
3197
|
}
|
|
3175
3198
|
const report = {
|
|
@@ -3213,14 +3236,14 @@ function runHealth(opts) {
|
|
|
3213
3236
|
recent_top_errors: hookErrors.recentTopErrors,
|
|
3214
3237
|
},
|
|
3215
3238
|
stream,
|
|
3216
|
-
|
|
3239
|
+
heartbeat_cache_issues: { count: cacheIssueCount, samples: cacheIssueSamples },
|
|
3217
3240
|
event_ledger: eventLedger,
|
|
3218
3241
|
stop_remediation: {
|
|
3219
3242
|
total: stopRemediation.total,
|
|
3220
3243
|
latest_at: stopRemediation.latestAt,
|
|
3221
3244
|
sessions: stopRemediation.sessions,
|
|
3222
3245
|
},
|
|
3223
|
-
|
|
3246
|
+
findings,
|
|
3224
3247
|
};
|
|
3225
3248
|
if (opts.json) {
|
|
3226
3249
|
emit.data(report);
|
|
@@ -3278,7 +3301,7 @@ function renderHealthBox(report) {
|
|
|
3278
3301
|
`open spans ${ledger.open_spans.total}${orphanGenerations > 0 ? ` (${orphanGenerations} gen turn-closed)` : ""}`,
|
|
3279
3302
|
`pending ends ${ledger.pending_finalizations.length}${pendingAges ? ` (${pendingAges})` : ""}`,
|
|
3280
3303
|
`intake ${ledger.intake_spool.total}`,
|
|
3281
|
-
`diagnostics ${ledger.diagnostics_spool.total} (${ledger.diagnostics_spool.last_1h} in 1h / ${ledger.diagnostics_spool.last_24h} in 24h)`,
|
|
3304
|
+
`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)`,
|
|
3282
3305
|
].join(" · ");
|
|
3283
3306
|
}
|
|
3284
3307
|
const rows = [
|
|
@@ -3298,20 +3321,20 @@ function renderHealthBox(report) {
|
|
|
3298
3321
|
["stream", streamStr],
|
|
3299
3322
|
["event ledger", ledgerStr],
|
|
3300
3323
|
[
|
|
3301
|
-
"
|
|
3302
|
-
report.
|
|
3324
|
+
"cache issues",
|
|
3325
|
+
report.heartbeat_cache_issues.count === 0
|
|
3303
3326
|
? "0"
|
|
3304
|
-
: `${report.
|
|
3327
|
+
: `${report.heartbeat_cache_issues.count} (${report.heartbeat_cache_issues.samples.join(", ")})`,
|
|
3305
3328
|
],
|
|
3306
3329
|
["councils", councilParts.join(", ")],
|
|
3307
|
-
["
|
|
3330
|
+
["findings", report.findings.length === 0 ? "(clean)" : `${report.findings.length} flagged`],
|
|
3308
3331
|
];
|
|
3309
3332
|
const localTime = formatLocalTime(new Date(report.generated_at));
|
|
3310
3333
|
const title = `Coord Health (${localTime})`;
|
|
3311
3334
|
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
|
|
3312
|
-
if (report.
|
|
3335
|
+
if (report.findings.length > 0) {
|
|
3313
3336
|
process.stdout.write("\n"); // lint-ok-emission: same chat-paste path
|
|
3314
|
-
for (const a of report.
|
|
3337
|
+
for (const a of report.findings) {
|
|
3315
3338
|
process.stdout.write(` ! ${a}\n`); // lint-ok-emission: same
|
|
3316
3339
|
}
|
|
3317
3340
|
}
|
|
@@ -3682,24 +3705,57 @@ function runPing(name, message, opts) {
|
|
|
3682
3705
|
}
|
|
3683
3706
|
const myOwner = resolveOwner();
|
|
3684
3707
|
if (!myOwner) {
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3708
|
+
const root = monorepoRoot();
|
|
3709
|
+
emit.error(root
|
|
3710
|
+
? sessionResolutionFailure(root, "not in an agent session; ppid walk found no pid-map entry")
|
|
3711
|
+
: {
|
|
3712
|
+
code: "no_pidmap_entry",
|
|
3713
|
+
message: "not in an agent session; ppid walk found no pid-map entry",
|
|
3714
|
+
});
|
|
3689
3715
|
process.exit(1);
|
|
3690
3716
|
}
|
|
3717
|
+
const coordRoot = monorepoRoot();
|
|
3691
3718
|
const peerOwner = resolveOwnerByName(name);
|
|
3692
|
-
|
|
3719
|
+
// A name with no live session is the common case, not an error: the agent it
|
|
3720
|
+
// refers to may have ended minutes ago and may come back under the same name.
|
|
3721
|
+
// Refuse only a name that no agent has ever held, which is a typo — queueing
|
|
3722
|
+
// that would swallow the message silently.
|
|
3723
|
+
if (!peerOwner && coordRoot && !isAddressableName(coordRoot, name)) {
|
|
3724
|
+
const suggestions = suggestNames(coordRoot, name);
|
|
3693
3725
|
emit.error({
|
|
3694
|
-
code: "
|
|
3695
|
-
message: `no
|
|
3726
|
+
code: "unknown_agent",
|
|
3727
|
+
message: `no agent has ever been named "${name}". ` +
|
|
3728
|
+
(suggestions.length > 0 ? `Did you mean ${suggestions.join(", ")}? ` : "") +
|
|
3729
|
+
`Run \`${resolveBinName()} agents list\` for live sessions.`,
|
|
3696
3730
|
});
|
|
3697
3731
|
process.exit(1);
|
|
3698
3732
|
}
|
|
3699
3733
|
const myHb = readCurrentCoordinationRow(myOwner);
|
|
3700
3734
|
const fromName = myHb?.name ?? "anonymous";
|
|
3701
3735
|
const body = `from agent-${fromName}: ${message.trim()}`;
|
|
3702
|
-
|
|
3736
|
+
// A live recipient gets the journal entry immediately, so a peer reading
|
|
3737
|
+
// their own journal mid-session sees it without waiting for a prompt. A
|
|
3738
|
+
// dormant recipient has no journal to write to yet; the drain writes it into
|
|
3739
|
+
// whichever session picks the message up.
|
|
3740
|
+
const doc = peerOwner ? appendEntry(peerOwner, "handoff", body) : null;
|
|
3741
|
+
let queued;
|
|
3742
|
+
try {
|
|
3743
|
+
queued = queueMailboxMessage({
|
|
3744
|
+
coordRoot: coordRoot ?? process.cwd(),
|
|
3745
|
+
toName: name,
|
|
3746
|
+
fromName,
|
|
3747
|
+
fromInstanceId: myOwner,
|
|
3748
|
+
body: message.trim(),
|
|
3749
|
+
journaled: Boolean(peerOwner),
|
|
3750
|
+
});
|
|
3751
|
+
}
|
|
3752
|
+
catch (error) {
|
|
3753
|
+
if (error instanceof MailboxCapacityError) {
|
|
3754
|
+
emit.error({ code: `mailbox_${error.reason_code}`, message: error.message });
|
|
3755
|
+
process.exit(1);
|
|
3756
|
+
}
|
|
3757
|
+
throw error;
|
|
3758
|
+
}
|
|
3703
3759
|
// Canonical delivery record: sender is the envelope owner, recipient rides
|
|
3704
3760
|
// in data, so read-only observers can render the communication without
|
|
3705
3761
|
// joining journal files.
|
|
@@ -3710,17 +3766,20 @@ function runPing(name, message, opts) {
|
|
|
3710
3766
|
observation: {
|
|
3711
3767
|
event_type: "coord.message_observed",
|
|
3712
3768
|
direction: "sent",
|
|
3713
|
-
subject: peerOwner
|
|
3769
|
+
subject: peerOwner ?? `name:${queued.message.to_name}`,
|
|
3714
3770
|
body: message.trim(),
|
|
3715
3771
|
},
|
|
3716
3772
|
});
|
|
3717
3773
|
const data = {
|
|
3718
|
-
peer:
|
|
3774
|
+
peer: queued.message.to_name,
|
|
3719
3775
|
peer_instance_id: peerOwner,
|
|
3776
|
+
delivery: peerOwner ? "live" : "queued",
|
|
3777
|
+
message_id: queued.message.message_id,
|
|
3778
|
+
pending: queued.pending,
|
|
3720
3779
|
from: fromName,
|
|
3721
3780
|
body,
|
|
3722
|
-
journal_path: doc
|
|
3723
|
-
journal_bytes: doc
|
|
3781
|
+
journal_path: doc?.path ?? null,
|
|
3782
|
+
journal_bytes: doc?.bytes ?? null,
|
|
3724
3783
|
};
|
|
3725
3784
|
if (opts.json) {
|
|
3726
3785
|
emit.config({ format: "json" });
|
|
@@ -3728,7 +3787,9 @@ function runPing(name, message, opts) {
|
|
|
3728
3787
|
return;
|
|
3729
3788
|
}
|
|
3730
3789
|
emit.data(data);
|
|
3731
|
-
emit.text(
|
|
3790
|
+
emit.text(peerOwner
|
|
3791
|
+
? `delivered to agent-${data.peer} (live; they see it on their next prompt): "${truncate(message.trim(), 80)}"\n`
|
|
3792
|
+
: `queued for agent-${data.peer} (no live session; delivered when a session of that name next starts): "${truncate(message.trim(), 80)}"\n`);
|
|
3732
3793
|
}
|
|
3733
3794
|
async function runWait(name, opts) {
|
|
3734
3795
|
const timeoutMs = parseDurationToMs(opts.timeout);
|
|
@@ -3827,12 +3888,10 @@ function emitWaitResult(data, opts) {
|
|
|
3827
3888
|
function runHeal(opts) {
|
|
3828
3889
|
if (opts.json)
|
|
3829
3890
|
emit.config({ format: "json" });
|
|
3830
|
-
const
|
|
3831
|
-
const
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
process.exit(1);
|
|
3835
|
-
}
|
|
3891
|
+
const requestedOwner = opts.owner?.trim() ?? "";
|
|
3892
|
+
const quarantineTransaction = opts.quarantineTransaction?.trim() ?? "";
|
|
3893
|
+
const approvalRecordId = opts.approvalRecordId?.trim() ?? "";
|
|
3894
|
+
const kind = opts.kind?.trim() || "cache";
|
|
3836
3895
|
if (kind !== "pidmap" && kind !== "cache") {
|
|
3837
3896
|
emit.error({
|
|
3838
3897
|
code: "bad_kind",
|
|
@@ -3840,6 +3899,30 @@ function runHeal(opts) {
|
|
|
3840
3899
|
});
|
|
3841
3900
|
process.exit(1);
|
|
3842
3901
|
}
|
|
3902
|
+
if (quarantineTransaction) {
|
|
3903
|
+
if (opts.kind || opts.pid) {
|
|
3904
|
+
emit.error({
|
|
3905
|
+
code: "conflicting_recovery_options",
|
|
3906
|
+
message: "--quarantine-transaction cannot be combined with --kind or --pid",
|
|
3907
|
+
});
|
|
3908
|
+
process.exit(1);
|
|
3909
|
+
}
|
|
3910
|
+
if (!opts.yes || !approvalRecordId) {
|
|
3911
|
+
emit.error({
|
|
3912
|
+
code: "transaction_quarantine_confirmation_required",
|
|
3913
|
+
message: "--quarantine-transaction requires --approval-record-id <id> and --yes; " +
|
|
3914
|
+
"the command abandons one uncommitted authority mutation while preserving its record",
|
|
3915
|
+
});
|
|
3916
|
+
process.exit(1);
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
else if (approvalRecordId || opts.yes) {
|
|
3920
|
+
emit.error({
|
|
3921
|
+
code: "transaction_quarantine_target_required",
|
|
3922
|
+
message: "--approval-record-id and --yes require --quarantine-transaction <id>",
|
|
3923
|
+
});
|
|
3924
|
+
process.exit(1);
|
|
3925
|
+
}
|
|
3843
3926
|
if (opts.adapter &&
|
|
3844
3927
|
opts.adapter !== "claude-code" &&
|
|
3845
3928
|
opts.adapter !== "cursor" &&
|
|
@@ -3858,7 +3941,42 @@ function runHeal(opts) {
|
|
|
3858
3941
|
});
|
|
3859
3942
|
process.exit(1);
|
|
3860
3943
|
}
|
|
3861
|
-
const
|
|
3944
|
+
const currentSessionRepair = kind === "cache" &&
|
|
3945
|
+
opts.owner === undefined &&
|
|
3946
|
+
opts.sessionId === undefined &&
|
|
3947
|
+
opts.adapter === undefined &&
|
|
3948
|
+
!quarantineTransaction;
|
|
3949
|
+
const ownerResolution = resolveOwnerWithSource();
|
|
3950
|
+
const bootstrapIdentity = currentSessionRepair ? commandSessionBootstrap() : null;
|
|
3951
|
+
const resolvedCurrentOwner = bootstrapIdentity &&
|
|
3952
|
+
(ownerResolution.source === "none" || ownerResolution.source === "active_singleton")
|
|
3953
|
+
? bootstrapIdentity.sessionId
|
|
3954
|
+
: ownerResolution.owner;
|
|
3955
|
+
const owner = requestedOwner || resolvedCurrentOwner || sessionIdentityFromEnv() || "";
|
|
3956
|
+
if (!owner) {
|
|
3957
|
+
emit.error({
|
|
3958
|
+
code: "session_identity_missing",
|
|
3959
|
+
message: `could not resolve the current session; run ${resolveBinName()} doctor, or pass ` +
|
|
3960
|
+
"--owner <instance-id> --session-id <native-session-id> --adapter <adapter>",
|
|
3961
|
+
});
|
|
3962
|
+
process.exit(1);
|
|
3963
|
+
}
|
|
3964
|
+
const currentRow = readLiveCoordinationRow(root, owner);
|
|
3965
|
+
const inferredAdapter = normalizeAdapter(opts.adapter?.trim() || currentRow?.platform || commandSessionBootstrap()?.adapter);
|
|
3966
|
+
const sessionId = opts.sessionId?.trim() ||
|
|
3967
|
+
(currentSessionRepair ? sessionIdentityFromEnv() : null) ||
|
|
3968
|
+
nativeSessionIdentity(currentRow, owner);
|
|
3969
|
+
if (kind === "cache") {
|
|
3970
|
+
const refusal = cacheHealAuthorityRefusal(root, owner, sessionId, inferredAdapter, currentRow);
|
|
3971
|
+
if (refusal) {
|
|
3972
|
+
emitHealFailure(refusal.reason, refusal.message);
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
const action = quarantineTransaction
|
|
3976
|
+
? "quarantine-authority-transaction"
|
|
3977
|
+
: kind === "pidmap"
|
|
3978
|
+
? "heal-pidmap"
|
|
3979
|
+
: "repair-coordination-cache";
|
|
3862
3980
|
// Refuse to materialize a V3 cache at a truncated owner id.
|
|
3863
3981
|
//
|
|
3864
3982
|
// Heartbeats are keyed by the whole instance_id, so healing at an
|
|
@@ -3897,24 +4015,54 @@ function runHeal(opts) {
|
|
|
3897
4015
|
// heal-pidmap <instance_id> [<pid>]
|
|
3898
4016
|
// repair-coordination-cache <instance_id> [<session_id>]
|
|
3899
4017
|
const helperArgs = [action, owner];
|
|
3900
|
-
if (
|
|
3901
|
-
helperArgs.push(
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
4018
|
+
if (quarantineTransaction) {
|
|
4019
|
+
helperArgs.push(quarantineTransaction, approvalRecordId, sessionId, `--adapter=${inferredAdapter}`);
|
|
4020
|
+
}
|
|
4021
|
+
else {
|
|
4022
|
+
if (kind === "pidmap" && opts.pid)
|
|
4023
|
+
helperArgs.push(opts.pid);
|
|
4024
|
+
if (kind === "cache")
|
|
4025
|
+
helperArgs.push(sessionId, `--adapter=${inferredAdapter}`);
|
|
4026
|
+
}
|
|
3906
4027
|
// Both recovery actions are handled by the bundled agent-coord binary.
|
|
3907
4028
|
const helper = agentCoordOrExit(root);
|
|
3908
|
-
|
|
4029
|
+
let proc = spawnSync(helper, helperArgs, {
|
|
3909
4030
|
encoding: "utf8",
|
|
3910
4031
|
...coordHelperOpts(root),
|
|
3911
4032
|
});
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
4033
|
+
let bootstrapState;
|
|
4034
|
+
if (proc.status !== 0 &&
|
|
4035
|
+
currentSessionRepair &&
|
|
4036
|
+
missingAuthorityForCurrentSessionBootstrap(root, owner, sessionId)) {
|
|
4037
|
+
const bootstrap = commandSessionBootstrap();
|
|
4038
|
+
if (!bootstrap ||
|
|
4039
|
+
bootstrap.sessionId !== sessionId ||
|
|
4040
|
+
bootstrap.sessionId !== owner ||
|
|
4041
|
+
bootstrap.adapter !== inferredAdapter) {
|
|
4042
|
+
emitHealFailure("native_identity_unverified", "the current adapter did not provide one matching native session id and adapter");
|
|
4043
|
+
}
|
|
4044
|
+
try {
|
|
4045
|
+
const bootstrapped = bootstrapLiveCoordinationAuthorityV3({
|
|
4046
|
+
coordRoot: root,
|
|
4047
|
+
owner,
|
|
4048
|
+
nativeSessionId: bootstrap.sessionId,
|
|
4049
|
+
adapter: bootstrap.adapter,
|
|
4050
|
+
});
|
|
4051
|
+
bootstrapState = bootstrapped.state;
|
|
4052
|
+
}
|
|
4053
|
+
catch (error) {
|
|
4054
|
+
const reason = error instanceof LiveCoordinationAuthorityV3Error
|
|
4055
|
+
? error.reason
|
|
4056
|
+
: "authority_bootstrap_failed";
|
|
4057
|
+
emitHealFailure(reason, "the current native session could not establish authority; no fallback cache was accepted");
|
|
4058
|
+
}
|
|
4059
|
+
proc = spawnSync(helper, helperArgs, {
|
|
4060
|
+
encoding: "utf8",
|
|
4061
|
+
...coordHelperOpts(root),
|
|
3916
4062
|
});
|
|
3917
|
-
|
|
4063
|
+
}
|
|
4064
|
+
if (proc.status !== 0) {
|
|
4065
|
+
emitHealFailure(healFailureReason(root, owner, sessionId, inferredAdapter), spawnFailureMessage(proc, `agent-coord ${action}`));
|
|
3918
4066
|
}
|
|
3919
4067
|
// Read the derived cache to surface post-action state.
|
|
3920
4068
|
let after = null;
|
|
@@ -3924,13 +4072,15 @@ function runHeal(opts) {
|
|
|
3924
4072
|
catch {
|
|
3925
4073
|
after = null;
|
|
3926
4074
|
}
|
|
3927
|
-
const outcome =
|
|
3928
|
-
?
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
:
|
|
4075
|
+
const outcome = quarantineTransaction
|
|
4076
|
+
? "transaction_quarantined"
|
|
4077
|
+
: kind === "pidmap"
|
|
4078
|
+
? proc.status === 0
|
|
4079
|
+
? "ok"
|
|
4080
|
+
: "failed"
|
|
4081
|
+
: after
|
|
4082
|
+
? "cache_present"
|
|
4083
|
+
: "cache_absent";
|
|
3934
4084
|
emit.data({
|
|
3935
4085
|
rows: [
|
|
3936
4086
|
{
|
|
@@ -3938,10 +4088,15 @@ function runHeal(opts) {
|
|
|
3938
4088
|
action,
|
|
3939
4089
|
outcome,
|
|
3940
4090
|
after,
|
|
4091
|
+
...(quarantineTransaction ? { recovery: JSON.parse(proc.stdout.trim()) } : {}),
|
|
3941
4092
|
},
|
|
3942
4093
|
],
|
|
3943
4094
|
meta: {
|
|
3944
4095
|
kind,
|
|
4096
|
+
automatic: currentSessionRepair && !quarantineTransaction,
|
|
4097
|
+
authority: "event-ledger-v3",
|
|
4098
|
+
adapter: kind === "cache" ? inferredAdapter : undefined,
|
|
4099
|
+
bootstrap: bootstrapState,
|
|
3945
4100
|
// The path actually spawned, not a guess at the layout: the helper is
|
|
3946
4101
|
// resolved from harnery's own package location, which differs between a
|
|
3947
4102
|
// submodule, an installed dependency, and a standalone checkout.
|
|
@@ -3949,11 +4104,16 @@ function runHeal(opts) {
|
|
|
3949
4104
|
},
|
|
3950
4105
|
});
|
|
3951
4106
|
if (!opts.json) {
|
|
3952
|
-
if (
|
|
4107
|
+
if (quarantineTransaction) {
|
|
4108
|
+
emit.text(`coordination recovered: ${quarantineTransaction} quarantined with approval ${approvalRecordId}; ` +
|
|
4109
|
+
`cache ${after ? "present" : "absent"} (${inferredAdapter})\n`);
|
|
4110
|
+
}
|
|
4111
|
+
else if (kind === "pidmap") {
|
|
3953
4112
|
emit.text(`agent-coord ${action} ok\n`);
|
|
3954
4113
|
}
|
|
3955
4114
|
else {
|
|
3956
|
-
emit.text(`
|
|
4115
|
+
emit.text(`coordination repaired: V3 authority live; ${currentSessionRepair ? "current-session " : ""}` +
|
|
4116
|
+
`cache ${after ? "present" : "absent"} (${inferredAdapter})\n`);
|
|
3957
4117
|
}
|
|
3958
4118
|
}
|
|
3959
4119
|
// Canonical health.* emission is owned by the cache writer, so it fires
|
|
@@ -3962,6 +4122,68 @@ function runHeal(opts) {
|
|
|
3962
4122
|
// event when an already-correct heal no-ops. (Previously emitted here
|
|
3963
4123
|
// unconditionally on every `harn agents heal`, which over-counted no-op heals.)
|
|
3964
4124
|
}
|
|
4125
|
+
function cacheHealAuthorityRefusal(root, owner, sessionId, adapter, currentRow) {
|
|
4126
|
+
if (currentRow && normalizeAdapter(currentRow.platform) !== adapter) {
|
|
4127
|
+
return {
|
|
4128
|
+
reason: "adapter_mismatch",
|
|
4129
|
+
message: `the live generation belongs to adapter ${normalizeAdapter(currentRow.platform)}, not ${adapter}`,
|
|
4130
|
+
};
|
|
4131
|
+
}
|
|
4132
|
+
let producer;
|
|
4133
|
+
try {
|
|
4134
|
+
producer = readHookProducerStateV3(root, adapter, sessionId);
|
|
4135
|
+
}
|
|
4136
|
+
catch {
|
|
4137
|
+
return {
|
|
4138
|
+
reason: "session_mismatch",
|
|
4139
|
+
message: "the native session producer state could not be read safely",
|
|
4140
|
+
};
|
|
4141
|
+
}
|
|
4142
|
+
if (producer?.terminal) {
|
|
4143
|
+
return {
|
|
4144
|
+
reason: "terminal_generation",
|
|
4145
|
+
message: "the matching generation is terminal and cannot be repaired or reopened by heal",
|
|
4146
|
+
};
|
|
4147
|
+
}
|
|
4148
|
+
if (producer && producer.instance_id !== liveInstanceIdV3(owner)) {
|
|
4149
|
+
return {
|
|
4150
|
+
reason: "owner_mismatch",
|
|
4151
|
+
message: "the native session is bound to a different instance owner",
|
|
4152
|
+
};
|
|
4153
|
+
}
|
|
4154
|
+
if (currentRow && (!producer || producer.generation_id !== currentRow.v3_generation_id)) {
|
|
4155
|
+
return {
|
|
4156
|
+
reason: "session_mismatch",
|
|
4157
|
+
message: "the native session does not bind to the requested live generation",
|
|
4158
|
+
};
|
|
4159
|
+
}
|
|
4160
|
+
return null;
|
|
4161
|
+
}
|
|
4162
|
+
function missingAuthorityForCurrentSessionBootstrap(root, owner, sessionId) {
|
|
4163
|
+
if (readLiveCoordinationRow(root, owner))
|
|
4164
|
+
return false;
|
|
4165
|
+
try {
|
|
4166
|
+
const nativeSessionHasProducer = ["claude-code", "codex", "cursor"].some((adapter) => readHookProducerStateV3(root, adapter, sessionId) !== undefined);
|
|
4167
|
+
if (nativeSessionHasProducer)
|
|
4168
|
+
return false;
|
|
4169
|
+
const instanceId = liveInstanceIdV3(owner);
|
|
4170
|
+
return !listHookProducerStateRecordsV3(root, { includeTerminal: true }).some(({ state }) => state.instance_id === instanceId);
|
|
4171
|
+
}
|
|
4172
|
+
catch {
|
|
4173
|
+
return false;
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4176
|
+
function healFailureReason(root, owner, sessionId, adapter) {
|
|
4177
|
+
const refusal = cacheHealAuthorityRefusal(root, owner, sessionId, adapter, readLiveCoordinationRow(root, owner));
|
|
4178
|
+
return refusal?.reason ?? "authority_missing";
|
|
4179
|
+
}
|
|
4180
|
+
function emitHealFailure(reason, message) {
|
|
4181
|
+
emit.error({
|
|
4182
|
+
code: "heal_failed",
|
|
4183
|
+
message: `coordination heal refused (reason=${reason}): ${message}`,
|
|
4184
|
+
});
|
|
4185
|
+
process.exit(1);
|
|
4186
|
+
}
|
|
3965
4187
|
/**
|
|
3966
4188
|
* Emit one V3 council audit transition keyed to the exact durable manifest.
|
|
3967
4189
|
* Falls through silently when no live session can attest the observation.
|