harnery 0.34.1 → 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 -94
- package/dist/commands/agents.d.ts +37 -6
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +466 -371
- 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 +31 -6
- 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/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +2 -2
- 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/events.d.ts.map +1 -1
- package/dist/commands/events.js +18 -1
- 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/presence.d.ts.map +1 -1
- package/dist/commands/presence.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 +4 -0
- package/dist/commands/semantic.d.ts.map +1 -0
- package/dist/commands/semantic.js +199 -0
- 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 +84 -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/canonical-emit.d.ts +3 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +12 -0
- package/dist/core/agents/claim-path.d.ts +11 -0
- package/dist/core/agents/claim-path.d.ts.map +1 -0
- package/dist/core/agents/claim-path.js +22 -0
- package/dist/core/agents/cli.js +209 -39
- package/dist/core/agents/coord-client.d.ts +29 -3
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +88 -9
- 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 +245 -13
- package/dist/core/agents/live-lifecycle-v3.js +9 -4
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
- package/dist/core/agents/live-observation-v3.js +8 -3
- 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 +36 -17
- 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 +115 -22
- 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/session-name-display.d.ts +1 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +8 -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-reader.d.ts +46 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-reader.js +25 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts +9 -48
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +34 -34
- package/dist/core/agents/state/live-coordination-view.d.ts +6 -8
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +16 -67
- 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/agents/state/names.d.ts +9 -1
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +190 -182
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -5
- package/dist/core/artifacts/constants.d.ts +5 -0
- package/dist/core/artifacts/constants.d.ts.map +1 -0
- package/dist/core/artifacts/constants.js +4 -0
- package/dist/core/artifacts/index.d.ts +24 -3
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +96 -8
- 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 +851 -16
- package/dist/core/events/v3/base-contract.d.ts.map +1 -1
- package/dist/core/events/v3/base-contract.js +50 -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 +11 -0
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +26 -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 +8 -5
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +7 -4
- package/dist/core/events/v3/latency.d.ts +31 -1
- package/dist/core/events/v3/latency.d.ts.map +1 -1
- package/dist/core/events/v3/latency.js +127 -3
- 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 +42 -20
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +153 -41
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +10 -1
- 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 +90 -13
- 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 +17 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +83 -2
- package/dist/core/events/v3/producers/intake.d.ts +13 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +36 -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 +117 -1
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +992 -27
- 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 +52 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
- 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 +21 -6
- 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/parse.d.ts +3 -0
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +14 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts +142 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
- package/dist/core/hooks/adapter/runtime-telemetry.js +869 -0
- package/dist/core/hooks/cli.js +318 -61
- 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 +39 -0
- package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
- package/dist/core/hooks/remediation-cap.js +63 -0
- 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 +33 -9
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +33 -10
- 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 +37 -0
- package/dist/core/semantic/adapters.d.ts.map +1 -0
- package/dist/core/semantic/adapters.js +360 -0
- package/dist/core/semantic/contract.d.ts +1072 -0
- package/dist/core/semantic/contract.d.ts.map +1 -0
- package/dist/core/semantic/contract.js +331 -0
- package/dist/core/semantic/evidence.d.ts +11 -0
- package/dist/core/semantic/evidence.d.ts.map +1 -0
- package/dist/core/semantic/evidence.js +262 -0
- package/dist/core/semantic/index.d.ts +14 -0
- package/dist/core/semantic/index.d.ts.map +1 -0
- package/dist/core/semantic/index.js +13 -0
- package/dist/core/semantic/once.d.ts +38 -0
- package/dist/core/semantic/once.d.ts.map +1 -0
- package/dist/core/semantic/once.js +364 -0
- package/dist/core/semantic/prompt.d.ts +12 -0
- package/dist/core/semantic/prompt.d.ts.map +1 -0
- package/dist/core/semantic/prompt.js +83 -0
- 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 +27 -0
- package/dist/core/semantic/scheduler.d.ts.map +1 -0
- package/dist/core/semantic/scheduler.js +91 -0
- package/dist/core/semantic/service-status.d.ts +51 -0
- package/dist/core/semantic/service-status.d.ts.map +1 -0
- package/dist/core/semantic/service-status.js +140 -0
- package/dist/core/semantic/service.d.ts +52 -0
- package/dist/core/semantic/service.d.ts.map +1 -0
- package/dist/core/semantic/service.js +559 -0
- 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 +81 -0
- package/dist/core/semantic/storage.d.ts.map +1 -0
- package/dist/core/semantic/storage.js +180 -0
- 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 +18 -0
- package/dist/core/semantic/validate.d.ts.map +1 -0
- package/dist/core/semantic/validate.js +207 -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 +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/browser/client.d.ts +11 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +13 -0
- package/dist/lib/browser/index.d.ts +1 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.d.ts +25 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -0
- package/dist/lib/browser/standalone-html.js +284 -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.map +1 -1
- package/dist/lib/instructions/apply.js +1 -0
- package/dist/lib/instructions/templates.d.ts +2 -0
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +149 -4
- 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 +34 -2
- package/schemas/config.schema.json +58 -0
- package/schemas/event-v3.schema.json +3073 -581
- package/src/commander.ts +462 -93
- package/src/commands/agents.ts +617 -355
- package/src/commands/backup.ts +18 -14
- package/src/commands/browse-session.ts +12 -0
- package/src/commands/browse.ts +31 -9
- package/src/commands/conversations.ts +279 -0
- package/src/commands/decision.ts +8 -2
- package/src/commands/deinit.ts +6 -0
- package/src/commands/docs.ts +25 -6
- package/src/commands/doctor.ts +75 -9
- package/src/commands/events.ts +21 -1
- 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/presence.ts +7 -2
- package/src/commands/read.ts +6 -2
- package/src/commands/semantic.ts +244 -0
- package/src/commands/storage.ts +310 -0
- package/src/commands/tunnel.ts +66 -52
- package/src/commands/web.ts +92 -7
- package/src/commands/work.ts +3 -3
- package/src/commands/workflow.ts +13 -13
- package/src/core/agents/canonical-emit.ts +15 -0
- package/src/core/agents/claim-path.ts +23 -0
- package/src/core/agents/cli.ts +259 -53
- package/src/core/agents/coord-client.ts +92 -8
- package/src/core/agents/live-authority-v3.ts +342 -14
- package/src/core/agents/live-lifecycle-v3.ts +14 -4
- package/src/core/agents/live-observation-v3.ts +13 -3
- package/src/core/agents/render/prompt-context.ts +40 -16
- package/src/core/agents/rules/stop-hook.ts +129 -25
- 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/session-name-display.ts +9 -1
- package/src/core/agents/state/activity-log.ts +7 -2
- package/src/core/agents/state/heartbeat-reader.ts +69 -0
- package/src/core/agents/state/heartbeat-writer.ts +47 -84
- package/src/core/agents/state/live-coordination-view.ts +17 -81
- package/src/core/agents/state/live-coordination-writer.ts +141 -0
- package/src/core/agents/state/names.ts +190 -182
- package/src/core/agents/state/stale-sweep.ts +25 -5
- package/src/core/artifacts/constants.ts +4 -0
- package/src/core/artifacts/index.ts +113 -8
- 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 +56 -7
- package/src/core/events/v3/bootstrap.ts +195 -2
- package/src/core/events/v3/capabilities.ts +37 -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 +26 -2
- package/src/core/events/v3/latency.ts +213 -2
- package/src/core/events/v3/live-route-observer.ts +80 -0
- package/src/core/events/v3/live-routing.ts +182 -45
- package/src/core/events/v3/producers/command-recorder.ts +10 -1
- package/src/core/events/v3/producers/coordination-recorder.ts +112 -15
- package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
- package/src/core/events/v3/producers/hook-base.ts +116 -2
- package/src/core/events/v3/producers/intake.ts +48 -2
- package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
- package/src/core/events/v3/producers/recorder.ts +1403 -30
- 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 +143 -0
- 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 +66 -5
- 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/parse.ts +16 -0
- package/src/core/hooks/adapter/runtime-telemetry.ts +1200 -0
- package/src/core/hooks/cli.ts +342 -64
- package/src/core/hooks/effects/image-capture.ts +4 -1
- package/src/core/hooks/remediation-cap.ts +83 -0
- 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 +55 -11
- 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 +452 -0
- package/src/core/semantic/contract.ts +430 -0
- package/src/core/semantic/evidence.ts +336 -0
- package/src/core/semantic/index.ts +201 -0
- package/src/core/semantic/once.ts +496 -0
- package/src/core/semantic/prompt.ts +96 -0
- package/src/core/semantic/review.ts +803 -0
- package/src/core/semantic/routes.ts +30 -0
- package/src/core/semantic/scheduler.ts +151 -0
- package/src/core/semantic/service-status.ts +212 -0
- package/src/core/semantic/service.ts +681 -0
- package/src/core/semantic/soak.ts +638 -0
- package/src/core/semantic/storage.ts +300 -0
- package/src/core/semantic/usage.ts +272 -0
- package/src/core/semantic/validate.ts +243 -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/browser/client.ts +21 -0
- package/src/lib/browser/index.ts +4 -0
- package/src/lib/browser/standalone-html.ts +312 -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 +1 -0
- package/src/lib/instructions/templates.ts +154 -4
- package/src/lib/local-file-url.ts +31 -0
- package/src/lib/web-performance.ts +335 -0
|
@@ -3,17 +3,19 @@ import { chmodSync, closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, open
|
|
|
3
3
|
import { hostname } from "node:os";
|
|
4
4
|
import { basename, join, resolve } from "node:path";
|
|
5
5
|
import { extractBashCommand } from "../../../hooks/adapter/parse.js";
|
|
6
|
+
import { discoverCodexSessionTranscript, readRuntimeContextTelemetry, readRuntimeTuning, } from "../../../hooks/adapter/runtime-telemetry.js";
|
|
6
7
|
import { fsyncParentDirectory } from "../../../workflow/durable-record.js";
|
|
7
8
|
import { acquireNoClobberLease } from "../../../workflow/workspaces/leases.js";
|
|
8
9
|
import { buildEventV3 } from "../builder.js";
|
|
9
|
-
import { fingerprintV3, normalizeNativeIdV3 } from "../canonical.js";
|
|
10
|
+
import { canonicalJsonV3, fingerprintV3, normalizeNativeIdV3 } from "../canonical.js";
|
|
10
11
|
import { adapterCapabilityProfileDigestV3, adapterSignalSupportV3, cursorToolChannelSupportV3, } from "../capabilities.js";
|
|
11
12
|
import { capabilityDriftPayloadsV3 } from "../capability-drift.js";
|
|
12
13
|
import { markObservedClockRegressionV3 } from "../clock-order.js";
|
|
13
14
|
import { readEventV3ControlState } from "../control.js";
|
|
14
15
|
import { fingerprintContextV3 } from "../fingerprint-keys.js";
|
|
15
|
-
import { attestationIdV3, clockIdV3, delegationIdV3, generationIdV3, spanIdV3 } from "../ids.js";
|
|
16
|
+
import { attestationIdV3, clockIdV3, delegationIdV3, eventIdV3, generationIdV3, spanIdV3, } from "../ids.js";
|
|
16
17
|
import { readLedgerV3 } from "../reader.js";
|
|
18
|
+
import { effectiveRuntimeTelemetryCapabilitiesV3, } from "../runtime-telemetry-capabilities.js";
|
|
17
19
|
import { closeSpanStateV3, openSpanStateV3, recoverSpanUpperBoundV3, } from "../span-state.js";
|
|
18
20
|
import { extractTurnTelemetryV3, } from "../turn-telemetry.js";
|
|
19
21
|
import { assertEventV3, validateEventV3 } from "../validate.js";
|
|
@@ -27,6 +29,14 @@ const CLOSED_SPAN_TURN_RETENTION = 2;
|
|
|
27
29
|
const CLOSED_SPAN_MEMORY_CAP = 512;
|
|
28
30
|
const CLOSED_TURN_MEMORY_CAP = 16;
|
|
29
31
|
const SPAN_SOFT_WATERMARK = 128;
|
|
32
|
+
const PENDING_RUNTIME_CONTEXT_CAP = 4;
|
|
33
|
+
const RUNTIME_CONTEXT_RETRY_LIMIT = 2;
|
|
34
|
+
/** Active turns pay for at most one bounded adapter telemetry read per interval. */
|
|
35
|
+
const ACTIVE_RUNTIME_CONTEXT_PROBE_INTERVAL_MS = 15_000;
|
|
36
|
+
/** Codex can flush the terminal row just after Stop; keep this grace bounded and off other hooks. */
|
|
37
|
+
const STOP_RUNTIME_CONTEXT_RETRY_DELAYS_MS = [75, 175];
|
|
38
|
+
/** Finalization is off the interactive hook path; briefly cover Codex's delayed transcript flush. */
|
|
39
|
+
const APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS = [0, 250, 250];
|
|
30
40
|
/**
|
|
31
41
|
* Adapters whose turn-boundary recovery and mid-flight onboarding are enabled.
|
|
32
42
|
* Kept in code, outside the digested capability profiles, so tuning recovery
|
|
@@ -88,7 +98,14 @@ function hookSignalGate(control, adapter, signal) {
|
|
|
88
98
|
return undefined;
|
|
89
99
|
}
|
|
90
100
|
function sessionHashForSignal(input, context) {
|
|
91
|
-
const
|
|
101
|
+
const nativeChild = input.payload.subagent_id ?? input.payload.agent_id;
|
|
102
|
+
const childOwnsSignal = input.signal !== "sub-agent-start" &&
|
|
103
|
+
input.signal !== "sub-agent-stop" &&
|
|
104
|
+
nativeChild !== undefined &&
|
|
105
|
+
input.instance_id === asLiveInstanceId(nativeChild);
|
|
106
|
+
const nativeSession = childOwnsSignal
|
|
107
|
+
? nativeChild
|
|
108
|
+
: (input.payload.session_id ?? input.payload.conversation_id ?? input.payload.agent_id);
|
|
92
109
|
if (nativeSession !== undefined) {
|
|
93
110
|
return normalizeNativeIdV3(context, `${input.adapter}.session`, nativeSession);
|
|
94
111
|
}
|
|
@@ -130,6 +147,7 @@ function intakeRecord(input) {
|
|
|
130
147
|
: {}),
|
|
131
148
|
...(input.stop_remediation !== undefined ? { stop_remediation: input.stop_remediation } : {}),
|
|
132
149
|
...(input.turn_ritual ? { turn_ritual: input.turn_ritual } : {}),
|
|
150
|
+
...(input.delegated_child ? { delegated_child: input.delegated_child } : {}),
|
|
133
151
|
};
|
|
134
152
|
}
|
|
135
153
|
function inputForIntakeRecord(coordRoot, record) {
|
|
@@ -152,6 +170,7 @@ function inputForIntakeRecord(coordRoot, record) {
|
|
|
152
170
|
...(record.hook_duration_ms !== undefined ? { hook_duration_ms: record.hook_duration_ms } : {}),
|
|
153
171
|
...(record.stop_remediation !== undefined ? { stop_remediation: record.stop_remediation } : {}),
|
|
154
172
|
...(record.turn_ritual ? { turn_ritual: record.turn_ritual } : {}),
|
|
173
|
+
...(record.delegated_child ? { delegated_child: record.delegated_child } : {}),
|
|
155
174
|
};
|
|
156
175
|
}
|
|
157
176
|
/**
|
|
@@ -268,8 +287,23 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
268
287
|
: control.activation.event.event_id;
|
|
269
288
|
const rootFingerprintContext = fingerprintContextV3(input.coordRoot, rootId, undefined, epochId);
|
|
270
289
|
const sessionId = `sid_${sessionHash.slice(4)}`;
|
|
290
|
+
const genesisId = control.genesis.event.payload.genesis_id;
|
|
291
|
+
// Every write below carries the epoch fence: an event produced for this
|
|
292
|
+
// epoch is refused (or quarantined from the spool) once the epoch has been
|
|
293
|
+
// replaced, instead of poisoning the successor's authority.
|
|
294
|
+
input = {
|
|
295
|
+
...input,
|
|
296
|
+
writerOptions: { ...input.writerOptions, expectedGenesisId: genesisId },
|
|
297
|
+
};
|
|
271
298
|
try {
|
|
272
299
|
let state = existsSync(path) ? readProducerState(path) : undefined;
|
|
300
|
+
if (state && state.epoch_genesis_id !== genesisId) {
|
|
301
|
+
// A producer state from a replaced epoch (or one that predates the
|
|
302
|
+
// field) is never adopted: its boot sequences and causal links only
|
|
303
|
+
// validate inside the epoch that recorded them. The session re-onboards
|
|
304
|
+
// below exactly as it does after an automatic epoch refresh.
|
|
305
|
+
state = undefined;
|
|
306
|
+
}
|
|
273
307
|
if (state &&
|
|
274
308
|
(state.adapter !== input.adapter ||
|
|
275
309
|
state.session_id !== sessionId ||
|
|
@@ -292,7 +326,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
292
326
|
const pendingSource = state.pending.source_id;
|
|
293
327
|
const incomingSource = sourceIdForSignal(input, rootFingerprintContext);
|
|
294
328
|
const pendingEvent = state.pending.event;
|
|
295
|
-
const durability = writeEventV3(input.coordRoot, pendingEvent);
|
|
329
|
+
const durability = writeEventV3(input.coordRoot, pendingEvent, input.writerOptions);
|
|
296
330
|
applyCommittedEvent(state, pendingEvent);
|
|
297
331
|
state.pending = undefined;
|
|
298
332
|
publishProducerState(path, state);
|
|
@@ -306,10 +340,11 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
306
340
|
if (state && !state.terminal && state.started_event_id) {
|
|
307
341
|
return { state: "already_started", event_id: state.started_event_id };
|
|
308
342
|
}
|
|
309
|
-
if (input.session_start_derivation && !state?.terminal)
|
|
343
|
+
if ((input.session_start_derivation === "approved_lifecycle_reopen" && !state?.terminal) ||
|
|
344
|
+
(input.session_start_derivation === "validated_current_session_heal" && state?.terminal)) {
|
|
310
345
|
return { state: "missing_session_start" };
|
|
311
346
|
}
|
|
312
|
-
state = newProducerState(input, sessionId, epochId, boundaryEventId);
|
|
347
|
+
state = newProducerState(input, sessionId, epochId, boundaryEventId, genesisId);
|
|
313
348
|
}
|
|
314
349
|
else if (!state || state.terminal) {
|
|
315
350
|
// Mid-flight onboarding (ADR 0078): a live session with no producer
|
|
@@ -335,7 +370,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
335
370
|
});
|
|
336
371
|
return { state: "missing_session_start" };
|
|
337
372
|
}
|
|
338
|
-
state = newProducerState(input, sessionId, epochId, boundaryEventId);
|
|
373
|
+
state = newProducerState(input, sessionId, epochId, boundaryEventId, genesisId);
|
|
339
374
|
const cursorPromptBootstrap = isCursorPromptBootstrap(input);
|
|
340
375
|
const onboarding = buildMidFlightSessionStart(input, state, rootId, cursorPromptBootstrap);
|
|
341
376
|
commitEventLocked(input, state, path, onboarding);
|
|
@@ -345,6 +380,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
345
380
|
instance_id: input.instance_id,
|
|
346
381
|
signal: input.signal,
|
|
347
382
|
session_hash: sessionHash,
|
|
383
|
+
...(input.adapter === "codex" ? codexMidFlightDiagnosticContext(input.payload) : {}),
|
|
348
384
|
});
|
|
349
385
|
}
|
|
350
386
|
}
|
|
@@ -386,6 +422,9 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
386
422
|
(cursorPromptWithinOpenTurn ||
|
|
387
423
|
(nativeTid !== undefined && state.current_turn_id === nativeTid));
|
|
388
424
|
recordTurnHarnessTiming(state, input, !duplicateOpenTurnStart);
|
|
425
|
+
reconcilePendingRuntimeContexts(input, state, path, rootId, fingerprintContext, {
|
|
426
|
+
finalAttempt: input.signal === "session-end",
|
|
427
|
+
});
|
|
389
428
|
closeResolvedWaits(input, state, path, rootId, fingerprintContext, nativeTid);
|
|
390
429
|
if (input.signal === "permission-request") {
|
|
391
430
|
const waitId = waitIdForInput(input, fingerprintContext);
|
|
@@ -435,6 +474,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
435
474
|
boot_id: state.boot_id,
|
|
436
475
|
clock: eventClock,
|
|
437
476
|
});
|
|
477
|
+
state.current_native_turn_id = input.payload.turn_id;
|
|
438
478
|
}
|
|
439
479
|
let sourceId = sourceIdForSignal(input, rootFingerprintContext);
|
|
440
480
|
const semanticKey = cursorShellSemanticKey(input, rootFingerprintContext);
|
|
@@ -628,7 +668,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
628
668
|
})
|
|
629
669
|
: undefined;
|
|
630
670
|
const turnTelemetry = input.signal === "stop" || input.signal === "stop-failure"
|
|
631
|
-
?
|
|
671
|
+
? turnTelemetryForTerminal(input, state, eventClock.observed_at)
|
|
632
672
|
: undefined;
|
|
633
673
|
const cursorToolChannelSupport = input.adapter === "cursor"
|
|
634
674
|
? cursorToolChannelSupportV3(state.cursor_mode ?? "unknown")
|
|
@@ -642,6 +682,9 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
642
682
|
}
|
|
643
683
|
const toolCallCountScopeMismatch = (input.signal === "stop" || input.signal === "stop-failure") &&
|
|
644
684
|
(!state.current_turn_id || state.tool_call_count_turn_id !== state.current_turn_id);
|
|
685
|
+
// Before the signal's own event: the tool call or turn that carries the
|
|
686
|
+
// new effort already ran under it, so it must ride the new attestation.
|
|
687
|
+
maybeAttestTuningChange(input, state, path, rootId);
|
|
645
688
|
const event = normalizeHookEventV3(input.signal, eventInput.payload, {
|
|
646
689
|
coordRoot: input.coordRoot,
|
|
647
690
|
adapter: input.adapter,
|
|
@@ -665,6 +708,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
665
708
|
platform: input.platform,
|
|
666
709
|
bridge: input.bridge,
|
|
667
710
|
capability_profile: state.capability_profile,
|
|
711
|
+
cursor_mode: state.cursor_mode,
|
|
668
712
|
fingerprintContext,
|
|
669
713
|
turn_id: state.current_turn_id,
|
|
670
714
|
span_id: openingSpan?.span_id ?? closingSpan?.span_id,
|
|
@@ -703,11 +747,53 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
703
747
|
if (!event)
|
|
704
748
|
return { state: "ignored" };
|
|
705
749
|
if (input.signal === "session-start" &&
|
|
706
|
-
input.
|
|
750
|
+
input.delegated_child &&
|
|
707
751
|
event.event_type === "session.started") {
|
|
752
|
+
event.links = {
|
|
753
|
+
caused_by: [input.delegated_child.caused_by_event_id],
|
|
754
|
+
parent_generation_id: input.delegated_child.parent_generation_id,
|
|
755
|
+
delegation_id: input.delegated_child.delegation_id,
|
|
756
|
+
};
|
|
757
|
+
event.provenance = {
|
|
758
|
+
...event.provenance,
|
|
759
|
+
source_event: `${input.adapter}.subagent-start.child-generation`,
|
|
760
|
+
attestation: "derived",
|
|
761
|
+
confidence: "high",
|
|
762
|
+
attribution: {
|
|
763
|
+
method: "native_payload",
|
|
764
|
+
state: "verified",
|
|
765
|
+
subject_instance_id: state.instance_id,
|
|
766
|
+
},
|
|
767
|
+
};
|
|
768
|
+
assertEventV3(event);
|
|
769
|
+
}
|
|
770
|
+
if (input.signal === "user-prompt-submit" &&
|
|
771
|
+
input.delegated_child &&
|
|
772
|
+
event.event_type === "turn.started") {
|
|
773
|
+
event.links = { caused_by: [input.delegated_child.caused_by_event_id] };
|
|
708
774
|
event.provenance = {
|
|
709
775
|
...event.provenance,
|
|
710
|
-
source_event: `${input.adapter}.
|
|
776
|
+
source_event: `${input.adapter}.subagent-start.child-turn`,
|
|
777
|
+
attestation: "derived",
|
|
778
|
+
confidence: "high",
|
|
779
|
+
attribution: {
|
|
780
|
+
method: "native_payload",
|
|
781
|
+
state: "verified",
|
|
782
|
+
subject_instance_id: state.instance_id,
|
|
783
|
+
},
|
|
784
|
+
};
|
|
785
|
+
assertEventV3(event);
|
|
786
|
+
}
|
|
787
|
+
if (input.signal === "session-start" &&
|
|
788
|
+
input.session_start_derivation &&
|
|
789
|
+
event.event_type === "session.started") {
|
|
790
|
+
const lifecycleReopen = input.session_start_derivation === "approved_lifecycle_reopen";
|
|
791
|
+
const reason = lifecycleReopen
|
|
792
|
+
? "approved_lifecycle_reopen"
|
|
793
|
+
: "validated_current_session_heal";
|
|
794
|
+
event.provenance = {
|
|
795
|
+
...event.provenance,
|
|
796
|
+
source_event: `${input.adapter}.${reason.replaceAll("_", "-")}`,
|
|
711
797
|
attestation: "derived",
|
|
712
798
|
confidence: "high",
|
|
713
799
|
attribution: {
|
|
@@ -718,7 +804,7 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
718
804
|
};
|
|
719
805
|
event.payload.resume = {
|
|
720
806
|
state: "unknown",
|
|
721
|
-
reason
|
|
807
|
+
reason,
|
|
722
808
|
};
|
|
723
809
|
assertEventV3(event);
|
|
724
810
|
}
|
|
@@ -727,7 +813,13 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
727
813
|
span.open_event_id = event.event_id;
|
|
728
814
|
stampSpanTurn(span, event, eventInput, state);
|
|
729
815
|
}
|
|
816
|
+
// A turn terminal clears current_native_turn_id when it commits. Retain the
|
|
817
|
+
// native identity long enough to seed a delayed context retry afterward.
|
|
818
|
+
const nativeTurnIdForContext = input.payload.turn_id ?? state.current_native_turn_id;
|
|
730
819
|
const durability = commitEventLocked(input, state, path, event, sourceId);
|
|
820
|
+
if (event.event_type === "context.compaction_started" && input.signal === "pre-compact") {
|
|
821
|
+
maybeCommitNativeHookContextObservation(input, state, path, rootId, fingerprintContext, event);
|
|
822
|
+
}
|
|
731
823
|
if (event.event_type === "tool.requested" && sourceId) {
|
|
732
824
|
const explicitWait = explicitNativeWait(input);
|
|
733
825
|
if (explicitWait) {
|
|
@@ -741,8 +833,13 @@ function processHookSignalLocked(control, input, sessionHash, path) {
|
|
|
741
833
|
if (progressKind) {
|
|
742
834
|
commitProgressObservation(input, state, path, rootId, event, progressKind);
|
|
743
835
|
}
|
|
836
|
+
if (event.event_type === "tool.completed" && input.signal === "post-tool-use") {
|
|
837
|
+
maybeCommitActiveRuntimeContextObservation(input, state, path, rootId, fingerprintContext, event);
|
|
838
|
+
}
|
|
744
839
|
if (turnTelemetry) {
|
|
745
|
-
|
|
840
|
+
const contextTarget = turnContextTarget(event);
|
|
841
|
+
queuePendingRuntimeContext(input, state, contextTarget, turnTelemetry.context, nativeTurnIdForContext);
|
|
842
|
+
commitTurnContextObservation(input, state, path, rootId, fingerprintContext, contextTarget, turnTelemetry.context, turnTelemetry.context_provenance);
|
|
746
843
|
}
|
|
747
844
|
if (event.event_type === "session.ended") {
|
|
748
845
|
commitCapabilityDriftEvents(input, state, path, rootId);
|
|
@@ -1101,9 +1198,28 @@ function commitEventLocked(input, state, path, event, sourceId) {
|
|
|
1101
1198
|
publishProducerState(path, state);
|
|
1102
1199
|
return durability;
|
|
1103
1200
|
}
|
|
1104
|
-
function commitTurnContextObservation(input, state, path, rootId,
|
|
1105
|
-
if (
|
|
1201
|
+
function commitTurnContextObservation(input, state, path, rootId, fingerprintContext, target, measurement, contextProvenance, observedAt) {
|
|
1202
|
+
if (!target)
|
|
1106
1203
|
return;
|
|
1204
|
+
commitContextObservation(input, state, path, rootId, fingerprintContext, {
|
|
1205
|
+
caused_by_event_id: target.terminal_event_id,
|
|
1206
|
+
observed_at: observedAt ?? target.terminal_observed_at,
|
|
1207
|
+
turn_id: target.turn_id,
|
|
1208
|
+
...(target.run_id ? { run_id: target.run_id } : {}),
|
|
1209
|
+
...(target.workflow_id ? { workflow_id: target.workflow_id } : {}),
|
|
1210
|
+
...(target.workflow_agent_id ? { workflow_agent_id: target.workflow_agent_id } : {}),
|
|
1211
|
+
}, measurement, contextProvenance);
|
|
1212
|
+
}
|
|
1213
|
+
function commitContextObservation(input, state, path, rootId, fingerprintContext, target, measurement, contextProvenance) {
|
|
1214
|
+
if (measurement.state === "observed" &&
|
|
1215
|
+
contextProvenance?.source_witness &&
|
|
1216
|
+
state.last_context_source_witness === contextProvenance.source_witness) {
|
|
1217
|
+
publishProducerState(path, state);
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
if (measurement.state === "observed" && contextProvenance?.source_witness) {
|
|
1221
|
+
state.last_context_source_witness = contextProvenance.source_witness;
|
|
1222
|
+
}
|
|
1107
1223
|
const event = buildEventV3("context.observed", {
|
|
1108
1224
|
producer: {
|
|
1109
1225
|
producer_id: input.producer_id,
|
|
@@ -1119,34 +1235,667 @@ function commitTurnContextObservation(input, state, path, rootId, turnTerminal,
|
|
|
1119
1235
|
instance_id: state.instance_id,
|
|
1120
1236
|
session_id: state.session_id,
|
|
1121
1237
|
generation_id: state.generation_id,
|
|
1122
|
-
turn_id:
|
|
1123
|
-
...(
|
|
1124
|
-
...(
|
|
1125
|
-
...(
|
|
1238
|
+
turn_id: target.turn_id,
|
|
1239
|
+
...(target.run_id ? { run_id: target.run_id } : {}),
|
|
1240
|
+
...(target.workflow_id ? { workflow_id: target.workflow_id } : {}),
|
|
1241
|
+
...(target.workflow_agent_id ? { workflow_agent_id: target.workflow_agent_id } : {}),
|
|
1126
1242
|
},
|
|
1127
1243
|
attestation_id: state.attestation_id,
|
|
1128
|
-
links: { caused_by: [
|
|
1244
|
+
links: { caused_by: [target.caused_by_event_id] },
|
|
1129
1245
|
provenance: {
|
|
1130
|
-
source_event:
|
|
1246
|
+
source_event: safeRole([
|
|
1247
|
+
contextProvenance?.source_event ?? `${input.adapter}.turn-context`,
|
|
1248
|
+
contextProvenance?.runtime_version,
|
|
1249
|
+
]
|
|
1250
|
+
.filter(Boolean)
|
|
1251
|
+
.join(".")),
|
|
1252
|
+
attestation: contextProvenance?.attestation ?? "native",
|
|
1253
|
+
confidence: contextProvenance?.confidence ?? "exact",
|
|
1254
|
+
...(contextProvenance?.source_witness
|
|
1255
|
+
? {
|
|
1256
|
+
source_record_id: normalizeNativeIdV3(fingerprintContext, `${input.adapter}.runtime-context`, contextProvenance.source_witness),
|
|
1257
|
+
}
|
|
1258
|
+
: {}),
|
|
1259
|
+
attribution: {
|
|
1260
|
+
method: "native_payload",
|
|
1261
|
+
state: "verified",
|
|
1262
|
+
subject_instance_id: state.instance_id,
|
|
1263
|
+
},
|
|
1264
|
+
},
|
|
1265
|
+
// The source sample may precede the hook boundary that admits it.
|
|
1266
|
+
// measurement.measured_at preserves the sample clock without creating a
|
|
1267
|
+
// causal wall-clock regression in the producer event chain.
|
|
1268
|
+
observed_at: target.observed_at,
|
|
1269
|
+
monotonic_ns: orderedEventMonotonic(state, input.monotonic_ns),
|
|
1270
|
+
clock_id: state.clock_id,
|
|
1271
|
+
payload: {
|
|
1272
|
+
measurement,
|
|
1273
|
+
},
|
|
1274
|
+
});
|
|
1275
|
+
commitEventLocked(input, state, path, event);
|
|
1276
|
+
maybeAttestContextCapabilityChange(input, state, path, rootId, measurement, contextProvenance);
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Admit fresh adapter-native or bounded runtime context while a turn is open.
|
|
1280
|
+
* Tool completions are safe sampling boundaries. Persistent owner-only cadence
|
|
1281
|
+
* state prevents short-lived hook processes from reading on every request,
|
|
1282
|
+
* and the source witness prevents duplicate public events.
|
|
1283
|
+
*/
|
|
1284
|
+
function maybeCommitActiveRuntimeContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent) {
|
|
1285
|
+
if (input.signal !== "post-tool-use" || state.terminal || !state.current_turn_id) {
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
|
|
1289
|
+
const nativeTurnId = input.payload.turn_id ?? state.current_native_turn_id;
|
|
1290
|
+
if (!nativeSessionId || (!nativeTurnId && input.adapter !== "cursor"))
|
|
1291
|
+
return;
|
|
1292
|
+
const now = Date.now();
|
|
1293
|
+
const configuredInterval = input.runtimeTelemetryOptions?.activeContextProbeIntervalMs;
|
|
1294
|
+
const intervalMs = configuredInterval !== undefined && Number.isFinite(configuredInterval)
|
|
1295
|
+
? Math.max(0, Math.floor(configuredInterval))
|
|
1296
|
+
: ACTIVE_RUNTIME_CONTEXT_PROBE_INTERVAL_MS;
|
|
1297
|
+
const prior = state.active_runtime_context_probe;
|
|
1298
|
+
const priorAttempt = prior ? Date.parse(prior.attempted_at) : Number.NaN;
|
|
1299
|
+
if (prior?.turn_id === state.current_turn_id &&
|
|
1300
|
+
prior.boundary === "tool_completed" &&
|
|
1301
|
+
Number.isFinite(priorAttempt) &&
|
|
1302
|
+
now - priorAttempt >= 0 &&
|
|
1303
|
+
now - priorAttempt < intervalMs) {
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
state.active_runtime_context_probe = {
|
|
1307
|
+
turn_id: state.current_turn_id,
|
|
1308
|
+
attempted_at: new Date(now).toISOString(),
|
|
1309
|
+
boundary: "tool_completed",
|
|
1310
|
+
};
|
|
1311
|
+
const native = extractTurnTelemetryV3(input.adapter, input.payload.raw, sourceEvent.time.observed_at).context;
|
|
1312
|
+
if (native.state === "observed") {
|
|
1313
|
+
commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, native, nativeContextProvenance(input, state, native));
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
if (input.adapter === "cursor" && state.cursor_mode === "cloud") {
|
|
1317
|
+
publishProducerState(path, state);
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
const transcriptPath = runtimeTranscriptPath(input, state);
|
|
1321
|
+
if (!transcriptPath && input.adapter !== "cursor") {
|
|
1322
|
+
publishProducerState(path, state);
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
const runtime = readRuntimeContextTelemetry({
|
|
1326
|
+
adapter: input.adapter,
|
|
1327
|
+
session_id: nativeSessionId,
|
|
1328
|
+
...(nativeTurnId ? { turn_id: nativeTurnId } : {}),
|
|
1329
|
+
...(state.current_turn_span?.opened_at
|
|
1330
|
+
? { turn_started_at: state.current_turn_span.opened_at }
|
|
1331
|
+
: {}),
|
|
1332
|
+
transcript_path: transcriptPath,
|
|
1333
|
+
observed_at: sourceEvent.time.observed_at,
|
|
1334
|
+
mode: "active_turn",
|
|
1335
|
+
}, input.runtimeTelemetryOptions);
|
|
1336
|
+
if (runtime.bytes_read > 0)
|
|
1337
|
+
recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
|
|
1338
|
+
if (runtime.state !== "observed") {
|
|
1339
|
+
publishProducerState(path, state);
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, runtimeContextObservation(runtime), {
|
|
1343
|
+
source_event: runtime.source_event,
|
|
1344
|
+
source_witness: runtime.source_witness,
|
|
1345
|
+
...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
|
|
1346
|
+
attestation: runtime.attestation,
|
|
1347
|
+
confidence: runtime.confidence,
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
function commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, measurement, provenance) {
|
|
1351
|
+
if (!state.current_turn_id)
|
|
1352
|
+
return;
|
|
1353
|
+
const scope = sourceEvent.scope;
|
|
1354
|
+
commitContextObservation(input, state, path, rootId, fingerprintContext, {
|
|
1355
|
+
caused_by_event_id: sourceEvent.event_id,
|
|
1356
|
+
observed_at: sourceEvent.time.observed_at,
|
|
1357
|
+
turn_id: state.current_turn_id,
|
|
1358
|
+
...(scope.run_id ? { run_id: scope.run_id } : {}),
|
|
1359
|
+
...(scope.workflow_id ? { workflow_id: scope.workflow_id } : {}),
|
|
1360
|
+
...(scope.workflow_agent_id ? { workflow_agent_id: scope.workflow_agent_id } : {}),
|
|
1361
|
+
}, measurement, provenance);
|
|
1362
|
+
}
|
|
1363
|
+
function nativeContextProvenance(input, state, measurement) {
|
|
1364
|
+
const { measured_at: _measuredAt, ...stableValue } = measurement.value;
|
|
1365
|
+
const witness = canonicalJsonV3({
|
|
1366
|
+
adapter: input.adapter,
|
|
1367
|
+
session_id: state.session_id,
|
|
1368
|
+
turn_id: state.current_turn_id,
|
|
1369
|
+
value: stableValue,
|
|
1370
|
+
});
|
|
1371
|
+
return {
|
|
1372
|
+
source_event: `${input.adapter}.native_context`,
|
|
1373
|
+
source_witness: createHash("sha256").update(witness).digest("hex"),
|
|
1374
|
+
...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
|
|
1375
|
+
attestation: measurement.attestation,
|
|
1376
|
+
confidence: measurement.confidence,
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
function maybeCommitNativeHookContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent) {
|
|
1380
|
+
const measurement = extractTurnTelemetryV3(input.adapter, input.payload.raw, sourceEvent.time.observed_at).context;
|
|
1381
|
+
if (measurement.state !== "observed")
|
|
1382
|
+
return;
|
|
1383
|
+
commitActiveContextObservation(input, state, path, rootId, fingerprintContext, sourceEvent, measurement, nativeContextProvenance(input, state, measurement));
|
|
1384
|
+
}
|
|
1385
|
+
function maybeAttestContextCapabilityChange(input, state, path, rootId, measurement, provenance) {
|
|
1386
|
+
const context = measurement.state === "observed"
|
|
1387
|
+
? {
|
|
1388
|
+
state: "observed",
|
|
1389
|
+
source: provenance?.source_event ?? `${input.adapter}.turn_context`,
|
|
1390
|
+
attestation: provenance?.attestation ?? measurement.attestation,
|
|
1391
|
+
confidence: provenance?.confidence ?? measurement.confidence,
|
|
1392
|
+
completeness: "used_percent" in measurement.value
|
|
1393
|
+
? "percentage_only"
|
|
1394
|
+
: (provenance?.attestation ?? measurement.attestation) === "inferred"
|
|
1395
|
+
? "inferred"
|
|
1396
|
+
: "exact",
|
|
1397
|
+
}
|
|
1398
|
+
: measurement.state === "expected_but_missing"
|
|
1399
|
+
? { state: "partial", reason: measurement.reason }
|
|
1400
|
+
: { state: "unsupported" };
|
|
1401
|
+
const telemetry = effectiveRuntimeTelemetryCapabilitiesV3({
|
|
1402
|
+
adapter: input.adapter,
|
|
1403
|
+
...(state.cursor_mode ? { cursor_mode: state.cursor_mode } : {}),
|
|
1404
|
+
context,
|
|
1405
|
+
canonical_turn_boundaries: true,
|
|
1406
|
+
});
|
|
1407
|
+
if (!state.last_attested_telemetry)
|
|
1408
|
+
return;
|
|
1409
|
+
if (canonicalJsonV3(telemetry) === canonicalJsonV3(state.last_attested_telemetry))
|
|
1410
|
+
return;
|
|
1411
|
+
if (!state.last_attested_model_observation || !state.last_attested_tuning_observation)
|
|
1412
|
+
return;
|
|
1413
|
+
commitRuntimeAttestationChange(input, state, path, rootId, {
|
|
1414
|
+
model: state.last_attested_model_observation,
|
|
1415
|
+
tuning: state.last_attested_tuning_observation,
|
|
1416
|
+
telemetry,
|
|
1417
|
+
reason: "runtime_telemetry_changed",
|
|
1418
|
+
source_event: provenance?.source_event ?? `${input.adapter}.turn_context`,
|
|
1419
|
+
attestation: provenance?.attestation ?? "derived",
|
|
1420
|
+
confidence: provenance?.confidence ?? (measurement.state === "observed" ? "exact" : "high"),
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1423
|
+
function turnContextTarget(turnTerminal) {
|
|
1424
|
+
if (turnTerminal.event_type !== "turn.completed")
|
|
1425
|
+
return undefined;
|
|
1426
|
+
const scope = turnTerminal.scope;
|
|
1427
|
+
return {
|
|
1428
|
+
terminal_event_id: turnTerminal.event_id,
|
|
1429
|
+
terminal_observed_at: turnTerminal.time.observed_at,
|
|
1430
|
+
turn_id: scope.turn_id,
|
|
1431
|
+
...(scope.run_id ? { run_id: scope.run_id } : {}),
|
|
1432
|
+
...(scope.workflow_id ? { workflow_id: scope.workflow_id } : {}),
|
|
1433
|
+
...(scope.workflow_agent_id ? { workflow_agent_id: scope.workflow_agent_id } : {}),
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
function queuePendingRuntimeContext(input, state, target, measurement, nativeTurnId) {
|
|
1437
|
+
if (input.adapter !== "codex" ||
|
|
1438
|
+
!target ||
|
|
1439
|
+
measurement.state !== "expected_but_missing" ||
|
|
1440
|
+
!retryableRuntimeContextReason(measurement.reason)) {
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
|
|
1444
|
+
if (!nativeSessionId || !nativeTurnId)
|
|
1445
|
+
return;
|
|
1446
|
+
const pending = {
|
|
1447
|
+
...target,
|
|
1448
|
+
native_session_id: nativeSessionId,
|
|
1449
|
+
native_turn_id: nativeTurnId,
|
|
1450
|
+
...((input.payload.transcript_path ?? state.runtime_transcript_path)
|
|
1451
|
+
? { transcript_path: input.payload.transcript_path ?? state.runtime_transcript_path }
|
|
1452
|
+
: {}),
|
|
1453
|
+
...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
|
|
1454
|
+
attempts: 0,
|
|
1455
|
+
};
|
|
1456
|
+
state.pending_runtime_contexts = [
|
|
1457
|
+
...(state.pending_runtime_contexts ?? []).filter((candidate) => candidate.turn_id !== target.turn_id),
|
|
1458
|
+
pending,
|
|
1459
|
+
].slice(-PENDING_RUNTIME_CONTEXT_CAP);
|
|
1460
|
+
}
|
|
1461
|
+
function reconcilePendingRuntimeContexts(input, state, path, rootId, fingerprintContext, options = {}) {
|
|
1462
|
+
if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length)
|
|
1463
|
+
return;
|
|
1464
|
+
for (const pending of [...state.pending_runtime_contexts]) {
|
|
1465
|
+
const runtime = readRuntimeContextTelemetry({
|
|
1466
|
+
adapter: "codex",
|
|
1467
|
+
session_id: pending.native_session_id,
|
|
1468
|
+
turn_id: pending.native_turn_id,
|
|
1469
|
+
transcript_path: pending.transcript_path,
|
|
1470
|
+
mode: "turn",
|
|
1471
|
+
}, input.runtimeTelemetryOptions);
|
|
1472
|
+
if (runtime.bytes_read > 0)
|
|
1473
|
+
recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
|
|
1474
|
+
const queue = state.pending_runtime_contexts;
|
|
1475
|
+
if (!queue)
|
|
1476
|
+
break;
|
|
1477
|
+
const index = queue.findIndex((candidate) => candidate.turn_id === pending.turn_id);
|
|
1478
|
+
if (index < 0)
|
|
1479
|
+
continue;
|
|
1480
|
+
if (runtime.state === "observed") {
|
|
1481
|
+
queue.splice(index, 1);
|
|
1482
|
+
if (queue.length === 0) {
|
|
1483
|
+
state.pending_runtime_contexts = undefined;
|
|
1484
|
+
}
|
|
1485
|
+
commitTurnContextObservation(input, state, path, rootId, fingerprintContext, pending, runtimeContextObservation(runtime), {
|
|
1486
|
+
source_event: runtime.source_event,
|
|
1487
|
+
source_witness: runtime.source_witness,
|
|
1488
|
+
...(pending.runtime_version ? { runtime_version: pending.runtime_version } : {}),
|
|
1489
|
+
attestation: "derived",
|
|
1490
|
+
confidence: "exact",
|
|
1491
|
+
}, signalClock(input).observed_at);
|
|
1492
|
+
continue;
|
|
1493
|
+
}
|
|
1494
|
+
const attempts = pending.attempts + 1;
|
|
1495
|
+
if (options.finalAttempt ||
|
|
1496
|
+
runtime.state === "unsupported" ||
|
|
1497
|
+
!retryableRuntimeContextReason(runtime.reason) ||
|
|
1498
|
+
(!options.deferRetryLimit && attempts >= RUNTIME_CONTEXT_RETRY_LIMIT)) {
|
|
1499
|
+
queue.splice(index, 1);
|
|
1500
|
+
}
|
|
1501
|
+
else {
|
|
1502
|
+
queue[index] = { ...pending, attempts };
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
if (state.pending_runtime_contexts?.length === 0) {
|
|
1506
|
+
state.pending_runtime_contexts = undefined;
|
|
1507
|
+
}
|
|
1508
|
+
publishProducerState(path, state);
|
|
1509
|
+
}
|
|
1510
|
+
function reconcilePendingRuntimeContextsBeforeApprovedEnd(input, state, path, rootId, fingerprintContext) {
|
|
1511
|
+
if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length)
|
|
1512
|
+
return;
|
|
1513
|
+
for (const [index, delayMs] of APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS.entries()) {
|
|
1514
|
+
if (delayMs > 0)
|
|
1515
|
+
sleepSync(delayMs);
|
|
1516
|
+
reconcilePendingRuntimeContexts({
|
|
1517
|
+
coordRoot: input.coordRoot,
|
|
1518
|
+
mode: input.mode,
|
|
1519
|
+
signal: "session-end",
|
|
1520
|
+
payload: { raw: {} },
|
|
1521
|
+
adapter: state.adapter,
|
|
1522
|
+
instance_id: state.instance_id,
|
|
1523
|
+
producer_id: "prd_agent-finalizer",
|
|
1524
|
+
build_id: input.build_id,
|
|
1525
|
+
platform: input.platform,
|
|
1526
|
+
observed_at: new Date().toISOString(),
|
|
1527
|
+
writerOptions: input.writerOptions,
|
|
1528
|
+
}, state, path, rootId, fingerprintContext, {
|
|
1529
|
+
deferRetryLimit: true,
|
|
1530
|
+
finalAttempt: index === APPROVED_END_RUNTIME_CONTEXT_RETRY_DELAYS_MS.length - 1,
|
|
1531
|
+
});
|
|
1532
|
+
if (!state.pending_runtime_contexts?.length)
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
function retryableRuntimeContextReason(reason) {
|
|
1537
|
+
return (reason === "codex_transcript_turn_not_found" ||
|
|
1538
|
+
reason === "codex_transcript_turn_not_terminal" ||
|
|
1539
|
+
reason === "codex_transcript_token_count_missing");
|
|
1540
|
+
}
|
|
1541
|
+
function turnTelemetryForTerminal(input, state, observedAt) {
|
|
1542
|
+
const native = extractTurnTelemetryV3(input.adapter, input.payload.raw, observedAt);
|
|
1543
|
+
if (native.context.state === "observed")
|
|
1544
|
+
return native;
|
|
1545
|
+
if (input.adapter === "cursor" && state.cursor_mode === "cloud") {
|
|
1546
|
+
return {
|
|
1547
|
+
...native,
|
|
1548
|
+
context: { state: "unsupported", capability: "context_usage" },
|
|
1549
|
+
};
|
|
1550
|
+
}
|
|
1551
|
+
const request = {
|
|
1552
|
+
adapter: input.adapter,
|
|
1553
|
+
session_id: input.payload.session_id ?? input.payload.conversation_id,
|
|
1554
|
+
turn_id: input.payload.turn_id ?? state.current_native_turn_id,
|
|
1555
|
+
transcript_path: runtimeTranscriptPath(input, state),
|
|
1556
|
+
observed_at: observedAt,
|
|
1557
|
+
mode: "turn",
|
|
1558
|
+
};
|
|
1559
|
+
let runtime = readRuntimeContextTelemetry(request, input.runtimeTelemetryOptions);
|
|
1560
|
+
if (runtime.bytes_read > 0)
|
|
1561
|
+
recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
|
|
1562
|
+
if (input.adapter === "codex" &&
|
|
1563
|
+
runtime.state === "partial" &&
|
|
1564
|
+
retryableRuntimeContextReason(runtime.reason)) {
|
|
1565
|
+
for (const delayMs of STOP_RUNTIME_CONTEXT_RETRY_DELAYS_MS) {
|
|
1566
|
+
sleepSync(delayMs);
|
|
1567
|
+
runtime = readRuntimeContextTelemetry(request, input.runtimeTelemetryOptions);
|
|
1568
|
+
if (runtime.bytes_read > 0)
|
|
1569
|
+
recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
|
|
1570
|
+
if (runtime.state !== "partial" || !retryableRuntimeContextReason(runtime.reason))
|
|
1571
|
+
break;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
if (runtime.state === "unsupported")
|
|
1575
|
+
return native;
|
|
1576
|
+
return {
|
|
1577
|
+
...native,
|
|
1578
|
+
context: runtimeContextObservation(runtime),
|
|
1579
|
+
context_provenance: {
|
|
1580
|
+
source_event: runtime.state === "observed" ? runtime.source_event : `${input.adapter}.runtime_context`,
|
|
1581
|
+
...(runtime.state === "observed" ? { source_witness: runtime.source_witness } : {}),
|
|
1582
|
+
...(input.adapterVersion ? { runtime_version: input.adapterVersion } : {}),
|
|
1583
|
+
attestation: runtime.state === "observed" ? runtime.attestation : "derived",
|
|
1584
|
+
confidence: runtime.state === "observed" ? runtime.confidence : "high",
|
|
1585
|
+
},
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Resolve Codex's rollout once, retain it in owner-only producer state, and
|
|
1590
|
+
* verify the cached path against the native session before every reuse. Public
|
|
1591
|
+
* events receive only numeric telemetry and an opaque source witness.
|
|
1592
|
+
*/
|
|
1593
|
+
function runtimeTranscriptPath(input, state) {
|
|
1594
|
+
if (input.adapter !== "codex")
|
|
1595
|
+
return input.payload.transcript_path;
|
|
1596
|
+
const nativeSessionId = input.payload.session_id ?? input.payload.conversation_id;
|
|
1597
|
+
if (!nativeSessionId)
|
|
1598
|
+
return input.payload.transcript_path;
|
|
1599
|
+
const supplied = input.payload.transcript_path;
|
|
1600
|
+
if (supplied) {
|
|
1601
|
+
const verified = discoverCodexSessionTranscript(nativeSessionId, supplied, input.runtimeTelemetryOptions);
|
|
1602
|
+
if (verified)
|
|
1603
|
+
state.runtime_transcript_path = verified;
|
|
1604
|
+
// Preserve a supplied mismatch so the typed reader reports it honestly.
|
|
1605
|
+
return verified ?? supplied;
|
|
1606
|
+
}
|
|
1607
|
+
if (state.runtime_transcript_path) {
|
|
1608
|
+
const verified = discoverCodexSessionTranscript(nativeSessionId, state.runtime_transcript_path, input.runtimeTelemetryOptions);
|
|
1609
|
+
if (verified)
|
|
1610
|
+
return verified;
|
|
1611
|
+
state.runtime_transcript_path = undefined;
|
|
1612
|
+
}
|
|
1613
|
+
const discovered = discoverCodexSessionTranscript(nativeSessionId, undefined, input.runtimeTelemetryOptions);
|
|
1614
|
+
if (discovered)
|
|
1615
|
+
state.runtime_transcript_path = discovered;
|
|
1616
|
+
return discovered;
|
|
1617
|
+
}
|
|
1618
|
+
function runtimeContextObservation(runtime) {
|
|
1619
|
+
if (runtime.state === "observed") {
|
|
1620
|
+
if ("used_percent" in runtime) {
|
|
1621
|
+
return {
|
|
1622
|
+
state: "observed",
|
|
1623
|
+
value: {
|
|
1624
|
+
used_percent: runtime.used_percent,
|
|
1625
|
+
remaining_percent: Math.max(0, 100 - runtime.used_percent),
|
|
1626
|
+
measured_at: runtime.measured_at,
|
|
1627
|
+
method: runtime.method,
|
|
1628
|
+
},
|
|
1629
|
+
attestation: runtime.attestation,
|
|
1630
|
+
confidence: runtime.confidence,
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
return {
|
|
1634
|
+
state: "observed",
|
|
1635
|
+
value: {
|
|
1636
|
+
used_tokens: runtime.used_tokens,
|
|
1637
|
+
limit_tokens: runtime.limit_tokens,
|
|
1638
|
+
remaining_tokens: Math.max(0, runtime.limit_tokens - runtime.used_tokens),
|
|
1639
|
+
measured_at: runtime.measured_at,
|
|
1640
|
+
method: runtime.method,
|
|
1641
|
+
},
|
|
1642
|
+
attestation: runtime.attestation,
|
|
1643
|
+
confidence: runtime.confidence,
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
return {
|
|
1647
|
+
state: "expected_but_missing",
|
|
1648
|
+
capability: "context_usage",
|
|
1649
|
+
reason: runtime.reason,
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
/** Seed the change-detection baseline from a committed session.started. */
|
|
1653
|
+
function seedAttestedTuning(state, event) {
|
|
1654
|
+
const attestation = event.payload
|
|
1655
|
+
.runtime_attestation;
|
|
1656
|
+
if (!attestation)
|
|
1657
|
+
return;
|
|
1658
|
+
const tuning = attestation.tuning;
|
|
1659
|
+
state.last_attested_tuning =
|
|
1660
|
+
tuning?.state === "observed"
|
|
1661
|
+
? {
|
|
1662
|
+
...(tuning.value?.effort ? { effort: tuning.value.effort } : {}),
|
|
1663
|
+
...(tuning.value?.speed ? { speed: tuning.value.speed } : {}),
|
|
1664
|
+
}
|
|
1665
|
+
: {};
|
|
1666
|
+
const model = attestation.model;
|
|
1667
|
+
if (model.state === "observed") {
|
|
1668
|
+
state.last_attested_model = { provider: model.value.provider, id: model.value.id };
|
|
1669
|
+
}
|
|
1670
|
+
state.last_attested_model_observation = model;
|
|
1671
|
+
state.last_attested_tuning_observation = tuning;
|
|
1672
|
+
state.last_attested_telemetry = attestation.telemetry;
|
|
1673
|
+
}
|
|
1674
|
+
/**
|
|
1675
|
+
* Emit `session.attestation_changed` when the observed tuning moves.
|
|
1676
|
+
*
|
|
1677
|
+
* Detection channels are deliberately cheap: CC stamps `effort.level` on
|
|
1678
|
+
* every tool hook and Stop (zero I/O), and Codex tuning is read from the
|
|
1679
|
+
* rollout only at turn terminals, where the context enrichment already pays
|
|
1680
|
+
* for a bounded tail read. A pre-upgrade state file (no baseline) seeds
|
|
1681
|
+
* silently so existing sessions do not fire a spurious change on their next
|
|
1682
|
+
* tool event; a fresh session's baseline comes from its session.started.
|
|
1683
|
+
*/
|
|
1684
|
+
function maybeAttestTuningChange(input, state, path, rootId) {
|
|
1685
|
+
if (input.signal !== "pre-tool-use" &&
|
|
1686
|
+
input.signal !== "post-tool-use" &&
|
|
1687
|
+
input.signal !== "stop") {
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
if (state.terminal)
|
|
1691
|
+
return;
|
|
1692
|
+
let candidate;
|
|
1693
|
+
let attestationSource = "native";
|
|
1694
|
+
let sourceEvent = `${input.adapter}.effort-payload`;
|
|
1695
|
+
if (input.adapter === "claude-code" || input.adapter === "cursor") {
|
|
1696
|
+
if (!input.payload.effort)
|
|
1697
|
+
return;
|
|
1698
|
+
candidate = { effort: input.payload.effort };
|
|
1699
|
+
}
|
|
1700
|
+
else if (input.adapter === "codex" &&
|
|
1701
|
+
(input.signal === "stop" ||
|
|
1702
|
+
// Early probe: without it, a Codex card shows no effort until the first
|
|
1703
|
+
// turn terminal. One rollout read per turn while effort is unknown.
|
|
1704
|
+
(input.signal === "post-tool-use" &&
|
|
1705
|
+
!state.last_attested_tuning?.effort &&
|
|
1706
|
+
state.current_turn_id !== undefined &&
|
|
1707
|
+
state.tuning_probe_turn_id !== state.current_turn_id))) {
|
|
1708
|
+
if (input.signal === "post-tool-use")
|
|
1709
|
+
state.tuning_probe_turn_id = state.current_turn_id;
|
|
1710
|
+
const runtime = readRuntimeTuning({
|
|
1711
|
+
adapter: "codex",
|
|
1712
|
+
session_id: input.payload.session_id ?? input.payload.conversation_id,
|
|
1713
|
+
transcript_path: runtimeTranscriptPath(input, state),
|
|
1714
|
+
}, input.runtimeTelemetryOptions);
|
|
1715
|
+
if (runtime.bytes_read > 0)
|
|
1716
|
+
recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
|
|
1717
|
+
if (runtime.state !== "observed")
|
|
1718
|
+
return;
|
|
1719
|
+
candidate = {
|
|
1720
|
+
...(runtime.effort ? { effort: runtime.effort } : {}),
|
|
1721
|
+
...(runtime.speed ? { speed: runtime.speed } : {}),
|
|
1722
|
+
...(runtime.model ? { model: runtime.model } : {}),
|
|
1723
|
+
};
|
|
1724
|
+
attestationSource = "derived";
|
|
1725
|
+
sourceEvent = runtime.source_event;
|
|
1726
|
+
}
|
|
1727
|
+
else {
|
|
1728
|
+
return;
|
|
1729
|
+
}
|
|
1730
|
+
const baseline = state.last_attested_tuning;
|
|
1731
|
+
const next = { effort: candidate.effort, speed: candidate.speed ?? baseline?.speed };
|
|
1732
|
+
if (baseline === undefined || state.last_attested_telemetry === undefined) {
|
|
1733
|
+
// Pre-upgrade state: adopt without emitting; there is no attested prior.
|
|
1734
|
+
state.last_attested_tuning = { ...(next.effort ? { effort: next.effort } : {}) };
|
|
1735
|
+
if (next.speed)
|
|
1736
|
+
state.last_attested_tuning.speed = next.speed;
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
if (baseline.effort === next.effort && (candidate.speed ?? baseline.speed) === baseline.speed) {
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
// CC change detection rides the payload; the paired transcript row also
|
|
1743
|
+
// carries speed and the (possibly swapped) model, so refresh from it.
|
|
1744
|
+
if (input.adapter === "claude-code") {
|
|
1745
|
+
const runtime = readRuntimeTuning({
|
|
1746
|
+
adapter: "claude-code",
|
|
1747
|
+
transcript_path: input.payload.transcript_path,
|
|
1748
|
+
});
|
|
1749
|
+
if (runtime.bytes_read > 0)
|
|
1750
|
+
recordRuntimeTelemetryTiming(state, runtime.io_duration_ms);
|
|
1751
|
+
if (runtime.state === "observed" && runtime.effort === candidate.effort) {
|
|
1752
|
+
if (runtime.speed)
|
|
1753
|
+
candidate.speed = runtime.speed;
|
|
1754
|
+
if (runtime.model)
|
|
1755
|
+
candidate.model = runtime.model;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
const model = candidate.model
|
|
1759
|
+
? {
|
|
1760
|
+
state: "observed",
|
|
1761
|
+
value: { provider: modelProviderFor(input.adapter), id: safeRole(candidate.model) },
|
|
1762
|
+
attestation: "derived",
|
|
1763
|
+
confidence: "high",
|
|
1764
|
+
}
|
|
1765
|
+
: state.last_attested_model
|
|
1766
|
+
? {
|
|
1767
|
+
state: "observed",
|
|
1768
|
+
value: state.last_attested_model,
|
|
1769
|
+
attestation: "derived",
|
|
1770
|
+
confidence: "high",
|
|
1771
|
+
}
|
|
1772
|
+
: { state: "expected_but_missing", capability: "model_identity", reason: "not_reported" };
|
|
1773
|
+
const tuning = candidate.effort || candidate.speed
|
|
1774
|
+
? {
|
|
1775
|
+
state: "observed",
|
|
1776
|
+
value: {
|
|
1777
|
+
...(candidate.effort ? { effort: candidate.effort } : {}),
|
|
1778
|
+
...(candidate.speed ? { speed: candidate.speed } : {}),
|
|
1779
|
+
},
|
|
1780
|
+
attestation: attestationSource,
|
|
1781
|
+
confidence: "exact",
|
|
1782
|
+
}
|
|
1783
|
+
: { state: "unsupported", capability: "effort_selection" };
|
|
1784
|
+
commitRuntimeAttestationChange(input, state, path, rootId, {
|
|
1785
|
+
model,
|
|
1786
|
+
tuning,
|
|
1787
|
+
telemetry: state.last_attested_telemetry,
|
|
1788
|
+
reason: "runtime_tuning_changed",
|
|
1789
|
+
source_event: sourceEvent,
|
|
1790
|
+
attestation: attestationSource,
|
|
1791
|
+
confidence: attestationSource === "native" ? "exact" : "high",
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
function commitRuntimeAttestationChange(input, state, path, rootId, change) {
|
|
1795
|
+
const priorAttestationId = state.attestation_id;
|
|
1796
|
+
const nextAttestationId = attestationIdV3();
|
|
1797
|
+
const eventId = eventIdV3();
|
|
1798
|
+
const runtimeAttestation = {
|
|
1799
|
+
attestation_id: nextAttestationId,
|
|
1800
|
+
generation_id: state.generation_id,
|
|
1801
|
+
adapter: {
|
|
1802
|
+
state: "observed",
|
|
1803
|
+
value: {
|
|
1804
|
+
id: input.adapter,
|
|
1805
|
+
...(input.adapterVersion ? { version: input.adapterVersion } : {}),
|
|
1806
|
+
},
|
|
1131
1807
|
attestation: "native",
|
|
1132
1808
|
confidence: "exact",
|
|
1809
|
+
},
|
|
1810
|
+
harness: {
|
|
1811
|
+
state: "observed",
|
|
1812
|
+
value: {
|
|
1813
|
+
id: input.adapter,
|
|
1814
|
+
...(input.harnessVersion ? { version: input.harnessVersion } : {}),
|
|
1815
|
+
},
|
|
1816
|
+
attestation: "native",
|
|
1817
|
+
confidence: "exact",
|
|
1818
|
+
},
|
|
1819
|
+
model: change.model,
|
|
1820
|
+
tuning: change.tuning,
|
|
1821
|
+
telemetry: change.telemetry,
|
|
1822
|
+
capability_profile: state.capability_profile,
|
|
1823
|
+
declared_by_event_id: eventId,
|
|
1824
|
+
};
|
|
1825
|
+
const event = buildEventV3("session.attestation_changed", {
|
|
1826
|
+
event_id: eventId,
|
|
1827
|
+
producer: {
|
|
1828
|
+
producer_id: input.producer_id,
|
|
1829
|
+
boot_id: state.boot_id,
|
|
1830
|
+
sequence: state.next_sequence,
|
|
1831
|
+
component: "agent-hook",
|
|
1832
|
+
build_id: input.build_id,
|
|
1833
|
+
platform: input.platform,
|
|
1834
|
+
...(input.bridge ? { bridge: input.bridge } : {}),
|
|
1835
|
+
},
|
|
1836
|
+
scope: {
|
|
1837
|
+
root_id: rootId,
|
|
1838
|
+
instance_id: state.instance_id,
|
|
1839
|
+
session_id: state.session_id,
|
|
1840
|
+
generation_id: state.generation_id,
|
|
1841
|
+
...(input.run_id ? { run_id: input.run_id } : {}),
|
|
1842
|
+
...(input.workflow_id ? { workflow_id: input.workflow_id } : {}),
|
|
1843
|
+
...(input.workflow_agent_id ? { workflow_agent_id: input.workflow_agent_id } : {}),
|
|
1844
|
+
},
|
|
1845
|
+
attestation_id: nextAttestationId,
|
|
1846
|
+
links: { caused_by: state.last_event_id ? [state.last_event_id] : [] },
|
|
1847
|
+
provenance: {
|
|
1848
|
+
source_event: safeRole(change.source_event),
|
|
1849
|
+
attestation: change.attestation,
|
|
1850
|
+
confidence: change.confidence,
|
|
1133
1851
|
attribution: {
|
|
1134
1852
|
method: "native_payload",
|
|
1135
1853
|
state: "verified",
|
|
1136
1854
|
subject_instance_id: state.instance_id,
|
|
1137
1855
|
},
|
|
1138
1856
|
},
|
|
1139
|
-
observed_at:
|
|
1140
|
-
? measurement.value.measured_at
|
|
1141
|
-
: turnTerminal.time.observed_at,
|
|
1857
|
+
observed_at: input.observed_at ?? new Date().toISOString(),
|
|
1142
1858
|
monotonic_ns: orderedEventMonotonic(state, input.monotonic_ns),
|
|
1143
1859
|
clock_id: state.clock_id,
|
|
1144
1860
|
payload: {
|
|
1145
|
-
|
|
1861
|
+
prior_attestation_id: priorAttestationId,
|
|
1862
|
+
runtime_attestation: runtimeAttestation,
|
|
1863
|
+
reason: change.reason,
|
|
1146
1864
|
},
|
|
1147
1865
|
});
|
|
1866
|
+
// Mutate BEFORE the commit: commitEventLocked publishes the state file, so
|
|
1867
|
+
// post-commit mutations would be dropped by the next signal's fresh read.
|
|
1868
|
+
// A crash between publishes replays the pending event against a state that
|
|
1869
|
+
// already carries the new attestation id, which is the id the event declares.
|
|
1870
|
+
state.attestation_id = nextAttestationId;
|
|
1871
|
+
state.last_attested_model_observation = change.model;
|
|
1872
|
+
state.last_attested_tuning_observation = change.tuning;
|
|
1873
|
+
state.last_attested_telemetry = change.telemetry;
|
|
1874
|
+
state.last_attested_model =
|
|
1875
|
+
change.model.state === "observed" ? { ...change.model.value } : undefined;
|
|
1876
|
+
state.last_attested_tuning = change.tuning.state === "observed" ? { ...change.tuning.value } : {};
|
|
1148
1877
|
commitEventLocked(input, state, path, event);
|
|
1149
1878
|
}
|
|
1879
|
+
function modelProviderFor(adapter) {
|
|
1880
|
+
if (adapter === "claude-code")
|
|
1881
|
+
return "anthropic";
|
|
1882
|
+
if (adapter === "codex")
|
|
1883
|
+
return "openai";
|
|
1884
|
+
return "cursor";
|
|
1885
|
+
}
|
|
1886
|
+
function recordRuntimeTelemetryTiming(state, durationMs) {
|
|
1887
|
+
const duration = Math.max(0, Math.ceil(durationMs));
|
|
1888
|
+
if (!Number.isSafeInteger(duration))
|
|
1889
|
+
return;
|
|
1890
|
+
state.turn_harness = {
|
|
1891
|
+
hook_time_ms: state.turn_harness.hook_time_ms + duration,
|
|
1892
|
+
hook_count: state.turn_harness.hook_count + 1,
|
|
1893
|
+
slowest_hook: duration >= state.turn_harness.slowest_hook_ms
|
|
1894
|
+
? "runtime-context"
|
|
1895
|
+
: state.turn_harness.slowest_hook,
|
|
1896
|
+
slowest_hook_ms: Math.max(duration, state.turn_harness.slowest_hook_ms),
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1150
1899
|
function commitCapabilityDriftEvents(input, state, path, rootId) {
|
|
1151
1900
|
const read = readLedgerV3(input.coordRoot);
|
|
1152
1901
|
if (!read.complete)
|
|
@@ -1336,6 +2085,34 @@ function isCursorPromptBootstrap(input) {
|
|
|
1336
2085
|
(input.payload.conversation_id !== undefined || input.payload.session_id !== undefined) &&
|
|
1337
2086
|
input.payload.turn_id !== undefined);
|
|
1338
2087
|
}
|
|
2088
|
+
/** Privacy-safe environment and recovery provenance for Codex mid-flight
|
|
2089
|
+
* onboarding. WSLENV values are never recorded, only normalized variable
|
|
2090
|
+
* names, and the native session identifier itself remains fingerprinted. */
|
|
2091
|
+
export function codexMidFlightDiagnosticContext(payload, env = process.env) {
|
|
2092
|
+
const wslenv = env.WSLENV?.trim() ?? "";
|
|
2093
|
+
const wslenvNames = [
|
|
2094
|
+
...new Set(wslenv
|
|
2095
|
+
.split(":")
|
|
2096
|
+
.map((entry) => entry.split("/", 1)[0]?.trim() ?? "")
|
|
2097
|
+
.filter((name) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(name))),
|
|
2098
|
+
]
|
|
2099
|
+
.sort()
|
|
2100
|
+
.join(":")
|
|
2101
|
+
.slice(0, 512);
|
|
2102
|
+
const identityRecoverySource = payload.session_id
|
|
2103
|
+
? "native_session_id"
|
|
2104
|
+
: payload.conversation_id
|
|
2105
|
+
? "native_conversation_id"
|
|
2106
|
+
: payload.agent_id
|
|
2107
|
+
? "native_agent_id"
|
|
2108
|
+
: "unavailable";
|
|
2109
|
+
return {
|
|
2110
|
+
thread_id_present: Boolean(env.CODEX_THREAD_ID?.trim()),
|
|
2111
|
+
wslenv_present: wslenv.length > 0,
|
|
2112
|
+
wslenv_names: wslenvNames,
|
|
2113
|
+
identity_recovery_source: identityRecoverySource,
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
1339
2116
|
function suppressClosedSpanSignal(input, sessionHash, category) {
|
|
1340
2117
|
writeProducerDiagnosticV3(input.coordRoot, category, {
|
|
1341
2118
|
adapter: input.adapter,
|
|
@@ -1357,6 +2134,13 @@ export function recordApprovedSessionEndV3(input) {
|
|
|
1357
2134
|
if (control.state !== input.mode) {
|
|
1358
2135
|
return { state: "gate_closed", reason: control.state };
|
|
1359
2136
|
}
|
|
2137
|
+
input = {
|
|
2138
|
+
...input,
|
|
2139
|
+
writerOptions: {
|
|
2140
|
+
...input.writerOptions,
|
|
2141
|
+
expectedGenesisId: control.genesis.event.payload.genesis_id,
|
|
2142
|
+
},
|
|
2143
|
+
};
|
|
1360
2144
|
const matches = listHookProducerStateRecordsV3(input.coordRoot, { includeTerminal: true }).filter(({ state }) => state.instance_id === input.instance_id && state.generation_id === input.generation_id);
|
|
1361
2145
|
if (matches.length !== 1) {
|
|
1362
2146
|
return {
|
|
@@ -1390,6 +2174,7 @@ export function recordApprovedSessionEndV3(input) {
|
|
|
1390
2174
|
}
|
|
1391
2175
|
const rootId = control.genesis.event.scope.root_id;
|
|
1392
2176
|
const context = fingerprintContextV3(input.coordRoot, rootId, state.generation_id, state.privacy_epoch_id);
|
|
2177
|
+
reconcilePendingRuntimeContextsBeforeApprovedEnd(input, state, record.path, rootId, context);
|
|
1393
2178
|
const expected = [
|
|
1394
2179
|
"session_started",
|
|
1395
2180
|
"turn_closed",
|
|
@@ -1482,6 +2267,13 @@ export function salvageOpenSpansV3(input) {
|
|
|
1482
2267
|
if (control.state !== input.mode) {
|
|
1483
2268
|
return { state: "gate_closed", reason: control.state };
|
|
1484
2269
|
}
|
|
2270
|
+
input = {
|
|
2271
|
+
...input,
|
|
2272
|
+
writerOptions: {
|
|
2273
|
+
...input.writerOptions,
|
|
2274
|
+
expectedGenesisId: control.genesis.event.payload.genesis_id,
|
|
2275
|
+
},
|
|
2276
|
+
};
|
|
1485
2277
|
const matches = listHookProducerStateRecordsV3(input.coordRoot).filter(({ state }) => state.instance_id === input.instance_id && state.generation_id === input.generation_id);
|
|
1486
2278
|
if (matches.length !== 1) {
|
|
1487
2279
|
return {
|
|
@@ -1568,6 +2360,10 @@ export function listHookProducerStateRecordsV3(coordRoot, options = {}) {
|
|
|
1568
2360
|
for (const name of readdirSync(directory).filter((entry) => /^hid_[a-f0-9]{64}\.json$/.test(entry))) {
|
|
1569
2361
|
const path = join(directory, name);
|
|
1570
2362
|
const state = readProducerState(path);
|
|
2363
|
+
// Skip authorities left behind by a replaced epoch: their sequences and
|
|
2364
|
+
// causal links belong to the archived ledger, not this one.
|
|
2365
|
+
if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id)
|
|
2366
|
+
continue;
|
|
1571
2367
|
if (!options.includeTerminal && state.terminal)
|
|
1572
2368
|
continue;
|
|
1573
2369
|
records.push({ path, modified_at_ms: lstatSync(path).mtimeMs, state });
|
|
@@ -1612,7 +2408,66 @@ export function readHookProducerStateV3(coordRoot, adapter, nativeSessionId) {
|
|
|
1612
2408
|
const context = fingerprintContextV3(coordRoot, rootId, undefined, control.genesis.profile.privacy_key_epoch);
|
|
1613
2409
|
const sessionHash = normalizeNativeIdV3(context, `${adapter}.session`, nativeSessionId);
|
|
1614
2410
|
const path = producerStatePath(coordRoot, adapter, sessionHash);
|
|
1615
|
-
|
|
2411
|
+
if (!existsSync(path))
|
|
2412
|
+
return undefined;
|
|
2413
|
+
const state = readProducerState(path);
|
|
2414
|
+
// A state left behind by a replaced epoch is not this epoch's authority.
|
|
2415
|
+
return state.epoch_genesis_id === control.genesis.event.payload.genesis_id ? state : undefined;
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Retry one Codex session's owner-only context join without replaying its Stop
|
|
2419
|
+
* signal. Codex appends `task_complete` only after the synchronous Stop hook
|
|
2420
|
+
* exits, so this is invoked by a bounded detached worker after that exit.
|
|
2421
|
+
*/
|
|
2422
|
+
export function reconcilePendingRuntimeContextV3(input) {
|
|
2423
|
+
const control = readEventV3ControlState(input.coordRoot);
|
|
2424
|
+
if (control.state !== input.mode)
|
|
2425
|
+
return { state: "gate_closed" };
|
|
2426
|
+
if (control.state !== "candidate" && control.state !== "active") {
|
|
2427
|
+
return { state: "gate_closed" };
|
|
2428
|
+
}
|
|
2429
|
+
const rootId = control.genesis.event.scope.root_id;
|
|
2430
|
+
const rootContext = fingerprintContextV3(input.coordRoot, rootId, undefined, control.genesis.profile.privacy_key_epoch);
|
|
2431
|
+
const sessionHash = normalizeNativeIdV3(rootContext, "codex.session", input.nativeSessionId);
|
|
2432
|
+
const path = producerStatePath(input.coordRoot, "codex", sessionHash);
|
|
2433
|
+
if (!existsSync(path))
|
|
2434
|
+
return { state: "missing" };
|
|
2435
|
+
const lease = acquireStateLeaseWithRetry(input.coordRoot, path, STATE_LEASE_RETRY_ATTEMPTS);
|
|
2436
|
+
if (!lease)
|
|
2437
|
+
return { state: "busy" };
|
|
2438
|
+
try {
|
|
2439
|
+
const state = readProducerState(path);
|
|
2440
|
+
if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id) {
|
|
2441
|
+
// The pending contexts belong to a replaced epoch; its archive already
|
|
2442
|
+
// holds everything this producer durably recorded.
|
|
2443
|
+
return { state: "missing" };
|
|
2444
|
+
}
|
|
2445
|
+
if (state.adapter !== "codex" || !state.pending_runtime_contexts?.length) {
|
|
2446
|
+
return { state: "not_pending" };
|
|
2447
|
+
}
|
|
2448
|
+
const context = fingerprintContextV3(input.coordRoot, rootId, state.generation_id, state.privacy_epoch_id);
|
|
2449
|
+
reconcilePendingRuntimeContexts({
|
|
2450
|
+
coordRoot: input.coordRoot,
|
|
2451
|
+
mode: input.mode,
|
|
2452
|
+
signal: "stop",
|
|
2453
|
+
payload: { raw: {}, session_id: input.nativeSessionId },
|
|
2454
|
+
adapter: "codex",
|
|
2455
|
+
instance_id: state.instance_id,
|
|
2456
|
+
producer_id: input.producer_id,
|
|
2457
|
+
build_id: input.build_id,
|
|
2458
|
+
platform: input.platform,
|
|
2459
|
+
observed_at: new Date().toISOString(),
|
|
2460
|
+
runtimeTelemetryOptions: input.runtimeTelemetryOptions,
|
|
2461
|
+
writerOptions: {
|
|
2462
|
+
...input.writerOptions,
|
|
2463
|
+
expectedGenesisId: control.genesis.event.payload.genesis_id,
|
|
2464
|
+
},
|
|
2465
|
+
}, state, path, rootId, context, { deferRetryLimit: true, finalAttempt: input.finalAttempt });
|
|
2466
|
+
return state.pending_runtime_contexts?.length ? { state: "pending" } : { state: "settled" };
|
|
2467
|
+
}
|
|
2468
|
+
finally {
|
|
2469
|
+
lease.release();
|
|
2470
|
+
}
|
|
1616
2471
|
}
|
|
1617
2472
|
/** Resolve one terminal producer only when native session and instance identity agree. */
|
|
1618
2473
|
export function readTerminalHookProducerStateV3(coordRoot, nativeSessionId, instanceId) {
|
|
@@ -1639,13 +2494,30 @@ export function readHookProducerStateByInstanceV3(coordRoot, instanceId) {
|
|
|
1639
2494
|
}
|
|
1640
2495
|
for (const name of readdirSync(directory).filter((entry) => /^hid_[a-f0-9]{64}\.json$/.test(entry))) {
|
|
1641
2496
|
const state = readProducerState(join(directory, name));
|
|
2497
|
+
if (state.epoch_genesis_id !== control.genesis.event.payload.genesis_id)
|
|
2498
|
+
continue;
|
|
1642
2499
|
if (state.instance_id === instanceId && !state.terminal)
|
|
1643
2500
|
matches.push(state);
|
|
1644
2501
|
}
|
|
1645
2502
|
}
|
|
1646
2503
|
return matches.length === 1 ? matches[0] : undefined;
|
|
1647
2504
|
}
|
|
1648
|
-
|
|
2505
|
+
/**
|
|
2506
|
+
* Join a coordination actor to its hook producer.
|
|
2507
|
+
*
|
|
2508
|
+
* Native subagent commands can retain the parent's session id even after the
|
|
2509
|
+
* child has its own canonical generation. Prefer the native session join, but
|
|
2510
|
+
* when that points at a different instance accept only one exact live
|
|
2511
|
+
* instance match for the same adapter.
|
|
2512
|
+
*/
|
|
2513
|
+
export function readJoinableHookProducerStateV3(coordRoot, adapter, nativeSessionId, instanceId) {
|
|
2514
|
+
const direct = readHookProducerStateV3(coordRoot, adapter, nativeSessionId);
|
|
2515
|
+
if (direct?.instance_id === instanceId && !direct.terminal)
|
|
2516
|
+
return direct;
|
|
2517
|
+
const byInstance = readHookProducerStateByInstanceV3(coordRoot, instanceId);
|
|
2518
|
+
return byInstance?.adapter === adapter && !byInstance.terminal ? byInstance : undefined;
|
|
2519
|
+
}
|
|
2520
|
+
function newProducerState(input, sessionId, epochId, boundaryEventId, genesisId) {
|
|
1649
2521
|
const bootId = `boot_${randomUUID()}`;
|
|
1650
2522
|
return {
|
|
1651
2523
|
format: STATE_FORMAT,
|
|
@@ -1653,11 +2525,12 @@ function newProducerState(input, sessionId, epochId, boundaryEventId) {
|
|
|
1653
2525
|
adapter: input.adapter,
|
|
1654
2526
|
instance_id: input.instance_id,
|
|
1655
2527
|
session_id: sessionId,
|
|
1656
|
-
generation_id: generationIdV3(),
|
|
2528
|
+
generation_id: input.delegated_child?.generation_id ?? generationIdV3(),
|
|
1657
2529
|
attestation_id: attestationIdV3(),
|
|
1658
2530
|
capability_profile: adapterCapabilityProfileDigestV3(input.adapter),
|
|
1659
2531
|
cursor_mode: input.adapter === "cursor" ? (input.payload.cursor_mode ?? "unknown") : undefined,
|
|
1660
2532
|
privacy_epoch_id: epochId,
|
|
2533
|
+
epoch_genesis_id: genesisId,
|
|
1661
2534
|
boot_id: bootId,
|
|
1662
2535
|
clock_id: clockIdV3(),
|
|
1663
2536
|
next_sequence: 1,
|
|
@@ -1668,6 +2541,7 @@ function newProducerState(input, sessionId, epochId, boundaryEventId) {
|
|
|
1668
2541
|
boot_id: bootId,
|
|
1669
2542
|
clock: signalClock(input),
|
|
1670
2543
|
}),
|
|
2544
|
+
session_start_derivation: input.session_start_derivation,
|
|
1671
2545
|
terminal: false,
|
|
1672
2546
|
spans: [],
|
|
1673
2547
|
delegations: [],
|
|
@@ -1694,10 +2568,12 @@ function applyCommittedEvent(state, event) {
|
|
|
1694
2568
|
if (event.event_type === "session.started") {
|
|
1695
2569
|
state.started_event_id = event.event_id;
|
|
1696
2570
|
state.session_span.open_event_id = event.event_id;
|
|
2571
|
+
seedAttestedTuning(state, event);
|
|
1697
2572
|
}
|
|
1698
2573
|
if (event.event_type === "turn.started") {
|
|
1699
2574
|
const nextTurnId = event.scope.turn_id;
|
|
1700
2575
|
state.current_turn_id = nextTurnId;
|
|
2576
|
+
state.session_start_derivation = undefined;
|
|
1701
2577
|
if (state.tool_call_count_turn_id !== nextTurnId) {
|
|
1702
2578
|
state.tool_call_count = 0;
|
|
1703
2579
|
state.tool_call_count_turn_id = nextTurnId;
|
|
@@ -1773,6 +2649,7 @@ function applyCommittedEvent(state, event) {
|
|
|
1773
2649
|
}
|
|
1774
2650
|
}
|
|
1775
2651
|
state.current_turn_id = undefined;
|
|
2652
|
+
state.current_native_turn_id = undefined;
|
|
1776
2653
|
state.current_turn_span = undefined;
|
|
1777
2654
|
state.tool_call_count = 0;
|
|
1778
2655
|
state.tool_call_count_turn_id = undefined;
|
|
@@ -1918,6 +2795,14 @@ function safeRole(value) {
|
|
|
1918
2795
|
.slice(0, 128);
|
|
1919
2796
|
return /^[a-zA-Z0-9]/.test(normalized) ? normalized : "agent";
|
|
1920
2797
|
}
|
|
2798
|
+
function asLiveInstanceId(nativeInstanceId) {
|
|
2799
|
+
if (/^inst_[a-zA-Z0-9._-]{1,128}$/.test(nativeInstanceId)) {
|
|
2800
|
+
return nativeInstanceId;
|
|
2801
|
+
}
|
|
2802
|
+
if (/^[a-zA-Z0-9._-]{1,128}$/.test(nativeInstanceId))
|
|
2803
|
+
return `inst_${nativeInstanceId}`;
|
|
2804
|
+
return `inst_${createHash("sha256").update(nativeInstanceId.normalize("NFC")).digest("hex")}`;
|
|
2805
|
+
}
|
|
1921
2806
|
function safeTokenOrUndefined(value) {
|
|
1922
2807
|
if (typeof value !== "string")
|
|
1923
2808
|
return undefined;
|
|
@@ -1996,9 +2881,14 @@ function readProducerState(path) {
|
|
|
1996
2881
|
state.waits ??= [];
|
|
1997
2882
|
state.closed_turn_ids ??= [];
|
|
1998
2883
|
state.turn_harness ??= emptyTurnHarnessTiming();
|
|
2884
|
+
if (Array.isArray(state.pending_runtime_contexts) &&
|
|
2885
|
+
state.pending_runtime_contexts.length === 0) {
|
|
2886
|
+
state.pending_runtime_contexts = undefined;
|
|
2887
|
+
}
|
|
1999
2888
|
if (state.adapter === "cursor")
|
|
2000
2889
|
state.cursor_mode ??= "unknown";
|
|
2001
2890
|
const allowedKeys = new Set([
|
|
2891
|
+
"active_runtime_context_probe",
|
|
2002
2892
|
"adapter",
|
|
2003
2893
|
"attestation_id",
|
|
2004
2894
|
"boot_id",
|
|
@@ -2007,20 +2897,32 @@ function readProducerState(path) {
|
|
|
2007
2897
|
"closed_spans",
|
|
2008
2898
|
"closed_turn_ids",
|
|
2009
2899
|
"current_turn_id",
|
|
2900
|
+
"current_native_turn_id",
|
|
2010
2901
|
"current_turn_span",
|
|
2011
2902
|
"cursor_mode",
|
|
2012
2903
|
"delegations",
|
|
2904
|
+
"epoch_genesis_id",
|
|
2013
2905
|
"format",
|
|
2014
2906
|
"format_version",
|
|
2015
2907
|
"generation_id",
|
|
2016
2908
|
"instance_id",
|
|
2909
|
+
"last_attested_model",
|
|
2910
|
+
"last_attested_model_observation",
|
|
2911
|
+
"last_attested_telemetry",
|
|
2912
|
+
"last_attested_tuning",
|
|
2913
|
+
"last_attested_tuning_observation",
|
|
2914
|
+
"last_context_source_witness",
|
|
2915
|
+
"tuning_probe_turn_id",
|
|
2017
2916
|
"last_event_id",
|
|
2018
2917
|
"last_monotonic_ns",
|
|
2019
2918
|
"last_observed_at",
|
|
2020
2919
|
"next_sequence",
|
|
2021
2920
|
"pending",
|
|
2921
|
+
"pending_runtime_contexts",
|
|
2922
|
+
"runtime_transcript_path",
|
|
2022
2923
|
"privacy_epoch_id",
|
|
2023
2924
|
"session_id",
|
|
2925
|
+
"session_start_derivation",
|
|
2024
2926
|
"session_span",
|
|
2025
2927
|
"spans",
|
|
2026
2928
|
"started_event_id",
|
|
@@ -2043,6 +2945,7 @@ function readProducerState(path) {
|
|
|
2043
2945
|
!/^att_[0-9a-f-]{36}$/.test(state.attestation_id) ||
|
|
2044
2946
|
!/^cap_[a-f0-9]{64}$/.test(state.capability_profile) ||
|
|
2045
2947
|
!/^pep_[a-zA-Z0-9._-]+$/.test(state.privacy_epoch_id) ||
|
|
2948
|
+
(state.epoch_genesis_id !== undefined && !/^gex_[0-9a-f-]{36}$/.test(state.epoch_genesis_id)) ||
|
|
2046
2949
|
!/^boot_[a-zA-Z0-9._-]+$/.test(state.boot_id) ||
|
|
2047
2950
|
!/^clk_[0-9a-f-]{36}$/.test(state.clock_id) ||
|
|
2048
2951
|
!Number.isSafeInteger(state.next_sequence) ||
|
|
@@ -2097,11 +3000,32 @@ function readProducerState(path) {
|
|
|
2097
3000
|
!Number.isSafeInteger(state.turn_ordinal) ||
|
|
2098
3001
|
state.turn_ordinal < 0 ||
|
|
2099
3002
|
(state.current_turn_id !== undefined && !/^tid_[a-f0-9]{64}$/.test(state.current_turn_id)) ||
|
|
3003
|
+
(state.current_native_turn_id !== undefined &&
|
|
3004
|
+
(typeof state.current_native_turn_id !== "string" ||
|
|
3005
|
+
state.current_native_turn_id.length === 0 ||
|
|
3006
|
+
state.current_native_turn_id.length > 512)) ||
|
|
2100
3007
|
(state.last_event_id !== undefined && !/^evt_[0-9a-f-]{36}$/.test(state.last_event_id)) ||
|
|
2101
3008
|
(state.last_monotonic_ns !== undefined && !/^\d+$/.test(state.last_monotonic_ns)) ||
|
|
2102
3009
|
(state.last_observed_at !== undefined &&
|
|
2103
3010
|
!Number.isFinite(Date.parse(state.last_observed_at))) ||
|
|
2104
3011
|
(state.started_event_id !== undefined && !/^evt_[0-9a-f-]{36}$/.test(state.started_event_id)) ||
|
|
3012
|
+
(state.session_start_derivation !== undefined &&
|
|
3013
|
+
state.session_start_derivation !== "approved_lifecycle_reopen" &&
|
|
3014
|
+
state.session_start_derivation !== "validated_current_session_heal") ||
|
|
3015
|
+
(state.pending_runtime_contexts !== undefined &&
|
|
3016
|
+
(!Array.isArray(state.pending_runtime_contexts) ||
|
|
3017
|
+
state.pending_runtime_contexts.length === 0 ||
|
|
3018
|
+
state.pending_runtime_contexts.length > PENDING_RUNTIME_CONTEXT_CAP ||
|
|
3019
|
+
state.pending_runtime_contexts.some((pending) => !validPendingRuntimeContext(pending)))) ||
|
|
3020
|
+
(state.active_runtime_context_probe !== undefined &&
|
|
3021
|
+
!validActiveRuntimeContextProbe(state.active_runtime_context_probe)) ||
|
|
3022
|
+
(state.last_context_source_witness !== undefined &&
|
|
3023
|
+
!/^[a-f0-9]{64}$/.test(state.last_context_source_witness)) ||
|
|
3024
|
+
(state.runtime_transcript_path !== undefined &&
|
|
3025
|
+
(typeof state.runtime_transcript_path !== "string" ||
|
|
3026
|
+
state.runtime_transcript_path.length === 0 ||
|
|
3027
|
+
state.runtime_transcript_path.length > 4096 ||
|
|
3028
|
+
state.runtime_transcript_path.includes("\0"))) ||
|
|
2105
3029
|
(state.pending?.source_id !== undefined &&
|
|
2106
3030
|
!/^hid_[a-f0-9]{64}$/.test(state.pending.source_id)) ||
|
|
2107
3031
|
(state.pending && !validateEventV3(state.pending.event).ok)) {
|
|
@@ -2163,6 +3087,47 @@ function validTurnHarnessTiming(value) {
|
|
|
2163
3087
|
(value.slowest_hook === undefined ||
|
|
2164
3088
|
/^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(value.slowest_hook)));
|
|
2165
3089
|
}
|
|
3090
|
+
function validPendingRuntimeContext(value) {
|
|
3091
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3092
|
+
return false;
|
|
3093
|
+
const pending = value;
|
|
3094
|
+
return (typeof pending.terminal_event_id === "string" &&
|
|
3095
|
+
/^evt_[0-9a-f-]{36}$/.test(pending.terminal_event_id) &&
|
|
3096
|
+
typeof pending.terminal_observed_at === "string" &&
|
|
3097
|
+
Number.isFinite(Date.parse(pending.terminal_observed_at)) &&
|
|
3098
|
+
typeof pending.turn_id === "string" &&
|
|
3099
|
+
/^tid_[a-f0-9]{64}$/.test(pending.turn_id) &&
|
|
3100
|
+
(pending.run_id === undefined || /^run_[0-9a-f-]{36}$/.test(pending.run_id)) &&
|
|
3101
|
+
(pending.workflow_id === undefined || /^wf_[0-9a-f-]{36}$/.test(pending.workflow_id)) &&
|
|
3102
|
+
(pending.workflow_agent_id === undefined ||
|
|
3103
|
+
/^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(pending.workflow_agent_id)) &&
|
|
3104
|
+
typeof pending.native_session_id === "string" &&
|
|
3105
|
+
pending.native_session_id.length > 0 &&
|
|
3106
|
+
pending.native_session_id.length <= 512 &&
|
|
3107
|
+
typeof pending.native_turn_id === "string" &&
|
|
3108
|
+
pending.native_turn_id.length > 0 &&
|
|
3109
|
+
pending.native_turn_id.length <= 512 &&
|
|
3110
|
+
(pending.transcript_path === undefined ||
|
|
3111
|
+
(typeof pending.transcript_path === "string" &&
|
|
3112
|
+
pending.transcript_path.length > 0 &&
|
|
3113
|
+
pending.transcript_path.length <= 4096)) &&
|
|
3114
|
+
(pending.runtime_version === undefined ||
|
|
3115
|
+
(typeof pending.runtime_version === "string" &&
|
|
3116
|
+
/^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(pending.runtime_version))) &&
|
|
3117
|
+
Number.isSafeInteger(pending.attempts) &&
|
|
3118
|
+
pending.attempts >= 0 &&
|
|
3119
|
+
pending.attempts < RUNTIME_CONTEXT_RETRY_LIMIT);
|
|
3120
|
+
}
|
|
3121
|
+
function validActiveRuntimeContextProbe(value) {
|
|
3122
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3123
|
+
return false;
|
|
3124
|
+
const probe = value;
|
|
3125
|
+
return (typeof probe.turn_id === "string" &&
|
|
3126
|
+
/^tid_[a-f0-9]{64}$/.test(probe.turn_id) &&
|
|
3127
|
+
typeof probe.attempted_at === "string" &&
|
|
3128
|
+
Number.isFinite(Date.parse(probe.attempted_at)) &&
|
|
3129
|
+
(probe.boundary === undefined || probe.boundary === "tool_completed"));
|
|
3130
|
+
}
|
|
2166
3131
|
function pidIsAlive(pid) {
|
|
2167
3132
|
if (!Number.isSafeInteger(pid) || pid < 1)
|
|
2168
3133
|
return false;
|