harnery 0.35.0 → 0.36.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 +124 -96
- package/dist/commands/agents.d.ts +23 -3
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +379 -198
- 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 +5 -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/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 +22 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +113 -0
- package/dist/commands/governor.js +14 -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 +347 -1
- 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/read.d.ts +1 -1
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +2 -2
- 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/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 +67 -7
- package/dist/commands/work.js +3 -3
- package/dist/commands/workflow.js +13 -13
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/cli.js +209 -39
- 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/render/prompt-context.d.ts +9 -3
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +24 -7
- 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 +94 -13
- 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 +5 -1
- 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 +21 -0
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +46 -1
- package/dist/core/config.d.ts +62 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +98 -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/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/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 +6 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/index.js +5 -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/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.js +3 -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 +4 -2
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +3 -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 +45 -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.js +1 -1
- 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 +25 -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 +55 -1
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +353 -24
- 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 +4 -2
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +13 -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 +212 -30
- 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/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/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/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 +683 -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 +82 -0
- package/dist/core/storage/logger.d.ts.map +1 -0
- package/dist/core/storage/logger.js +411 -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 +34 -0
- package/dist/core/storage/query.d.ts.map +1 -0
- package/dist/core/storage/query.js +295 -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/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +10 -14
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.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/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/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +5 -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 +29 -2
- package/schemas/config.schema.json +58 -0
- package/schemas/event-v3.schema.json +324 -112
- package/src/commander.ts +462 -95
- package/src/commands/agents.ts +517 -190
- package/src/commands/backup.ts +18 -14
- package/src/commands/browse-session.ts +12 -0
- package/src/commands/browse.ts +6 -7
- package/src/commands/conversations.ts +279 -0
- package/src/commands/deinit.ts +6 -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 +143 -0
- package/src/commands/governor.ts +13 -12
- package/src/commands/inbox.ts +61 -0
- package/src/commands/init.ts +78 -16
- package/src/commands/ledger-v3.ts +421 -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/read.ts +6 -2
- package/src/commands/semantic.ts +66 -1
- package/src/commands/storage.ts +310 -0
- package/src/commands/tunnel.ts +66 -52
- package/src/commands/web.ts +77 -7
- package/src/commands/work.ts +3 -3
- package/src/commands/workflow.ts +13 -13
- package/src/core/agents/cli.ts +259 -53
- 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/render/prompt-context.ts +27 -6
- package/src/core/agents/rules/stop-hook.ts +107 -16
- 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 +4 -1
- 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 +64 -1
- package/src/core/config.ts +126 -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/events/legacy-storage/canary.ts +177 -0
- package/src/core/events/legacy-storage/fence.ts +129 -0
- package/src/core/events/legacy-storage/index.ts +5 -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/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 +3 -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 +5 -2
- package/src/core/events/v3/live-route-observer.ts +80 -0
- package/src/core/events/v3/live-routing.ts +64 -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 +1 -1
- package/src/core/events/v3/producers/intake.ts +30 -2
- package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
- package/src/core/events/v3/producers/recorder.ts +571 -33
- 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 +12 -5
- package/src/core/hooks/adapter/runtime-telemetry.ts +408 -13
- package/src/core/hooks/cli.ts +226 -32
- package/src/core/hooks/effects/image-capture.ts +4 -1
- 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/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/buffer.ts +124 -0
- package/src/core/storage/builtins.ts +916 -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 +546 -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 +360 -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/work/state.ts +12 -21
- package/src/core/workflow/live-session-v3.ts +2 -4
- package/src/index.ts +2 -0
- package/src/lazy-commands.ts +294 -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/templates.ts +5 -0
- package/src/lib/local-file-url.ts +31 -0
- package/src/lib/web-performance.ts +335 -0
|
@@ -30,6 +30,8 @@ export interface StopHookRequest {
|
|
|
30
30
|
adapter?: string;
|
|
31
31
|
now_ms?: number;
|
|
32
32
|
turn_window?: { start_ms: number; end_ms: number };
|
|
33
|
+
stop_hook_active?: boolean;
|
|
34
|
+
status_box_present_strict?: boolean;
|
|
33
35
|
bypass?: boolean;
|
|
34
36
|
workflow_child?: boolean;
|
|
35
37
|
}
|
|
@@ -107,15 +109,24 @@ export function evaluateStopHookV3Events(
|
|
|
107
109
|
"generation_id" in event.scope &&
|
|
108
110
|
event.scope.generation_id === generationId,
|
|
109
111
|
);
|
|
112
|
+
const fallbackStartMs = Math.max(0, endMs - 5 * 60 * 1000);
|
|
113
|
+
const claudeContinuation = req.adapter === "claude-code" && req.stop_hook_active === true;
|
|
114
|
+
const resolvedStart = resolveTurnStart(ownerEvents, endMs, claudeContinuation);
|
|
115
|
+
const resolvedStartMs = eventTimeMs(resolvedStart);
|
|
110
116
|
const startMs =
|
|
111
117
|
req.turn_window?.start_ms ??
|
|
112
|
-
|
|
118
|
+
(Number.isFinite(resolvedStartMs) ? resolvedStartMs : fallbackStartMs);
|
|
113
119
|
const inTurn = ownerEvents.filter((event) => {
|
|
114
120
|
const time = eventTimeMs(event);
|
|
115
121
|
return Number.isFinite(time) && time >= startMs && time <= endMs;
|
|
116
122
|
});
|
|
117
123
|
|
|
118
|
-
const
|
|
124
|
+
const policyEvents =
|
|
125
|
+
claudeContinuation && resolvedStart
|
|
126
|
+
? originalTurnEvents(ownerEvents, resolvedStart, endMs)
|
|
127
|
+
: inTurn;
|
|
128
|
+
const usedTool = policyEvents.some((event) => event.event_type === "tool.requested");
|
|
129
|
+
const cycleAnchor = remediationCycleAnchor(resolvedStart, startMs);
|
|
119
130
|
const statusEvents = inTurn.filter(
|
|
120
131
|
(event) =>
|
|
121
132
|
event.event_type === "coord.status_observed" && event.payload.subject_instance_id === owner,
|
|
@@ -139,13 +150,22 @@ export function evaluateStopHookV3Events(
|
|
|
139
150
|
);
|
|
140
151
|
const latestTerminal = turnTerminals.at(-1);
|
|
141
152
|
const latestBox = observedBoolean(latestTerminal?.payload.ritual?.status_box_present_strict);
|
|
142
|
-
|
|
153
|
+
const strictBoxObservations = turnTerminals
|
|
154
|
+
.map((event) => observedBoolean(event.payload.ritual?.status_box_present_strict))
|
|
155
|
+
.filter((value): value is boolean => value !== undefined);
|
|
156
|
+
const currentStrictBox = claudeContinuation ? req.status_box_present_strict : undefined;
|
|
157
|
+
if (req.adapter !== "cursor" && latestBox === undefined && currentStrictBox === undefined) {
|
|
143
158
|
return evidenceUnavailable(
|
|
144
159
|
"turn.completed has no observed V3 assistant-text status-box result; Stop remains fail-open",
|
|
145
160
|
);
|
|
146
161
|
}
|
|
147
162
|
|
|
148
|
-
const ackPresent =
|
|
163
|
+
const ackPresent =
|
|
164
|
+
req.adapter === "cursor"
|
|
165
|
+
? requiredStatusChecked
|
|
166
|
+
: claudeContinuation
|
|
167
|
+
? strictBoxObservations.includes(true) || currentStrictBox === true
|
|
168
|
+
: latestBox === true;
|
|
149
169
|
const ackBlock =
|
|
150
170
|
req.adapter === "cursor"
|
|
151
171
|
? () => rule13Block(coordRoot, req.session_id)
|
|
@@ -154,7 +174,7 @@ export function evaluateStopHookV3Events(
|
|
|
154
174
|
// Pure prose turns keep the human-visible acknowledgement but do not require
|
|
155
175
|
// task or final-status mutations. This preserves the pre-V3 policy exactly.
|
|
156
176
|
if (!usedTool) {
|
|
157
|
-
if (!ackPresent) return ackBlock();
|
|
177
|
+
if (!ackPresent) return withCycleAnchor(ackBlock(), cycleAnchor);
|
|
158
178
|
return {
|
|
159
179
|
allow: true,
|
|
160
180
|
exit_code: 0,
|
|
@@ -163,9 +183,14 @@ export function evaluateStopHookV3Events(
|
|
|
163
183
|
};
|
|
164
184
|
}
|
|
165
185
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
// Collect EVERY missing signal before returning. Reporting them one at a
|
|
187
|
+
// time made each additional missing signal cost a whole continuation, and
|
|
188
|
+
// every continuation forks a fresh hook process: on a busy multi-agent host
|
|
189
|
+
// the ritual's own enforcement became part of the hook load it polices.
|
|
190
|
+
const pending: VerdictResult[] = [];
|
|
191
|
+
if (!requiredStatusChecked) pending.push(rule13Block(coordRoot, req.session_id));
|
|
192
|
+
if (!ackPresent) pending.push(ackBlock());
|
|
193
|
+
if (!taskSet) pending.push(rule33Block(coordRoot, req.session_id));
|
|
169
194
|
|
|
170
195
|
// Claude Code can prove session-name presentation from assistant-only text.
|
|
171
196
|
// Cursor cannot expose that text and Codex returned observe-only above.
|
|
@@ -178,10 +203,13 @@ export function evaluateStopHookV3Events(
|
|
|
178
203
|
!naming.some(({ present }) => present) &&
|
|
179
204
|
!sessionNameSeenStamped(coordRoot, req.instance_id)
|
|
180
205
|
) {
|
|
181
|
-
|
|
206
|
+
pending.push(sessionNameBlock(coordRoot, req.instance_id));
|
|
182
207
|
}
|
|
183
208
|
}
|
|
184
209
|
|
|
210
|
+
const blocked = mergeStopBlocks(pending);
|
|
211
|
+
if (blocked) return withCycleAnchor(blocked, cycleAnchor);
|
|
212
|
+
|
|
185
213
|
return { allow: true, exit_code: 0, rule: "stop-hook.pass" };
|
|
186
214
|
}
|
|
187
215
|
|
|
@@ -213,29 +241,65 @@ function unconditionalVerdict(req: StopHookRequest): VerdictResult | undefined {
|
|
|
213
241
|
return undefined;
|
|
214
242
|
}
|
|
215
243
|
|
|
216
|
-
function
|
|
244
|
+
function resolveTurnStart(
|
|
217
245
|
ownerEvents: readonly EventV3[],
|
|
218
246
|
nowMs: number,
|
|
219
|
-
|
|
220
|
-
):
|
|
247
|
+
claudeContinuation: boolean,
|
|
248
|
+
): Extract<EventV3, { event_type: "turn.started" }> | undefined {
|
|
221
249
|
const turns = ownerEvents.filter(
|
|
222
250
|
(event): event is Extract<EventV3, { event_type: "turn.started" }> =>
|
|
223
251
|
event.event_type === "turn.started" && eventTimeMs(event) <= nowMs,
|
|
224
252
|
);
|
|
225
|
-
if (turns.length === 0) return
|
|
253
|
+
if (turns.length === 0) return undefined;
|
|
226
254
|
|
|
227
255
|
let index = turns.length - 1;
|
|
228
256
|
let hops = 0;
|
|
229
257
|
while (index > 0 && hops < MAX_REMEDIATION_WALK_BACK) {
|
|
230
258
|
const turn = turns[index];
|
|
231
|
-
|
|
259
|
+
const continuesCycle = claudeContinuation
|
|
260
|
+
? turn?.provenance.source_event === "claude-code.recovery" &&
|
|
261
|
+
turn.provenance.attestation === "derived"
|
|
262
|
+
: turn?.payload.stop_remediation === true;
|
|
263
|
+
if (!continuesCycle) break;
|
|
232
264
|
index -= 1;
|
|
233
265
|
hops += 1;
|
|
234
266
|
}
|
|
235
|
-
return
|
|
267
|
+
return turns[index];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function originalTurnEvents(
|
|
271
|
+
ownerEvents: readonly EventV3[],
|
|
272
|
+
turnStart: Extract<EventV3, { event_type: "turn.started" }> | undefined,
|
|
273
|
+
endMs: number,
|
|
274
|
+
): EventV3[] {
|
|
275
|
+
if (!turnStart) return [];
|
|
276
|
+
const startMs = eventTimeMs(turnStart);
|
|
277
|
+
const terminal = ownerEvents.find(
|
|
278
|
+
(event) => event.event_type === "turn.completed" && eventTimeMs(event) >= startMs,
|
|
279
|
+
);
|
|
280
|
+
const policyEndMs = terminal ? eventTimeMs(terminal) : endMs;
|
|
281
|
+
return ownerEvents.filter((event) => {
|
|
282
|
+
const time = eventTimeMs(event);
|
|
283
|
+
return time >= startMs && time <= policyEndMs;
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function remediationCycleAnchor(
|
|
288
|
+
turnStart: Extract<EventV3, { event_type: "turn.started" }> | undefined,
|
|
289
|
+
startMs: number,
|
|
290
|
+
): string {
|
|
291
|
+
if (turnStart && "turn_id" in turnStart.scope && turnStart.scope.turn_id) {
|
|
292
|
+
return turnStart.scope.turn_id;
|
|
293
|
+
}
|
|
294
|
+
return new Date(startMs).toISOString();
|
|
236
295
|
}
|
|
237
296
|
|
|
238
|
-
function
|
|
297
|
+
function withCycleAnchor(verdict: VerdictResult, anchor: string): VerdictResult {
|
|
298
|
+
return { ...verdict, remediation_cycle_anchor: anchor };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function eventTimeMs(event: EventV3 | undefined): number {
|
|
302
|
+
if (!event) return Number.NaN;
|
|
239
303
|
return Date.parse(event.time.observed_at);
|
|
240
304
|
}
|
|
241
305
|
|
|
@@ -284,6 +348,33 @@ function sessionIdSuffix(sessionId?: string): string {
|
|
|
284
348
|
return sessionId ? ` --session-id ${sessionId}` : "";
|
|
285
349
|
}
|
|
286
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Fold every failing end-of-turn signal into ONE verdict.
|
|
353
|
+
*
|
|
354
|
+
* The verdict keeps the first failure's rule id, so the `blocked_rule`
|
|
355
|
+
* telemetry and the adapter's `rule=` stderr contract are unchanged; the
|
|
356
|
+
* reason enumerates the rest so a single continuation can repair all of them.
|
|
357
|
+
* Cursor maps the acknowledgement onto rule 1/3, so identical rules dedupe.
|
|
358
|
+
*/
|
|
359
|
+
function mergeStopBlocks(blocks: VerdictResult[]): VerdictResult | undefined {
|
|
360
|
+
let primary: VerdictResult | undefined;
|
|
361
|
+
const seen = new Set<string>();
|
|
362
|
+
const reasons: string[] = [];
|
|
363
|
+
for (const block of blocks) {
|
|
364
|
+
if (seen.has(block.rule)) continue;
|
|
365
|
+
seen.add(block.rule);
|
|
366
|
+
if (!primary) primary = block;
|
|
367
|
+
if (block.reason) reasons.push(block.reason);
|
|
368
|
+
}
|
|
369
|
+
if (!primary) return undefined;
|
|
370
|
+
if (reasons.length < 2) return primary;
|
|
371
|
+
const numbered = reasons.map((reason, index) => `${index + 1}. ${reason}`).join("\n");
|
|
372
|
+
return {
|
|
373
|
+
...primary,
|
|
374
|
+
reason: `End-of-turn ritual: ${reasons.length} signals are missing from this turn. Repair ALL of them in this continuation, then stop.\n${numbered}`,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
287
378
|
function rule13Block(coordRoot?: string, sessionId?: string): VerdictResult {
|
|
288
379
|
const missingEvidence = agentsRequireGitFinalization(coordRoot)
|
|
289
380
|
? "no end_turn_checked coord.status_observed event found in this turn"
|
|
@@ -102,6 +102,10 @@ function recordCommandObservation(type: SessionEventType, fields: Record<string,
|
|
|
102
102
|
monotonic_ns: process.hrtime.bigint().toString(),
|
|
103
103
|
});
|
|
104
104
|
if (result.state === "generation_unavailable") {
|
|
105
|
+
const expectedLifecycleReopenGap =
|
|
106
|
+
result.reason === "turn_not_started" &&
|
|
107
|
+
hook.session_start_derivation === "approved_lifecycle_reopen";
|
|
108
|
+
if (expectedLifecycleReopenGap) return;
|
|
105
109
|
writeProducerDiagnosticV3(coordRoot, "command_emit_unjoinable", {
|
|
106
110
|
type,
|
|
107
111
|
instance_id: instanceId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import type { ApprovedSessionEndReasonV3 } from "../events/v3/producers/recorder.ts";
|
|
4
|
-
import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../events/v3/
|
|
4
|
+
import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../events/v3/reader.ts";
|
|
5
5
|
|
|
6
6
|
export const SESSION_FINALIZATION_REQUEST_FORMAT_V3 =
|
|
7
7
|
"harnery-v3-session-finalization-request" as const;
|
|
@@ -690,7 +690,10 @@ function ensureRequest(
|
|
|
690
690
|
};
|
|
691
691
|
const observation = buildObservationEvent(coordRoot, record, request, input);
|
|
692
692
|
request.observation_event_id = observation.event_id as `evt_${string}`;
|
|
693
|
-
writeEventV3(coordRoot, observation
|
|
693
|
+
const durability = writeEventV3(coordRoot, observation, {
|
|
694
|
+
expectedGenesisId: input.route.genesis_id,
|
|
695
|
+
});
|
|
696
|
+
if (durability.state === "epoch_replaced") return null;
|
|
694
697
|
writeRequest(coordRoot, request, true);
|
|
695
698
|
return request;
|
|
696
699
|
}
|
|
@@ -20,6 +20,11 @@ import { readLiveCoordinationRow } from "./live-coordination-view.ts";
|
|
|
20
20
|
export function resolveShortName(coordRoot: string, instanceId: string | null): string {
|
|
21
21
|
if (!instanceId) return "agent-unknown";
|
|
22
22
|
const row = readLiveCoordinationRow(coordRoot, instanceId);
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
return agentDisplayName(instanceId, row?.name);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Build a collision-resistant agent label even when identity onboarding has
|
|
27
|
+
* not produced a usable display name yet. */
|
|
28
|
+
export function agentDisplayName(instanceId: string, name?: string | null): string {
|
|
29
|
+
return `agent-${name?.trim() || instanceId.slice(0, 8) || "unknown"}`;
|
|
25
30
|
}
|
|
@@ -108,6 +108,33 @@ export function setIdentityCache(
|
|
|
108
108
|
return heartbeat;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/** Restore the pool-assigned display name on a generation that was
|
|
112
|
+
* materialized before the adapter's normal SessionStart naming path ran.
|
|
113
|
+
* The durable assignment lives in `.name-history`; this only repairs the
|
|
114
|
+
* disposable generation cache and deliberately leaves durable persona state
|
|
115
|
+
* (`agent_id`) untouched. */
|
|
116
|
+
export function setAssignedNameCache(
|
|
117
|
+
coordRoot: string,
|
|
118
|
+
instanceId: string,
|
|
119
|
+
name: string,
|
|
120
|
+
kind: "session" | "subagent" | "transient" = "session",
|
|
121
|
+
): Heartbeat | null {
|
|
122
|
+
return mutate(coordRoot, instanceId, (heartbeat) => {
|
|
123
|
+
const suggestedSessionName = heartbeat.suggested_session_name?.replace(
|
|
124
|
+
/^(\[DONE\]\s+)?Agent unknown( - .+)$/,
|
|
125
|
+
`$1Agent ${name}$2`,
|
|
126
|
+
);
|
|
127
|
+
return {
|
|
128
|
+
...heartbeat,
|
|
129
|
+
name,
|
|
130
|
+
kind: heartbeat.kind ?? kind,
|
|
131
|
+
...(suggestedSessionName && suggestedSessionName !== heartbeat.suggested_session_name
|
|
132
|
+
? { suggested_session_name: suggestedSessionName }
|
|
133
|
+
: {}),
|
|
134
|
+
};
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
111
138
|
/**
|
|
112
139
|
* Build the copy-pasteable session name from the coord identity + the agent's
|
|
113
140
|
* description parts. Pure (no coord-state reads) so it's unit-testable; collapses
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
mkdirSync,
|
|
4
|
-
readdirSync,
|
|
5
|
-
readFileSync,
|
|
6
|
-
renameSync,
|
|
7
|
-
writeFileSync,
|
|
8
|
-
} from "node:fs";
|
|
9
|
-
import { dirname, join } from "node:path";
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
10
3
|
import type { Adapter } from "../../adapter.ts";
|
|
11
4
|
import {
|
|
12
5
|
type CoordinationGenerationViewV3,
|
|
@@ -17,8 +10,8 @@ import {
|
|
|
17
10
|
import {
|
|
18
11
|
liveInstanceIdV3,
|
|
19
12
|
nativeInstanceIdV3,
|
|
20
|
-
|
|
21
|
-
} from "../../events/v3/live-
|
|
13
|
+
observeLiveEventLedgerRouteV3,
|
|
14
|
+
} from "../../events/v3/live-route-observer.ts";
|
|
22
15
|
import { type Heartbeat, readHeartbeat } from "./heartbeat-reader.ts";
|
|
23
16
|
import { resolveName } from "./names.ts";
|
|
24
17
|
|
|
@@ -36,7 +29,7 @@ export interface V3HeartbeatMaterialization extends Heartbeat {
|
|
|
36
29
|
|
|
37
30
|
/** Read the live coordination rows through the hard-cut ledger route. */
|
|
38
31
|
export function readLiveCoordinationRows(coordRoot: string): V3HeartbeatMaterialization[] {
|
|
39
|
-
const route =
|
|
32
|
+
const route = observeLiveEventLedgerRouteV3(coordRoot);
|
|
40
33
|
if (route.state === "blocked") return [];
|
|
41
34
|
let view: CoordinationViewV3;
|
|
42
35
|
try {
|
|
@@ -69,7 +62,7 @@ export function readLiveCoordinationRow(
|
|
|
69
62
|
coordRoot: string,
|
|
70
63
|
nativeInstanceId: string,
|
|
71
64
|
): V3HeartbeatMaterialization | null {
|
|
72
|
-
const route =
|
|
65
|
+
const route = observeLiveEventLedgerRouteV3(coordRoot);
|
|
73
66
|
if (route.state === "blocked") return null;
|
|
74
67
|
try {
|
|
75
68
|
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
@@ -84,7 +77,7 @@ export function readLiveCoordinationRow(
|
|
|
84
77
|
return projectHeartbeatV3(
|
|
85
78
|
coordRoot,
|
|
86
79
|
generation,
|
|
87
|
-
|
|
80
|
+
isCurrentV3HeartbeatCache(cache, generation) ? cache : undefined,
|
|
88
81
|
nativeInstanceId,
|
|
89
82
|
parent,
|
|
90
83
|
);
|
|
@@ -102,89 +95,18 @@ export function liveCoordinationAdapterV3(
|
|
|
102
95
|
coordRoot: string,
|
|
103
96
|
nativeInstanceId: string,
|
|
104
97
|
): Adapter | null {
|
|
105
|
-
const route =
|
|
98
|
+
const route = observeLiveEventLedgerRouteV3(coordRoot);
|
|
106
99
|
if (route.state === "blocked") throw new Error(`event_v3_coordination_view:${route.reason}`);
|
|
107
100
|
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
108
101
|
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
109
102
|
if (!generation?.authority_eligible) return null;
|
|
110
|
-
const adapter =
|
|
111
|
-
if (!
|
|
103
|
+
const adapter = observedAdapterV3(generation);
|
|
104
|
+
if (!isAdapterV3(adapter)) {
|
|
112
105
|
throw new Error("event_v3_coordination_view:adapter_not_observed");
|
|
113
106
|
}
|
|
114
107
|
return adapter;
|
|
115
108
|
}
|
|
116
109
|
|
|
117
|
-
/**
|
|
118
|
-
* Ensure the current V3 generation has a mutation target. The resulting file
|
|
119
|
-
* is explicitly generation-bound and disposable: V3 remains the source of
|
|
120
|
-
* truth, while the cache gives the crash-safe authority outbox an atomic local
|
|
121
|
-
* state to reconcile.
|
|
122
|
-
*/
|
|
123
|
-
export function ensureLiveCoordinationHeartbeat(
|
|
124
|
-
coordRoot: string,
|
|
125
|
-
nativeInstanceId: string,
|
|
126
|
-
nativeSessionId: string,
|
|
127
|
-
_adapter: Adapter,
|
|
128
|
-
model?: string,
|
|
129
|
-
): Heartbeat | null {
|
|
130
|
-
const route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
131
|
-
if (route.state === "blocked") throw new Error(`event_v3_coordination_view:${route.reason}`);
|
|
132
|
-
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
133
|
-
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
134
|
-
if (!generation?.authority_eligible) return null;
|
|
135
|
-
const generationAdapter = observedAdapter(generation);
|
|
136
|
-
if (!isAdapter(generationAdapter)) {
|
|
137
|
-
throw new Error("event_v3_coordination_view:adapter_not_observed");
|
|
138
|
-
}
|
|
139
|
-
const current = readHeartbeat(coordRoot, nativeInstanceId);
|
|
140
|
-
if (isCurrentCache(current, generation) && current.platform === generationAdapter) return current;
|
|
141
|
-
|
|
142
|
-
const resolved = resolveName(coordRoot, nativeInstanceId, nativeSessionId);
|
|
143
|
-
const projected = projectHeartbeatV3(coordRoot, generation, undefined, nativeInstanceId);
|
|
144
|
-
// A generation reopen (resume, mid-flight onboarding) discards the stale
|
|
145
|
-
// cache, but the adapter tab it names is unchanged: same native session,
|
|
146
|
-
// same agent identity. Rebuilding without the naming evidence re-mints a
|
|
147
|
-
// fresh suggested name on the next set-task, so a multi-day session
|
|
148
|
-
// accumulates titles it is asked to display over and over. Carry the
|
|
149
|
-
// naming evidence across generations; everything else re-projects from V3.
|
|
150
|
-
// Same native session id means the same adapter tab; drop the carry only
|
|
151
|
-
// when the durable identity observably changed (a reassumed name would make
|
|
152
|
-
// the old "Agent <name> - …" block wrong for the new owner).
|
|
153
|
-
const identityUnchanged = !resolved?.name || !current?.name || resolved.name === current.name;
|
|
154
|
-
const carriedNaming =
|
|
155
|
-
current && current.session_id === nativeSessionId && identityUnchanged
|
|
156
|
-
? {
|
|
157
|
-
...(current.suggested_session_name
|
|
158
|
-
? { suggested_session_name: current.suggested_session_name }
|
|
159
|
-
: {}),
|
|
160
|
-
...(current.session_name_seen_for
|
|
161
|
-
? { session_name_seen_for: current.session_name_seen_for }
|
|
162
|
-
: {}),
|
|
163
|
-
...(current.session_name_seen_at
|
|
164
|
-
? { session_name_seen_at: current.session_name_seen_at }
|
|
165
|
-
: {}),
|
|
166
|
-
}
|
|
167
|
-
: {};
|
|
168
|
-
const materialized: V3HeartbeatMaterialization = {
|
|
169
|
-
...projected,
|
|
170
|
-
...carriedNaming,
|
|
171
|
-
schema_version: 2,
|
|
172
|
-
instance_id: nativeInstanceId,
|
|
173
|
-
session_id: nativeSessionId,
|
|
174
|
-
name: resolved?.name ?? "",
|
|
175
|
-
kind: resolved?.kind ?? projected.kind,
|
|
176
|
-
agent_id: resolved?.agent_id ?? (resolved?.kind === "subagent" ? nativeInstanceId : ""),
|
|
177
|
-
model: projected.model ?? model ?? "",
|
|
178
|
-
platform: generationAdapter,
|
|
179
|
-
v3_instance_id: generation.instance_id as `inst_${string}`,
|
|
180
|
-
v3_generation_id: generation.generation_id as `gen_${string}`,
|
|
181
|
-
v3_projection_event_id: generation.last_event_id,
|
|
182
|
-
v3_task_state: generation.task_state === "set" ? "set" : "cleared",
|
|
183
|
-
};
|
|
184
|
-
writeHeartbeatCache(coordRoot, nativeInstanceId, materialized);
|
|
185
|
-
return materialized;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
110
|
function readCacheRows(coordRoot: string): Heartbeat[] {
|
|
189
111
|
const dir = join(coordRoot, ".harnery", "active");
|
|
190
112
|
if (!existsSync(dir)) return [];
|
|
@@ -210,10 +132,10 @@ function matchingCache(
|
|
|
210
132
|
caches: Heartbeat[],
|
|
211
133
|
generation: CoordinationGenerationViewV3,
|
|
212
134
|
): Heartbeat | undefined {
|
|
213
|
-
return caches.find((cache) =>
|
|
135
|
+
return caches.find((cache) => isCurrentV3HeartbeatCache(cache, generation));
|
|
214
136
|
}
|
|
215
137
|
|
|
216
|
-
function
|
|
138
|
+
export function isCurrentV3HeartbeatCache(
|
|
217
139
|
cache: Heartbeat | null | undefined,
|
|
218
140
|
generation: CoordinationGenerationViewV3,
|
|
219
141
|
): cache is Heartbeat {
|
|
@@ -224,14 +146,14 @@ function isCurrentCache(
|
|
|
224
146
|
);
|
|
225
147
|
}
|
|
226
148
|
|
|
227
|
-
function projectHeartbeatV3(
|
|
149
|
+
export function projectHeartbeatV3(
|
|
228
150
|
coordRoot: string,
|
|
229
151
|
generation: CoordinationGenerationViewV3,
|
|
230
152
|
cache: Heartbeat | undefined,
|
|
231
153
|
nativeInstanceId: string | undefined,
|
|
232
154
|
parent?: CoordinationGenerationViewV3,
|
|
233
155
|
): V3HeartbeatMaterialization {
|
|
234
|
-
const adapter =
|
|
156
|
+
const adapter = observedAdapterV3(generation) ?? cache?.platform ?? "unknown";
|
|
235
157
|
const model = observedModel(generation) ?? cache?.model ?? "";
|
|
236
158
|
const instanceId =
|
|
237
159
|
nativeInstanceId ?? cache?.instance_id ?? nativeInstanceIdV3(generation.instance_id);
|
|
@@ -285,12 +207,12 @@ function projectHeartbeatV3(
|
|
|
285
207
|
};
|
|
286
208
|
}
|
|
287
209
|
|
|
288
|
-
function
|
|
210
|
+
export function observedAdapterV3(generation: CoordinationGenerationViewV3): string | undefined {
|
|
289
211
|
const observation = generation.runtime_attestation.adapter;
|
|
290
212
|
return observation.state === "observed" ? observation.value.id : undefined;
|
|
291
213
|
}
|
|
292
214
|
|
|
293
|
-
function
|
|
215
|
+
export function isAdapterV3(value: string | undefined): value is Adapter {
|
|
294
216
|
return value === "claude-code" || value === "cursor" || value === "codex";
|
|
295
217
|
}
|
|
296
218
|
|
|
@@ -302,14 +224,3 @@ function observedModel(generation: CoordinationGenerationViewV3): string | undef
|
|
|
302
224
|
function isLifecycleState(value: string | undefined): value is "active" | "blocked" | "done" {
|
|
303
225
|
return value === "active" || value === "blocked" || value === "done";
|
|
304
226
|
}
|
|
305
|
-
|
|
306
|
-
function writeHeartbeatCache(coordRoot: string, instanceId: string, heartbeat: Heartbeat): void {
|
|
307
|
-
if (!/^[a-zA-Z0-9._-]{1,128}$/.test(instanceId)) {
|
|
308
|
-
throw new Error("instance_id is unsafe for heartbeat materialization");
|
|
309
|
-
}
|
|
310
|
-
const path = join(coordRoot, ".harnery", "active", `${instanceId}.json`);
|
|
311
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
312
|
-
const temporary = `${path}.tmp.${process.pid}`;
|
|
313
|
-
writeFileSync(temporary, JSON.stringify(heartbeat, null, 2), "utf8");
|
|
314
|
-
renameSync(temporary, path);
|
|
315
|
-
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import type { Adapter } from "../../adapter.ts";
|
|
4
|
+
import {
|
|
5
|
+
readCoordinationViewV3,
|
|
6
|
+
requireAuthoritySafeCoordinationViewV3,
|
|
7
|
+
} from "../../events/v3/coordination-view.ts";
|
|
8
|
+
import { liveInstanceIdV3, resolveLiveEventLedgerRouteV3 } from "../../events/v3/live-routing.ts";
|
|
9
|
+
import { type Heartbeat, readHeartbeat } from "./heartbeat-reader.ts";
|
|
10
|
+
import {
|
|
11
|
+
isAdapterV3,
|
|
12
|
+
isCurrentV3HeartbeatCache,
|
|
13
|
+
observedAdapterV3,
|
|
14
|
+
projectHeartbeatV3,
|
|
15
|
+
type V3HeartbeatMaterialization,
|
|
16
|
+
} from "./live-coordination-view.ts";
|
|
17
|
+
import { resolveName } from "./names.ts";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Ensure the current V3 generation has a mutation target. The resulting file
|
|
21
|
+
* is explicitly generation-bound and disposable: V3 remains the source of
|
|
22
|
+
* truth, while the cache gives the crash-safe authority outbox an atomic local
|
|
23
|
+
* state to reconcile.
|
|
24
|
+
*/
|
|
25
|
+
export function ensureLiveCoordinationHeartbeat(
|
|
26
|
+
coordRoot: string,
|
|
27
|
+
nativeInstanceId: string,
|
|
28
|
+
nativeSessionId: string,
|
|
29
|
+
_adapter: Adapter,
|
|
30
|
+
model?: string,
|
|
31
|
+
): Heartbeat | null {
|
|
32
|
+
return materializeLiveCoordinationHeartbeat(
|
|
33
|
+
coordRoot,
|
|
34
|
+
nativeInstanceId,
|
|
35
|
+
nativeSessionId,
|
|
36
|
+
_adapter,
|
|
37
|
+
model,
|
|
38
|
+
false,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Rebuild a disposable cache from V3 even when its generation markers look current. */
|
|
43
|
+
export function repairLiveCoordinationHeartbeat(
|
|
44
|
+
coordRoot: string,
|
|
45
|
+
nativeInstanceId: string,
|
|
46
|
+
nativeSessionId: string,
|
|
47
|
+
adapter: Adapter,
|
|
48
|
+
model?: string,
|
|
49
|
+
): Heartbeat | null {
|
|
50
|
+
return materializeLiveCoordinationHeartbeat(
|
|
51
|
+
coordRoot,
|
|
52
|
+
nativeInstanceId,
|
|
53
|
+
nativeSessionId,
|
|
54
|
+
adapter,
|
|
55
|
+
model,
|
|
56
|
+
true,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function materializeLiveCoordinationHeartbeat(
|
|
61
|
+
coordRoot: string,
|
|
62
|
+
nativeInstanceId: string,
|
|
63
|
+
nativeSessionId: string,
|
|
64
|
+
_adapter: Adapter,
|
|
65
|
+
model: string | undefined,
|
|
66
|
+
force: boolean,
|
|
67
|
+
): Heartbeat | null {
|
|
68
|
+
const route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
69
|
+
if (route.state === "blocked") throw new Error(`event_v3_coordination_view:${route.reason}`);
|
|
70
|
+
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
71
|
+
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
72
|
+
if (!generation?.authority_eligible) return null;
|
|
73
|
+
const generationAdapter = observedAdapterV3(generation);
|
|
74
|
+
if (!isAdapterV3(generationAdapter)) {
|
|
75
|
+
throw new Error("event_v3_coordination_view:adapter_not_observed");
|
|
76
|
+
}
|
|
77
|
+
const current = readHeartbeat(coordRoot, nativeInstanceId);
|
|
78
|
+
if (
|
|
79
|
+
!force &&
|
|
80
|
+
isCurrentV3HeartbeatCache(current, generation) &&
|
|
81
|
+
current.platform === generationAdapter
|
|
82
|
+
) {
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const resolved = resolveName(coordRoot, nativeInstanceId, nativeSessionId);
|
|
87
|
+
const projected = projectHeartbeatV3(coordRoot, generation, undefined, nativeInstanceId);
|
|
88
|
+
// A generation reopen (resume, mid-flight onboarding) discards the stale
|
|
89
|
+
// cache, but the adapter tab it names is unchanged: same native session,
|
|
90
|
+
// same agent identity. Rebuilding without the naming evidence re-mints a
|
|
91
|
+
// fresh suggested name on the next set-task, so a multi-day session
|
|
92
|
+
// accumulates titles it is asked to display over and over. Carry the
|
|
93
|
+
// naming evidence across generations; everything else re-projects from V3.
|
|
94
|
+
// Same native session id means the same adapter tab; drop the carry only
|
|
95
|
+
// when the durable identity observably changed (a reassumed name would make
|
|
96
|
+
// the old "Agent <name> - …" block wrong for the new owner).
|
|
97
|
+
const identityUnchanged = !resolved?.name || !current?.name || resolved.name === current.name;
|
|
98
|
+
const carriedNaming =
|
|
99
|
+
current && current.session_id === nativeSessionId && identityUnchanged
|
|
100
|
+
? {
|
|
101
|
+
...(current.suggested_session_name
|
|
102
|
+
? { suggested_session_name: current.suggested_session_name }
|
|
103
|
+
: {}),
|
|
104
|
+
...(current.session_name_seen_for
|
|
105
|
+
? { session_name_seen_for: current.session_name_seen_for }
|
|
106
|
+
: {}),
|
|
107
|
+
...(current.session_name_seen_at
|
|
108
|
+
? { session_name_seen_at: current.session_name_seen_at }
|
|
109
|
+
: {}),
|
|
110
|
+
}
|
|
111
|
+
: {};
|
|
112
|
+
const materialized: V3HeartbeatMaterialization = {
|
|
113
|
+
...projected,
|
|
114
|
+
...carriedNaming,
|
|
115
|
+
schema_version: 2,
|
|
116
|
+
instance_id: nativeInstanceId,
|
|
117
|
+
session_id: nativeSessionId,
|
|
118
|
+
name: resolved?.name ?? "",
|
|
119
|
+
kind: resolved?.kind ?? projected.kind,
|
|
120
|
+
agent_id: resolved?.agent_id ?? (resolved?.kind === "subagent" ? nativeInstanceId : ""),
|
|
121
|
+
model: projected.model ?? model ?? "",
|
|
122
|
+
platform: generationAdapter,
|
|
123
|
+
v3_instance_id: generation.instance_id as `inst_${string}`,
|
|
124
|
+
v3_generation_id: generation.generation_id as `gen_${string}`,
|
|
125
|
+
v3_projection_event_id: generation.last_event_id,
|
|
126
|
+
v3_task_state: generation.task_state === "set" ? "set" : "cleared",
|
|
127
|
+
};
|
|
128
|
+
writeHeartbeatCache(coordRoot, nativeInstanceId, materialized);
|
|
129
|
+
return materialized;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function writeHeartbeatCache(coordRoot: string, instanceId: string, heartbeat: Heartbeat): void {
|
|
133
|
+
if (!/^[a-zA-Z0-9._-]{1,128}$/.test(instanceId)) {
|
|
134
|
+
throw new Error("instance_id is unsafe for heartbeat materialization");
|
|
135
|
+
}
|
|
136
|
+
const path = join(coordRoot, ".harnery", "active", `${instanceId}.json`);
|
|
137
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
138
|
+
const temporary = `${path}.tmp.${process.pid}`;
|
|
139
|
+
writeFileSync(temporary, JSON.stringify(heartbeat, null, 2), "utf8");
|
|
140
|
+
renameSync(temporary, path);
|
|
141
|
+
}
|