harnery 0.33.0 → 0.34.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.map +1 -1
- package/dist/commander.js +4 -0
- package/dist/commands/adapter.js +2 -2
- package/dist/commands/agents.d.ts +144 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +1220 -588
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +7 -6
- package/dist/commands/backup.d.ts +1 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +29 -16
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +234 -12
- package/dist/commands/checkpoint.d.ts.map +1 -1
- package/dist/commands/checkpoint.js +3 -2
- package/dist/commands/claude-desktop.d.ts +1 -1
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +3 -74
- package/dist/commands/context.js +1 -6
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +22 -38
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +91 -28
- package/dist/commands/doctor.js +10 -1
- package/dist/commands/events.d.ts +5 -0
- package/dist/commands/events.d.ts.map +1 -0
- package/dist/commands/events.js +189 -0
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +13 -4
- package/dist/commands/init.d.ts +9 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +223 -51
- package/dist/commands/journal.d.ts.map +1 -1
- package/dist/commands/journal.js +4 -13
- package/dist/commands/ledger-v3.d.ts +5 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -0
- package/dist/commands/ledger-v3.js +91 -0
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +11 -5
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +1 -1
- package/dist/commands/web.d.ts +6 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +67 -7
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +22 -5
- package/dist/core/adapter.d.ts +5 -0
- package/dist/core/adapter.d.ts.map +1 -0
- package/dist/core/adapter.js +1 -0
- package/dist/core/adapters/attest.d.ts +5 -2
- package/dist/core/adapters/attest.d.ts.map +1 -1
- package/dist/core/adapters/attest.js +8 -3
- package/dist/core/adapters/profiles.d.ts +6 -6
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +4 -4
- package/dist/core/agents/canonical-emit.d.ts +17 -15
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +22 -22
- package/dist/core/agents/cli.js +207 -234
- package/dist/core/agents/codex-archive-v3.d.ts +14 -0
- package/dist/core/agents/codex-archive-v3.d.ts.map +1 -0
- package/dist/core/agents/codex-archive-v3.js +110 -0
- package/dist/core/agents/coord-client.d.ts +19 -81
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +65 -155
- package/dist/core/agents/finalization.d.ts +4 -1
- package/dist/core/agents/finalization.d.ts.map +1 -1
- package/dist/core/agents/finalization.js +89 -32
- package/dist/core/agents/index.d.ts +4 -5
- package/dist/core/agents/index.d.ts.map +1 -1
- package/dist/core/agents/index.js +4 -5
- package/dist/core/agents/live-authority-v3.d.ts +59 -0
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -0
- package/dist/core/agents/live-authority-v3.js +233 -0
- package/dist/core/agents/live-lifecycle-v3.d.ts +20 -0
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -0
- package/dist/core/agents/live-lifecycle-v3.js +91 -0
- package/dist/core/agents/live-observation-v3.d.ts +25 -0
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -0
- package/dist/core/agents/live-observation-v3.js +157 -0
- package/dist/core/agents/render/prompt-context.d.ts +4 -4
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +23 -58
- package/dist/core/agents/render/session-context.d.ts +1 -1
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +8 -32
- package/dist/core/agents/rules/claim-conflict.d.ts +3 -3
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +79 -127
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +3 -18
- package/dist/core/agents/rules/stop-hook.d.ts +9 -50
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +193 -236
- package/dist/core/agents/session-events.d.ts +5 -7
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +127 -95
- package/dist/core/agents/session-finalization-state-v3.d.ts +30 -0
- package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -0
- package/dist/core/agents/session-finalization-state-v3.js +40 -0
- package/dist/core/agents/session-finalizer-v3.d.ts +107 -0
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -0
- package/dist/core/agents/session-finalizer-v3.js +734 -0
- package/dist/core/agents/session-name-display.d.ts +40 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -0
- package/dist/core/agents/session-name-display.js +119 -0
- package/dist/core/agents/state/activity-log.d.ts +3 -3
- package/dist/core/agents/state/activity-log.d.ts.map +1 -1
- package/dist/core/agents/state/activity-log.js +7 -16
- package/dist/core/agents/state/heartbeat-writer.d.ts +23 -55
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +56 -228
- package/dist/core/agents/state/live-coordination-view.d.ts +31 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -0
- package/dist/core/agents/state/live-coordination-view.js +209 -0
- package/dist/core/agents/state/session-state.d.ts +4 -3
- package/dist/core/agents/state/session-state.d.ts.map +1 -1
- package/dist/core/agents/state/session-state.js +18 -9
- package/dist/core/agents/state/stale-sweep.d.ts +1 -1
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +26 -15
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +5 -7
- package/dist/core/config.d.ts +33 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +98 -2
- package/dist/core/context/index.d.ts +1 -4
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +9 -9
- package/dist/core/events/span-parent.d.ts +15 -0
- package/dist/core/events/span-parent.d.ts.map +1 -0
- package/dist/core/events/span-parent.js +34 -0
- package/dist/core/events/v3/advance.d.ts +14 -0
- package/dist/core/events/v3/advance.d.ts.map +1 -0
- package/dist/core/events/v3/advance.js +134 -0
- package/dist/core/events/v3/authority-outbox.d.ts +78 -0
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -0
- package/dist/core/events/v3/authority-outbox.js +399 -0
- package/dist/core/events/v3/base-builder.d.ts +20 -0
- package/dist/core/events/v3/base-builder.d.ts.map +1 -0
- package/dist/core/events/v3/base-builder.js +29 -0
- package/dist/core/events/v3/base-contract.d.ts +7576 -0
- package/dist/core/events/v3/base-contract.d.ts.map +1 -0
- package/dist/core/events/v3/base-contract.js +647 -0
- package/dist/core/events/v3/bootstrap.d.ts +34 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -0
- package/dist/core/events/v3/bootstrap.js +175 -0
- package/dist/core/events/v3/builder.d.ts +20 -0
- package/dist/core/events/v3/builder.d.ts.map +1 -0
- package/dist/core/events/v3/builder.js +28 -0
- package/dist/core/events/v3/canonical.d.ts +31 -0
- package/dist/core/events/v3/canonical.d.ts.map +1 -0
- package/dist/core/events/v3/canonical.js +100 -0
- package/dist/core/events/v3/capabilities.d.ts +31 -0
- package/dist/core/events/v3/capabilities.d.ts.map +1 -0
- package/dist/core/events/v3/capabilities.js +107 -0
- package/dist/core/events/v3/capability-drift.d.ts +22 -0
- package/dist/core/events/v3/capability-drift.d.ts.map +1 -0
- package/dist/core/events/v3/capability-drift.js +134 -0
- package/dist/core/events/v3/catalog.d.ts +38 -0
- package/dist/core/events/v3/catalog.d.ts.map +1 -0
- package/dist/core/events/v3/catalog.js +135 -0
- package/dist/core/events/v3/clock-order.d.ts +34 -0
- package/dist/core/events/v3/clock-order.d.ts.map +1 -0
- package/dist/core/events/v3/clock-order.js +35 -0
- package/dist/core/events/v3/contract.d.ts +171 -0
- package/dist/core/events/v3/contract.d.ts.map +1 -0
- package/dist/core/events/v3/contract.js +180 -0
- package/dist/core/events/v3/control.d.ts +111 -0
- package/dist/core/events/v3/control.d.ts.map +1 -0
- package/dist/core/events/v3/control.js +419 -0
- package/dist/core/events/v3/coordination-view.d.ts +69 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -0
- package/dist/core/events/v3/coordination-view.js +119 -0
- package/dist/core/events/v3/economics.d.ts +77 -0
- package/dist/core/events/v3/economics.d.ts.map +1 -0
- package/dist/core/events/v3/economics.js +274 -0
- package/dist/core/events/v3/finalization-view.d.ts +26 -0
- package/dist/core/events/v3/finalization-view.d.ts.map +1 -0
- package/dist/core/events/v3/finalization-view.js +37 -0
- package/dist/core/events/v3/fingerprint-keys.d.ts +25 -0
- package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -0
- package/dist/core/events/v3/fingerprint-keys.js +217 -0
- package/dist/core/events/v3/generated.d.ts +4 -0
- package/dist/core/events/v3/generated.d.ts.map +1 -0
- package/dist/core/events/v3/generated.js +47 -0
- package/dist/core/events/v3/ids.d.ts +9 -0
- package/dist/core/events/v3/ids.d.ts.map +1 -0
- package/dist/core/events/v3/ids.js +25 -0
- package/dist/core/events/v3/index.d.ts +35 -0
- package/dist/core/events/v3/index.d.ts.map +1 -0
- package/dist/core/events/v3/index.js +33 -0
- package/dist/core/events/v3/latency.d.ts +63 -0
- package/dist/core/events/v3/latency.d.ts.map +1 -0
- package/dist/core/events/v3/latency.js +412 -0
- package/dist/core/events/v3/live-feed.d.ts +45 -0
- package/dist/core/events/v3/live-feed.d.ts.map +1 -0
- package/dist/core/events/v3/live-feed.js +246 -0
- package/dist/core/events/v3/live-observation.d.ts +35 -0
- package/dist/core/events/v3/live-observation.d.ts.map +1 -0
- package/dist/core/events/v3/live-observation.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts +57 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -0
- package/dist/core/events/v3/live-routing.js +107 -0
- package/dist/core/events/v3/producers/command-recorder.d.ts +67 -0
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -0
- package/dist/core/events/v3/producers/command-recorder.js +477 -0
- package/dist/core/events/v3/producers/command.d.ts +50 -0
- package/dist/core/events/v3/producers/command.d.ts.map +1 -0
- package/dist/core/events/v3/producers/command.js +135 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +53 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -0
- package/dist/core/events/v3/producers/coordination-recorder.js +376 -0
- package/dist/core/events/v3/producers/coordination.d.ts +90 -0
- package/dist/core/events/v3/producers/coordination.d.ts.map +1 -0
- package/dist/core/events/v3/producers/coordination.js +229 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +54 -0
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -0
- package/dist/core/events/v3/producers/hook-base.js +424 -0
- package/dist/core/events/v3/producers/hook.d.ts +29 -0
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -0
- package/dist/core/events/v3/producers/hook.js +71 -0
- package/dist/core/events/v3/producers/intake.d.ts +65 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -0
- package/dist/core/events/v3/producers/intake.js +244 -0
- package/dist/core/events/v3/producers/recorder.d.ts +240 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -0
- package/dist/core/events/v3/producers/recorder.js +2176 -0
- package/dist/core/events/v3/projection.d.ts +101 -0
- package/dist/core/events/v3/projection.d.ts.map +1 -0
- package/dist/core/events/v3/projection.js +479 -0
- package/dist/core/events/v3/reader.d.ts +75 -0
- package/dist/core/events/v3/reader.d.ts.map +1 -0
- package/dist/core/events/v3/reader.js +778 -0
- package/dist/core/events/v3/recovery-record.d.ts +47 -0
- package/dist/core/events/v3/recovery-record.d.ts.map +1 -0
- package/dist/core/events/v3/recovery-record.js +167 -0
- package/dist/core/events/v3/recovery.d.ts +22 -0
- package/dist/core/events/v3/recovery.d.ts.map +1 -0
- package/dist/core/events/v3/recovery.js +227 -0
- package/dist/core/events/v3/span-state.d.ts +52 -0
- package/dist/core/events/v3/span-state.d.ts.map +1 -0
- package/dist/core/events/v3/span-state.js +142 -0
- package/dist/core/events/v3/targets.d.ts +23 -0
- package/dist/core/events/v3/targets.d.ts.map +1 -0
- package/dist/core/events/v3/targets.js +134 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +41 -0
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -0
- package/dist/core/events/v3/turn-telemetry.js +168 -0
- package/dist/core/events/v3/validate.d.ts +9 -0
- package/dist/core/events/v3/validate.d.ts.map +1 -0
- package/dist/core/events/v3/validate.js +281 -0
- package/dist/core/events/v3/writer.d.ts +56 -0
- package/dist/core/events/v3/writer.d.ts.map +1 -0
- package/dist/core/events/v3/writer.js +335 -0
- package/dist/core/governor/index.d.ts +1 -1
- package/dist/core/governor/index.d.ts.map +1 -1
- package/dist/core/governor/index.js +1 -1
- package/dist/core/governor/plan-api.d.ts +2 -1
- package/dist/core/governor/plan-api.d.ts.map +1 -1
- package/dist/core/governor/plan-api.js +6 -3
- package/dist/core/governor/read.d.ts +1 -1
- package/dist/core/governor/read.d.ts.map +1 -1
- package/dist/core/governor/read.js +1 -1
- package/dist/core/governor/state.d.ts +9 -0
- package/dist/core/governor/state.d.ts.map +1 -1
- package/dist/core/governor/state.js +40 -3
- package/dist/core/guard/config.d.ts +5 -0
- package/dist/core/guard/config.d.ts.map +1 -0
- package/dist/core/guard/config.js +157 -0
- package/dist/core/guard/coordinator.d.ts +14 -0
- package/dist/core/guard/coordinator.d.ts.map +1 -0
- package/dist/core/guard/coordinator.js +173 -0
- package/dist/core/guard/evaluator.d.ts +4 -0
- package/dist/core/guard/evaluator.d.ts.map +1 -0
- package/dist/core/guard/evaluator.js +242 -0
- package/dist/core/guard/evidence-v3.d.ts +15 -0
- package/dist/core/guard/evidence-v3.d.ts.map +1 -0
- package/dist/core/guard/evidence-v3.js +171 -0
- package/dist/core/guard/index.d.ts +10 -0
- package/dist/core/guard/index.d.ts.map +1 -0
- package/dist/core/guard/index.js +6 -0
- package/dist/core/guard/live-source-v3.d.ts +40 -0
- package/dist/core/guard/live-source-v3.d.ts.map +1 -0
- package/dist/core/guard/live-source-v3.js +128 -0
- package/dist/core/guard/storage.d.ts +27 -0
- package/dist/core/guard/storage.d.ts.map +1 -0
- package/dist/core/guard/storage.js +140 -0
- package/dist/core/guard/types.d.ts +119 -0
- package/dist/core/guard/types.d.ts.map +1 -0
- package/dist/core/guard/types.js +1 -0
- package/dist/core/hooks/adapter/detect.d.ts +18 -1
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +29 -0
- package/dist/core/hooks/adapter/events.d.ts +7 -4
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +12 -4
- package/dist/core/hooks/adapter/output.d.ts +2 -2
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.d.ts +7 -4
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +63 -25
- package/dist/core/hooks/adapter/wiring.d.ts +30 -4
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +89 -11
- package/dist/core/hooks/cli.d.ts +1 -1
- package/dist/core/hooks/cli.js +305 -444
- package/dist/core/hooks/effects/image-capture.d.ts +20 -34
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +212 -221
- package/dist/core/hooks/effects/index.d.ts +1 -9
- package/dist/core/hooks/effects/index.d.ts.map +1 -1
- package/dist/core/hooks/effects/index.js +1 -24
- package/dist/core/hooks/events/input-hash.d.ts +7 -0
- package/dist/core/hooks/events/input-hash.d.ts.map +1 -0
- package/dist/core/hooks/events/input-hash.js +43 -0
- package/dist/core/hooks/index.d.ts +4 -3
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +2 -3
- package/dist/core/hooks/resolve/coord-root.d.ts +1 -1
- package/dist/core/hooks/resolve/coord-root.js +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +16 -15
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +51 -42
- package/dist/core/hooks/resolve/transcript.d.ts +33 -3
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +155 -14
- package/dist/core/hooks/session-name-presence.d.ts +9 -10
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +15 -15
- package/dist/core/hooks/unsafe-cross-shell.d.ts +1 -1
- package/dist/core/hooks/unsafe-cross-shell.d.ts.map +1 -1
- package/dist/core/journal/index.d.ts +2 -2
- package/dist/core/journal/index.d.ts.map +1 -1
- package/dist/core/journal/index.js +9 -22
- package/dist/core/presence/blob.d.ts +4 -3
- package/dist/core/presence/blob.d.ts.map +1 -1
- package/dist/core/presence/blob.js +45 -44
- package/dist/core/presence/codec-digest.d.ts +29 -0
- package/dist/core/presence/codec-digest.d.ts.map +1 -0
- package/dist/core/presence/codec-digest.js +170 -0
- package/dist/core/presence/relay-client.d.ts +1 -1
- package/dist/core/presence/relay-client.d.ts.map +1 -1
- package/dist/core/presence/relay-client.js +5 -5
- package/dist/core/work/index.d.ts +1 -1
- package/dist/core/work/index.d.ts.map +1 -1
- package/dist/core/work/index.js +1 -1
- package/dist/core/work/read.d.ts +1 -1
- package/dist/core/work/read.d.ts.map +1 -1
- package/dist/core/work/read.js +1 -1
- package/dist/core/work/runner.d.ts.map +1 -1
- package/dist/core/work/runner.js +6 -0
- package/dist/core/work/state.d.ts +9 -0
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +17 -3
- package/dist/core/workflow/engine.js +24 -25
- package/dist/core/workflow/live-session-v3.d.ts +19 -0
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -0
- package/dist/core/workflow/live-session-v3.js +86 -0
- package/dist/core/workflow/scope-id.d.ts +3 -0
- package/dist/core/workflow/scope-id.d.ts.map +1 -0
- package/dist/core/workflow/scope-id.js +5 -0
- package/dist/core/workflow/workspaces/leases.d.ts +4 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +53 -19
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/browser/client.d.ts +41 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +203 -0
- package/dist/lib/browser/critique.d.ts +28 -2
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +74 -18
- package/dist/lib/browser/geometry.d.ts +1 -1
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +130 -6
- package/dist/lib/browser/index.d.ts +3 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +3 -0
- package/dist/lib/browser/qa-plan.d.ts +174 -0
- package/dist/lib/browser/qa-plan.d.ts.map +1 -0
- package/dist/lib/browser/qa-plan.js +321 -0
- package/dist/lib/browser/qa-reuse.d.ts +99 -0
- package/dist/lib/browser/qa-reuse.d.ts.map +1 -0
- package/dist/lib/browser/qa-reuse.js +222 -0
- package/dist/lib/browser/qa-snapshot.d.ts +64 -0
- package/dist/lib/browser/qa-snapshot.d.ts.map +1 -0
- package/dist/lib/browser/qa-snapshot.js +171 -0
- package/dist/lib/browser/runts.d.ts.map +1 -1
- package/dist/lib/browser/runts.js +22 -1
- package/dist/lib/browser/tiling.d.ts +71 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -0
- package/dist/lib/browser/tiling.js +118 -0
- package/dist/lib/claude-desktop.d.ts +0 -47
- package/dist/lib/claude-desktop.d.ts.map +1 -1
- package/dist/lib/claude-desktop.js +1 -169
- package/dist/lib/context/index.d.ts +0 -3
- package/dist/lib/context/index.d.ts.map +1 -1
- package/dist/lib/context/index.js +20 -42
- package/dist/lib/council/index.d.ts +2 -2
- package/dist/lib/council/index.d.ts.map +1 -1
- package/dist/lib/council/index.js +9 -20
- package/dist/lib/docs-frontmatter.d.ts +1 -6
- package/dist/lib/docs-frontmatter.d.ts.map +1 -1
- package/dist/lib/docs-frontmatter.js +12 -78
- package/dist/lib/docs-index.d.ts +9 -0
- package/dist/lib/docs-index.d.ts.map +1 -1
- package/dist/lib/docs-index.js +32 -3
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +14 -30
- package/dist/lib/docs-metadata-audit.d.ts +19 -0
- package/dist/lib/docs-metadata-audit.d.ts.map +1 -0
- package/dist/lib/docs-metadata-audit.js +132 -0
- package/dist/lib/docs-metadata-managed.d.ts +23 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -0
- package/dist/lib/docs-metadata-managed.js +78 -0
- package/dist/lib/docs-metadata-sync.d.ts +20 -0
- package/dist/lib/docs-metadata-sync.d.ts.map +1 -0
- package/dist/lib/docs-metadata-sync.js +222 -0
- package/dist/lib/docs-metadata-v2-schema.d.ts +273 -0
- package/dist/lib/docs-metadata-v2-schema.d.ts.map +1 -0
- package/dist/lib/docs-metadata-v2-schema.js +134 -0
- package/dist/lib/docs-metadata-v2.d.ts +21 -0
- package/dist/lib/docs-metadata-v2.d.ts.map +1 -0
- package/dist/lib/docs-metadata-v2.js +424 -0
- package/dist/lib/docs-new.d.ts +11 -0
- package/dist/lib/docs-new.d.ts.map +1 -0
- package/dist/lib/docs-new.js +52 -0
- package/dist/lib/docs-sweep.d.ts.map +1 -1
- package/dist/lib/docs-sweep.js +45 -29
- package/dist/lib/headless/index.d.ts +98 -0
- package/dist/lib/headless/index.d.ts.map +1 -0
- package/dist/lib/headless/index.js +211 -0
- package/dist/lib/identities/assume.d.ts +4 -4
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +52 -68
- package/dist/lib/instructions/apply.d.ts +5 -4
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +32 -20
- package/dist/lib/instructions/bundle.d.ts +1 -1
- package/dist/lib/instructions/bundle.d.ts.map +1 -1
- package/dist/lib/instructions/bundle.js +1 -1
- package/dist/lib/instructions/splice.d.ts +0 -1
- package/dist/lib/instructions/splice.d.ts.map +1 -1
- package/dist/lib/instructions/splice.js +22 -6
- package/dist/lib/instructions/templates.d.ts +7 -5
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +79 -9
- package/package.json +26 -5
- package/schemas/config.schema.json +120 -2
- package/schemas/docs-metadata-v2.schema.json +441 -0
- package/schemas/event-v3.schema.json +24472 -0
- package/src/commander.ts +4 -0
- package/src/commands/adapter.ts +2 -2
- package/src/commands/agents.ts +1512 -592
- package/src/commands/artifacts.ts +7 -6
- package/src/commands/backup.ts +29 -21
- package/src/commands/browse.ts +349 -8
- package/src/commands/checkpoint.ts +4 -3
- package/src/commands/claude-desktop.ts +2 -101
- package/src/commands/context.ts +1 -6
- package/src/commands/decision.ts +27 -44
- package/src/commands/docs.ts +100 -33
- package/src/commands/doctor.ts +14 -1
- package/src/commands/events.ts +256 -0
- package/src/commands/governor.ts +18 -4
- package/src/commands/init.ts +253 -57
- package/src/commands/instructions.ts +1 -1
- package/src/commands/journal.ts +4 -13
- package/src/commands/ledger-v3.ts +111 -0
- package/src/commands/presence.ts +11 -10
- package/src/commands/sync.ts +1 -1
- package/src/commands/web.ts +67 -8
- package/src/commands/work.ts +28 -5
- package/src/core/adapter.ts +5 -0
- package/src/core/adapters/attest.ts +8 -3
- package/src/core/adapters/profiles.ts +4 -6
- package/src/core/agents/canonical-emit.ts +34 -25
- package/src/core/agents/cli.ts +236 -262
- package/src/core/agents/codex-archive-v3.ts +138 -0
- package/src/core/agents/coord-client.ts +75 -188
- package/src/core/agents/finalization.ts +120 -38
- package/src/core/agents/index.ts +4 -5
- package/src/core/agents/live-authority-v3.ts +375 -0
- package/src/core/agents/live-lifecycle-v3.ts +140 -0
- package/src/core/agents/live-observation-v3.ts +216 -0
- package/src/core/agents/render/prompt-context.ts +29 -60
- package/src/core/agents/render/session-context.ts +10 -31
- package/src/core/agents/rules/claim-conflict.ts +85 -126
- package/src/core/agents/rules/commit-conflict.ts +3 -14
- package/src/core/agents/rules/stop-hook.ts +239 -293
- package/src/core/agents/session-events.ts +137 -104
- package/src/core/agents/session-finalization-state-v3.ts +90 -0
- package/src/core/agents/session-finalizer-v3.ts +953 -0
- package/src/core/agents/session-name-display.ts +149 -0
- package/src/core/agents/state/activity-log.ts +6 -14
- package/src/core/agents/state/heartbeat-writer.ts +82 -277
- package/src/core/agents/state/live-coordination-view.ts +290 -0
- package/src/core/agents/state/session-state.ts +24 -12
- package/src/core/agents/state/stale-sweep.ts +40 -17
- package/src/core/artifacts/index.ts +4 -5
- package/src/core/config.ts +148 -3
- package/src/core/context/index.ts +9 -17
- package/src/core/events/span-parent.ts +46 -0
- package/src/core/events/v3/advance.ts +168 -0
- package/src/core/events/v3/authority-outbox.ts +548 -0
- package/src/core/events/v3/base-builder.ts +60 -0
- package/src/core/events/v3/base-contract.ts +882 -0
- package/src/core/events/v3/bootstrap.ts +226 -0
- package/src/core/events/v3/builder.ts +59 -0
- package/src/core/events/v3/canonical.ts +153 -0
- package/src/core/events/v3/capabilities.ts +171 -0
- package/src/core/events/v3/capability-drift.ts +177 -0
- package/src/core/events/v3/catalog.ts +202 -0
- package/src/core/events/v3/clock-order.ts +41 -0
- package/src/core/events/v3/contract.ts +365 -0
- package/src/core/events/v3/control.ts +576 -0
- package/src/core/events/v3/coordination-view.ts +193 -0
- package/src/core/events/v3/economics.ts +384 -0
- package/src/core/events/v3/finalization-view.ts +67 -0
- package/src/core/events/v3/fingerprint-keys.ts +260 -0
- package/src/core/events/v3/generated.ts +48 -0
- package/src/core/events/v3/ids.ts +33 -0
- package/src/core/events/v3/index.ts +322 -0
- package/src/core/events/v3/latency.ts +551 -0
- package/src/core/events/v3/live-feed.ts +319 -0
- package/src/core/events/v3/live-observation.ts +39 -0
- package/src/core/events/v3/live-routing.ts +135 -0
- package/src/core/events/v3/producers/command-recorder.ts +631 -0
- package/src/core/events/v3/producers/command.ts +201 -0
- package/src/core/events/v3/producers/coordination-recorder.ts +538 -0
- package/src/core/events/v3/producers/coordination.ts +355 -0
- package/src/core/events/v3/producers/hook-base.ts +578 -0
- package/src/core/events/v3/producers/hook.ts +119 -0
- package/src/core/events/v3/producers/intake.ts +319 -0
- package/src/core/events/v3/producers/recorder.ts +2805 -0
- package/src/core/events/v3/projection.ts +653 -0
- package/src/core/events/v3/reader.ts +1127 -0
- package/src/core/events/v3/recovery-record.ts +244 -0
- package/src/core/events/v3/recovery.ts +271 -0
- package/src/core/events/v3/span-state.ts +187 -0
- package/src/core/events/v3/targets.ts +182 -0
- package/src/core/events/v3/turn-telemetry.ts +259 -0
- package/src/core/events/v3/validate.ts +361 -0
- package/src/core/events/v3/writer.ts +419 -0
- package/src/core/governor/index.ts +3 -0
- package/src/core/governor/plan-api.ts +10 -2
- package/src/core/governor/read.ts +3 -0
- package/src/core/governor/state.ts +52 -5
- package/src/core/guard/config.ts +206 -0
- package/src/core/guard/coordinator.ts +227 -0
- package/src/core/guard/evaluator.ts +343 -0
- package/src/core/guard/evidence-v3.ts +227 -0
- package/src/core/guard/index.ts +35 -0
- package/src/core/guard/live-source-v3.ts +204 -0
- package/src/core/guard/storage.ts +188 -0
- package/src/core/guard/types.ts +152 -0
- package/src/core/hooks/adapter/detect.ts +28 -1
- package/src/core/hooks/adapter/events.ts +14 -6
- package/src/core/hooks/adapter/output.ts +7 -2
- package/src/core/hooks/adapter/parse.ts +80 -38
- package/src/core/hooks/adapter/wiring.ts +119 -13
- package/src/core/hooks/cli.ts +351 -466
- package/src/core/hooks/effects/image-capture.ts +228 -238
- package/src/core/hooks/effects/index.ts +1 -36
- package/src/core/hooks/events/input-hash.ts +47 -0
- package/src/core/hooks/index.ts +4 -11
- package/src/core/hooks/resolve/coord-root.ts +1 -1
- package/src/core/hooks/resolve/owner.ts +52 -45
- package/src/core/hooks/resolve/transcript.ts +165 -14
- package/src/core/hooks/session-name-presence.ts +14 -15
- package/src/core/hooks/unsafe-cross-shell.ts +1 -1
- package/src/core/journal/index.ts +15 -22
- package/src/core/presence/blob.ts +48 -41
- package/src/core/presence/codec-digest.ts +215 -0
- package/src/core/presence/relay-client.ts +5 -5
- package/src/core/work/index.ts +3 -0
- package/src/core/work/read.ts +3 -0
- package/src/core/work/runner.ts +6 -0
- package/src/core/work/state.ts +27 -3
- package/src/core/workflow/engine.ts +24 -24
- package/src/core/workflow/live-session-v3.ts +126 -0
- package/src/core/workflow/scope-id.ts +6 -0
- package/src/core/workflow/workspaces/leases.ts +56 -19
- package/src/index.ts +1 -1
- package/src/lib/browser/client.ts +230 -0
- package/src/lib/browser/critique.ts +104 -27
- package/src/lib/browser/geometry.ts +143 -14
- package/src/lib/browser/index.ts +34 -0
- package/src/lib/browser/qa-plan.ts +501 -0
- package/src/lib/browser/qa-reuse.ts +306 -0
- package/src/lib/browser/qa-snapshot.ts +223 -0
- package/src/lib/browser/runts.ts +27 -2
- package/src/lib/browser/tiling.ts +164 -0
- package/src/lib/claude-desktop.ts +1 -232
- package/src/lib/context/index.ts +22 -46
- package/src/lib/council/index.ts +9 -21
- package/src/lib/docs-frontmatter.ts +8 -79
- package/src/lib/docs-index.ts +33 -3
- package/src/lib/docs-lint.ts +15 -29
- package/src/lib/docs-metadata-audit.ts +166 -0
- package/src/lib/docs-metadata-managed.ts +83 -0
- package/src/lib/docs-metadata-sync.ts +262 -0
- package/src/lib/docs-metadata-v2-schema.ts +138 -0
- package/src/lib/docs-metadata-v2.ts +646 -0
- package/src/lib/docs-new.ts +63 -0
- package/src/lib/docs-sweep.ts +42 -28
- package/src/lib/headless/index.ts +287 -0
- package/src/lib/identities/assume.ts +67 -86
- package/src/lib/instructions/apply.ts +33 -20
- package/src/lib/instructions/bundle.ts +2 -2
- package/src/lib/instructions/splice.ts +21 -7
- package/src/lib/instructions/templates.ts +85 -13
- package/dist/core/agents/cli-emit.d.ts +0 -27
- package/dist/core/agents/cli-emit.d.ts.map +0 -1
- package/dist/core/agents/cli-emit.js +0 -57
- package/dist/core/agents/codex-replay.d.ts +0 -29
- package/dist/core/agents/codex-replay.d.ts.map +0 -1
- package/dist/core/agents/codex-replay.js +0 -138
- package/dist/core/agents/events/consume.d.ts +0 -82
- package/dist/core/agents/events/consume.d.ts.map +0 -1
- package/dist/core/agents/events/consume.js +0 -195
- package/dist/core/agents/events/emit.d.ts +0 -42
- package/dist/core/agents/events/emit.d.ts.map +0 -1
- package/dist/core/agents/events/emit.js +0 -75
- package/dist/core/agents/events/ulid.d.ts +0 -11
- package/dist/core/agents/events/ulid.d.ts.map +0 -1
- package/dist/core/agents/events/ulid.js +0 -47
- package/dist/core/agents/state/heartbeat-projector.d.ts +0 -76
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +0 -1
- package/dist/core/agents/state/heartbeat-projector.js +0 -581
- package/dist/core/hooks/events/emit.d.ts +0 -31
- package/dist/core/hooks/events/emit.d.ts.map +0 -1
- package/dist/core/hooks/events/emit.js +0 -93
- package/dist/core/hooks/events/rotate.d.ts +0 -43
- package/dist/core/hooks/events/rotate.d.ts.map +0 -1
- package/dist/core/hooks/events/rotate.js +0 -142
- package/dist/core/hooks/events/schema.d.ts +0 -341
- package/dist/core/hooks/events/schema.d.ts.map +0 -1
- package/dist/core/hooks/events/schema.js +0 -12
- package/dist/core/hooks/events/ulid.d.ts +0 -10
- package/dist/core/hooks/events/ulid.d.ts.map +0 -1
- package/dist/core/hooks/events/ulid.js +0 -47
- package/dist/lib/docs-frontmatter-migrate.d.ts +0 -33
- package/dist/lib/docs-frontmatter-migrate.d.ts.map +0 -1
- package/dist/lib/docs-frontmatter-migrate.js +0 -364
- package/src/core/agents/cli-emit.ts +0 -64
- package/src/core/agents/codex-replay.ts +0 -163
- package/src/core/agents/events/consume.ts +0 -254
- package/src/core/agents/events/emit.ts +0 -115
- package/src/core/agents/events/ulid.ts +0 -51
- package/src/core/agents/state/heartbeat-projector.ts +0 -645
- package/src/core/hooks/events/emit.ts +0 -125
- package/src/core/hooks/events/rotate.ts +0 -151
- package/src/core/hooks/events/schema.ts +0 -582
- package/src/core/hooks/events/ulid.ts +0 -51
- package/src/lib/docs-frontmatter-migrate.ts +0 -427
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { LatencyMetricV3 } from "./latency.js";
|
|
2
|
+
import type { ReadLedgerV3Result } from "./reader.js";
|
|
3
|
+
export declare const EVENT_V3_ECONOMICS_PROJECTION_VERSION: "event-v3-economics-v1";
|
|
4
|
+
export interface TokenTotalsV3 {
|
|
5
|
+
input_tokens: number;
|
|
6
|
+
output_tokens: number;
|
|
7
|
+
cache_read_tokens: number;
|
|
8
|
+
cache_write_tokens: number;
|
|
9
|
+
}
|
|
10
|
+
export type TokenTotalsMetricV3 = {
|
|
11
|
+
state: "observed";
|
|
12
|
+
value: TokenTotalsV3;
|
|
13
|
+
} | {
|
|
14
|
+
state: "unknown";
|
|
15
|
+
known: TokenTotalsV3;
|
|
16
|
+
reasons: string[];
|
|
17
|
+
};
|
|
18
|
+
export type CostMetricV3 = {
|
|
19
|
+
state: "observed";
|
|
20
|
+
usd: number;
|
|
21
|
+
pricing_key: string;
|
|
22
|
+
} | {
|
|
23
|
+
state: "unknown";
|
|
24
|
+
known_usd: number;
|
|
25
|
+
reasons: string[];
|
|
26
|
+
};
|
|
27
|
+
export interface ModelPricingV3 {
|
|
28
|
+
input_usd_per_million: number;
|
|
29
|
+
output_usd_per_million: number;
|
|
30
|
+
cache_read_usd_per_million?: number;
|
|
31
|
+
cache_write_usd_per_million?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface EconomicsProjectionOptionsV3 {
|
|
34
|
+
pricing?: Record<string, ModelPricingV3>;
|
|
35
|
+
}
|
|
36
|
+
export interface TurnEconomicsV3 {
|
|
37
|
+
generation_id: string;
|
|
38
|
+
turn_id: string;
|
|
39
|
+
terminal_event_id: string;
|
|
40
|
+
model_key: string | null;
|
|
41
|
+
usage_method: string | null;
|
|
42
|
+
tokens: TokenTotalsMetricV3;
|
|
43
|
+
inference_ms: LatencyMetricV3;
|
|
44
|
+
harness_ms: LatencyMetricV3;
|
|
45
|
+
slowest_hook: string | null;
|
|
46
|
+
slowest_hook_ms: number | null;
|
|
47
|
+
cost: CostMetricV3;
|
|
48
|
+
}
|
|
49
|
+
export interface GenerationEconomicsV3 {
|
|
50
|
+
generation_id: string;
|
|
51
|
+
turn_count: number;
|
|
52
|
+
tokens: TokenTotalsMetricV3;
|
|
53
|
+
inference_ms: LatencyMetricV3;
|
|
54
|
+
harness_ms: LatencyMetricV3;
|
|
55
|
+
cost: CostMetricV3;
|
|
56
|
+
}
|
|
57
|
+
export interface EconomicsProjectionV3 {
|
|
58
|
+
projection_version: typeof EVENT_V3_ECONOMICS_PROJECTION_VERSION;
|
|
59
|
+
turns: TurnEconomicsV3[];
|
|
60
|
+
generations: GenerationEconomicsV3[];
|
|
61
|
+
}
|
|
62
|
+
export type DelegationRollupDiagnosticCodeV3 = "delegation_cycle" | "generation_economics_missing";
|
|
63
|
+
export interface DelegationRollupV3 {
|
|
64
|
+
root_generation_id: string;
|
|
65
|
+
generation_ids: string[];
|
|
66
|
+
tokens: TokenTotalsMetricV3;
|
|
67
|
+
inference_ms: LatencyMetricV3;
|
|
68
|
+
harness_ms: LatencyMetricV3;
|
|
69
|
+
cost: CostMetricV3;
|
|
70
|
+
diagnostics: Array<{
|
|
71
|
+
code: DelegationRollupDiagnosticCodeV3;
|
|
72
|
+
generation_id: string;
|
|
73
|
+
}>;
|
|
74
|
+
}
|
|
75
|
+
export declare function projectEconomicsV3(read: ReadLedgerV3Result, options?: EconomicsProjectionOptionsV3): EconomicsProjectionV3;
|
|
76
|
+
export declare function projectDelegationRollupV3(read: ReadLedgerV3Result, economics: EconomicsProjectionV3, rootGenerationId: string): DelegationRollupV3;
|
|
77
|
+
//# sourceMappingURL=economics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"economics.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/economics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,qCAAqC,EAAG,uBAAgC,CAAC;AAEtF,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAC3C;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAElE,MAAM,MAAM,YAAY,GACpB;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,YAAY,EAAE,eAAe,CAAC;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,YAAY,EAAE,eAAe,CAAC;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,OAAO,qCAAqC,CAAC;IACjE,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC;AAED,MAAM,MAAM,gCAAgC,GAAG,kBAAkB,GAAG,8BAA8B,CAAC;AAEnG,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,YAAY,EAAE,eAAe,CAAC;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,gCAAgC,CAAC;QACvC,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;CACJ;AASD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,kBAAkB,EACxB,OAAO,GAAE,4BAAiC,GACzC,qBAAqB,CAmDvB;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,kBAAkB,EACxB,SAAS,EAAE,qBAAqB,EAChC,gBAAgB,EAAE,MAAM,GACvB,kBAAkB,CAqEpB"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
export const EVENT_V3_ECONOMICS_PROJECTION_VERSION = "event-v3-economics-v1";
|
|
2
|
+
export function projectEconomicsV3(read, options = {}) {
|
|
3
|
+
if (!read.complete)
|
|
4
|
+
throw new Error("economics projection requires a complete V3 ledger read");
|
|
5
|
+
const models = new Map();
|
|
6
|
+
const turns = [];
|
|
7
|
+
for (const positioned of read.events) {
|
|
8
|
+
const event = positioned.event;
|
|
9
|
+
const generationId = event.scope.generation_id;
|
|
10
|
+
if (generationId &&
|
|
11
|
+
(event.event_type === "session.started" || event.event_type === "session.attestation_changed")) {
|
|
12
|
+
models.set(generationId, modelKey(event.payload.runtime_attestation));
|
|
13
|
+
}
|
|
14
|
+
if (event.event_type !== "turn.completed")
|
|
15
|
+
continue;
|
|
16
|
+
const tokens = tokensFromObservation(event.payload.usage);
|
|
17
|
+
const model = generationId ? (models.get(generationId) ?? null) : null;
|
|
18
|
+
const slowestHook = slowestHookFromObservation(event.payload.harness);
|
|
19
|
+
turns.push({
|
|
20
|
+
generation_id: generationId ?? "",
|
|
21
|
+
turn_id: event.scope.turn_id ?? "",
|
|
22
|
+
terminal_event_id: event.event_id,
|
|
23
|
+
model_key: model,
|
|
24
|
+
usage_method: usageMethod(event.payload.usage),
|
|
25
|
+
tokens,
|
|
26
|
+
inference_ms: timingFromObservation(event.payload.inference, "api_time_ms", "inference_unknown"),
|
|
27
|
+
harness_ms: timingFromObservation(event.payload.harness, "hook_time_ms", "harness_unknown"),
|
|
28
|
+
slowest_hook: slowestHook.name,
|
|
29
|
+
slowest_hook_ms: slowestHook.duration_ms,
|
|
30
|
+
cost: costForTurn(tokens, model, options.pricing),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const grouped = new Map();
|
|
34
|
+
for (const turn of turns) {
|
|
35
|
+
const generationTurns = grouped.get(turn.generation_id) ?? [];
|
|
36
|
+
generationTurns.push(turn);
|
|
37
|
+
grouped.set(turn.generation_id, generationTurns);
|
|
38
|
+
}
|
|
39
|
+
const generations = [...grouped.entries()].map(([generationId, generationTurns]) => ({
|
|
40
|
+
generation_id: generationId,
|
|
41
|
+
turn_count: generationTurns.length,
|
|
42
|
+
tokens: sumTokenMetrics(generationTurns.map(({ tokens }) => tokens)),
|
|
43
|
+
inference_ms: sumTimingMetrics(generationTurns.map(({ inference_ms }) => inference_ms)),
|
|
44
|
+
harness_ms: sumTimingMetrics(generationTurns.map(({ harness_ms }) => harness_ms)),
|
|
45
|
+
cost: sumCostMetrics(generationTurns.map(({ cost }) => cost)),
|
|
46
|
+
}));
|
|
47
|
+
generations.sort((left, right) => left.generation_id.localeCompare(right.generation_id));
|
|
48
|
+
return { projection_version: EVENT_V3_ECONOMICS_PROJECTION_VERSION, turns, generations };
|
|
49
|
+
}
|
|
50
|
+
export function projectDelegationRollupV3(read, economics, rootGenerationId) {
|
|
51
|
+
if (!read.complete)
|
|
52
|
+
throw new Error("delegation rollup requires a complete V3 ledger read");
|
|
53
|
+
const children = new Map();
|
|
54
|
+
for (const positioned of read.events) {
|
|
55
|
+
const event = positioned.event;
|
|
56
|
+
if (event.event_type !== "agent.completed")
|
|
57
|
+
continue;
|
|
58
|
+
const parent = event.scope.generation_id;
|
|
59
|
+
const child = string(event.payload.child_generation_id);
|
|
60
|
+
if (!parent || !child)
|
|
61
|
+
continue;
|
|
62
|
+
const set = children.get(parent) ?? new Set();
|
|
63
|
+
set.add(child);
|
|
64
|
+
children.set(parent, set);
|
|
65
|
+
}
|
|
66
|
+
const generationIds = [];
|
|
67
|
+
const diagnostics = [];
|
|
68
|
+
const visited = new Set();
|
|
69
|
+
const active = new Set();
|
|
70
|
+
const visit = (generationId) => {
|
|
71
|
+
if (active.has(generationId)) {
|
|
72
|
+
diagnostics.push({ code: "delegation_cycle", generation_id: generationId });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (visited.has(generationId))
|
|
76
|
+
return;
|
|
77
|
+
visited.add(generationId);
|
|
78
|
+
active.add(generationId);
|
|
79
|
+
generationIds.push(generationId);
|
|
80
|
+
for (const child of [...(children.get(generationId) ?? [])].sort())
|
|
81
|
+
visit(child);
|
|
82
|
+
active.delete(generationId);
|
|
83
|
+
};
|
|
84
|
+
visit(rootGenerationId);
|
|
85
|
+
const byGeneration = new Map(economics.generations.map((generation) => [generation.generation_id, generation]));
|
|
86
|
+
const included = generationIds.flatMap((generationId) => {
|
|
87
|
+
const generation = byGeneration.get(generationId);
|
|
88
|
+
if (generation)
|
|
89
|
+
return [generation];
|
|
90
|
+
diagnostics.push({ code: "generation_economics_missing", generation_id: generationId });
|
|
91
|
+
return [];
|
|
92
|
+
});
|
|
93
|
+
const missing = diagnostics
|
|
94
|
+
.filter(({ code }) => code === "generation_economics_missing")
|
|
95
|
+
.map(({ generation_id }) => `generation_economics_missing:${generation_id}`);
|
|
96
|
+
return {
|
|
97
|
+
root_generation_id: rootGenerationId,
|
|
98
|
+
generation_ids: generationIds,
|
|
99
|
+
tokens: sumTokenMetrics([
|
|
100
|
+
...included.map(({ tokens }) => tokens),
|
|
101
|
+
...missing.map((reason) => ({
|
|
102
|
+
state: "unknown",
|
|
103
|
+
known: zeroTokens(),
|
|
104
|
+
reasons: [reason],
|
|
105
|
+
})),
|
|
106
|
+
]),
|
|
107
|
+
inference_ms: sumTimingMetrics([
|
|
108
|
+
...included.map(({ inference_ms }) => inference_ms),
|
|
109
|
+
...missing.map((reason) => ({ state: "unknown", known_ms: 0, reasons: [reason] })),
|
|
110
|
+
]),
|
|
111
|
+
harness_ms: sumTimingMetrics([
|
|
112
|
+
...included.map(({ harness_ms }) => harness_ms),
|
|
113
|
+
...missing.map((reason) => ({ state: "unknown", known_ms: 0, reasons: [reason] })),
|
|
114
|
+
]),
|
|
115
|
+
cost: sumCostMetrics([
|
|
116
|
+
...included.map(({ cost }) => cost),
|
|
117
|
+
...missing.map((reason) => ({ state: "unknown", known_usd: 0, reasons: [reason] })),
|
|
118
|
+
]),
|
|
119
|
+
diagnostics,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function modelKey(runtimeAttestation) {
|
|
123
|
+
const model = record(record(runtimeAttestation).model);
|
|
124
|
+
if (model.state !== "observed")
|
|
125
|
+
return null;
|
|
126
|
+
const value = record(model.value);
|
|
127
|
+
const provider = string(value.provider);
|
|
128
|
+
const id = string(value.id);
|
|
129
|
+
return provider && id ? `${provider}/${id}` : null;
|
|
130
|
+
}
|
|
131
|
+
function tokensFromObservation(value) {
|
|
132
|
+
const observation = record(value);
|
|
133
|
+
if (observation.state !== "observed") {
|
|
134
|
+
return { state: "unknown", known: zeroTokens(), reasons: [observationReason(value)] };
|
|
135
|
+
}
|
|
136
|
+
const usage = record(observation.value);
|
|
137
|
+
if (!nonnegative(usage.input_tokens) || !nonnegative(usage.output_tokens)) {
|
|
138
|
+
return { state: "unknown", known: zeroTokens(), reasons: ["usage_invalid"] };
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
state: "observed",
|
|
142
|
+
value: {
|
|
143
|
+
input_tokens: usage.input_tokens,
|
|
144
|
+
output_tokens: usage.output_tokens,
|
|
145
|
+
cache_read_tokens: nonnegative(usage.cache_read_tokens)
|
|
146
|
+
? usage.cache_read_tokens
|
|
147
|
+
: 0,
|
|
148
|
+
cache_write_tokens: nonnegative(usage.cache_write_tokens)
|
|
149
|
+
? usage.cache_write_tokens
|
|
150
|
+
: 0,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function usageMethod(value) {
|
|
155
|
+
const observation = record(value);
|
|
156
|
+
return observation.state === "observed" ? string(record(observation.value).method) || null : null;
|
|
157
|
+
}
|
|
158
|
+
function timingFromObservation(value, field, fallback) {
|
|
159
|
+
const observation = record(value);
|
|
160
|
+
const fieldValue = record(observation.value)[field];
|
|
161
|
+
return observation.state === "observed" && nonnegative(fieldValue)
|
|
162
|
+
? { state: "observed", value_ms: fieldValue }
|
|
163
|
+
: { state: "unknown", known_ms: 0, reasons: [observationReason(value) || fallback] };
|
|
164
|
+
}
|
|
165
|
+
function slowestHookFromObservation(value) {
|
|
166
|
+
const observation = record(value);
|
|
167
|
+
if (observation.state !== "observed")
|
|
168
|
+
return { name: null, duration_ms: null };
|
|
169
|
+
const harness = record(observation.value);
|
|
170
|
+
const name = string(harness.slowest_hook);
|
|
171
|
+
const duration = harness.slowest_hook_ms;
|
|
172
|
+
return name && nonnegative(duration) && Number.isSafeInteger(duration)
|
|
173
|
+
? { name, duration_ms: duration }
|
|
174
|
+
: { name: null, duration_ms: null };
|
|
175
|
+
}
|
|
176
|
+
function costForTurn(tokens, model, pricing) {
|
|
177
|
+
const reasons = tokens.state === "unknown" ? ["usage_unknown"] : [];
|
|
178
|
+
const tokenValue = tokens.state === "observed" ? tokens.value : tokens.known;
|
|
179
|
+
if (!model)
|
|
180
|
+
return { state: "unknown", known_usd: 0, reasons: [...reasons, "model_unknown"].sort() };
|
|
181
|
+
const rates = pricing?.[model];
|
|
182
|
+
if (!rates) {
|
|
183
|
+
return {
|
|
184
|
+
state: "unknown",
|
|
185
|
+
known_usd: 0,
|
|
186
|
+
reasons: [...reasons, `pricing_unavailable:${model}`].sort(),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (tokenValue.cache_read_tokens > 0 && rates.cache_read_usd_per_million === undefined) {
|
|
190
|
+
reasons.push("cache_read_pricing_unavailable");
|
|
191
|
+
}
|
|
192
|
+
if (tokenValue.cache_write_tokens > 0 && rates.cache_write_usd_per_million === undefined) {
|
|
193
|
+
reasons.push("cache_write_pricing_unavailable");
|
|
194
|
+
}
|
|
195
|
+
const usd = (tokenValue.input_tokens * rates.input_usd_per_million +
|
|
196
|
+
tokenValue.output_tokens * rates.output_usd_per_million +
|
|
197
|
+
tokenValue.cache_read_tokens * (rates.cache_read_usd_per_million ?? 0) +
|
|
198
|
+
tokenValue.cache_write_tokens * (rates.cache_write_usd_per_million ?? 0)) /
|
|
199
|
+
1_000_000;
|
|
200
|
+
return reasons.length > 0
|
|
201
|
+
? { state: "unknown", known_usd: roundUsd(usd), reasons }
|
|
202
|
+
: { state: "observed", usd: roundUsd(usd), pricing_key: model };
|
|
203
|
+
}
|
|
204
|
+
function sumTokenMetrics(metrics) {
|
|
205
|
+
const total = zeroTokens();
|
|
206
|
+
const reasons = [];
|
|
207
|
+
for (const metric of metrics) {
|
|
208
|
+
addTokens(total, metric.state === "observed" ? metric.value : metric.known);
|
|
209
|
+
if (metric.state === "unknown")
|
|
210
|
+
reasons.push(...metric.reasons);
|
|
211
|
+
}
|
|
212
|
+
return reasons.length === 0
|
|
213
|
+
? { state: "observed", value: total }
|
|
214
|
+
: { state: "unknown", known: total, reasons: unique(reasons) };
|
|
215
|
+
}
|
|
216
|
+
function sumTimingMetrics(metrics) {
|
|
217
|
+
let known = 0;
|
|
218
|
+
const reasons = [];
|
|
219
|
+
for (const metric of metrics) {
|
|
220
|
+
known += metric.state === "observed" ? metric.value_ms : metric.known_ms;
|
|
221
|
+
if (metric.state === "unknown")
|
|
222
|
+
reasons.push(...metric.reasons);
|
|
223
|
+
}
|
|
224
|
+
return reasons.length === 0
|
|
225
|
+
? { state: "observed", value_ms: known }
|
|
226
|
+
: { state: "unknown", known_ms: known, reasons: unique(reasons) };
|
|
227
|
+
}
|
|
228
|
+
function sumCostMetrics(metrics) {
|
|
229
|
+
let known = 0;
|
|
230
|
+
const reasons = [];
|
|
231
|
+
const keys = new Set();
|
|
232
|
+
for (const metric of metrics) {
|
|
233
|
+
known += metric.state === "observed" ? metric.usd : metric.known_usd;
|
|
234
|
+
if (metric.state === "observed")
|
|
235
|
+
keys.add(metric.pricing_key);
|
|
236
|
+
else
|
|
237
|
+
reasons.push(...metric.reasons);
|
|
238
|
+
}
|
|
239
|
+
return reasons.length === 0
|
|
240
|
+
? { state: "observed", usd: roundUsd(known), pricing_key: [...keys].sort().join("+") }
|
|
241
|
+
: { state: "unknown", known_usd: roundUsd(known), reasons: unique(reasons) };
|
|
242
|
+
}
|
|
243
|
+
function zeroTokens() {
|
|
244
|
+
return { input_tokens: 0, output_tokens: 0, cache_read_tokens: 0, cache_write_tokens: 0 };
|
|
245
|
+
}
|
|
246
|
+
function addTokens(target, value) {
|
|
247
|
+
target.input_tokens += value.input_tokens;
|
|
248
|
+
target.output_tokens += value.output_tokens;
|
|
249
|
+
target.cache_read_tokens += value.cache_read_tokens;
|
|
250
|
+
target.cache_write_tokens += value.cache_write_tokens;
|
|
251
|
+
}
|
|
252
|
+
function nonnegative(value) {
|
|
253
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
254
|
+
}
|
|
255
|
+
function observationReason(value) {
|
|
256
|
+
const observation = record(value);
|
|
257
|
+
const state = string(observation.state) || "unknown";
|
|
258
|
+
const reason = string(observation.reason);
|
|
259
|
+
return reason ? `${state}:${reason}` : state;
|
|
260
|
+
}
|
|
261
|
+
function roundUsd(value) {
|
|
262
|
+
return Math.round(value * 1_000_000_000_000) / 1_000_000_000_000;
|
|
263
|
+
}
|
|
264
|
+
function unique(values) {
|
|
265
|
+
return [...new Set(values)].sort();
|
|
266
|
+
}
|
|
267
|
+
function record(value) {
|
|
268
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
269
|
+
? value
|
|
270
|
+
: {};
|
|
271
|
+
}
|
|
272
|
+
function string(value) {
|
|
273
|
+
return typeof value === "string" ? value : "";
|
|
274
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReadLedgerV3Result } from "./reader.js";
|
|
2
|
+
export declare const EVENT_V3_FINALIZATION_VIEW_VERSION: 1;
|
|
3
|
+
export type FinalizationScopeV3ErrorCode = "authority_unsafe" | "instance_not_live";
|
|
4
|
+
export declare class FinalizationScopeV3Error extends Error {
|
|
5
|
+
readonly code: FinalizationScopeV3ErrorCode;
|
|
6
|
+
constructor(code: FinalizationScopeV3ErrorCode);
|
|
7
|
+
}
|
|
8
|
+
export interface FinalizationScopeV3 {
|
|
9
|
+
projection_version: typeof EVENT_V3_FINALIZATION_VIEW_VERSION;
|
|
10
|
+
contract_major: 2;
|
|
11
|
+
instance_id: string;
|
|
12
|
+
session_id: string;
|
|
13
|
+
generation_id: string;
|
|
14
|
+
lifecycle_state?: string;
|
|
15
|
+
files_touched: string[];
|
|
16
|
+
source_event_id: string;
|
|
17
|
+
source_position: {
|
|
18
|
+
segment_ordinal: number;
|
|
19
|
+
byte_offset: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Read and validate the current V3 finalization boundary for one live instance. */
|
|
23
|
+
export declare function readFinalizationScopeV3(coordRoot: string, instanceId: string): FinalizationScopeV3;
|
|
24
|
+
/** Pure adapter used by replay tests and safety consumers. */
|
|
25
|
+
export declare function projectFinalizationScopeV3(read: ReadLedgerV3Result, instanceId: string): FinalizationScopeV3;
|
|
26
|
+
//# sourceMappingURL=finalization-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finalization-view.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/finalization-view.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,eAAO,MAAM,kCAAkC,EAAG,CAAU,CAAC;AAE7D,MAAM,MAAM,4BAA4B,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;AAEpF,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,IAAI,EAAE,4BAA4B;gBAAlC,IAAI,EAAE,4BAA4B;CAI/D;AAED,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,EAAE,OAAO,kCAAkC,CAAC;IAC9D,cAAc,EAAE,CAAC,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACnE;AAED,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,mBAAmB,CAErB;AAED,8DAA8D;AAC9D,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,MAAM,GACjB,mBAAmB,CAErB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { projectCoordinationViewV3, readCoordinationViewV3, } from "./coordination-view.js";
|
|
2
|
+
export const EVENT_V3_FINALIZATION_VIEW_VERSION = 1;
|
|
3
|
+
export class FinalizationScopeV3Error extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(code) {
|
|
6
|
+
super(`event_v3_finalization_scope:${code}`);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.name = "FinalizationScopeV3Error";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Read and validate the current V3 finalization boundary for one live instance. */
|
|
12
|
+
export function readFinalizationScopeV3(coordRoot, instanceId) {
|
|
13
|
+
return finalizationScopeFromCoordinationViewV3(readCoordinationViewV3(coordRoot), instanceId);
|
|
14
|
+
}
|
|
15
|
+
/** Pure adapter used by replay tests and safety consumers. */
|
|
16
|
+
export function projectFinalizationScopeV3(read, instanceId) {
|
|
17
|
+
return finalizationScopeFromCoordinationViewV3(projectCoordinationViewV3(read), instanceId);
|
|
18
|
+
}
|
|
19
|
+
function finalizationScopeFromCoordinationViewV3(view, instanceId) {
|
|
20
|
+
if (!view.authority_safe)
|
|
21
|
+
throw new FinalizationScopeV3Error("authority_unsafe");
|
|
22
|
+
const instance = view.instances[instanceId];
|
|
23
|
+
if (!instance?.authority_eligible) {
|
|
24
|
+
throw new FinalizationScopeV3Error("instance_not_live");
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
projection_version: EVENT_V3_FINALIZATION_VIEW_VERSION,
|
|
28
|
+
contract_major: 2,
|
|
29
|
+
instance_id: instance.instance_id,
|
|
30
|
+
session_id: instance.session_id,
|
|
31
|
+
generation_id: instance.generation_id,
|
|
32
|
+
lifecycle_state: instance.lifecycle_state,
|
|
33
|
+
files_touched: [...instance.files_touched],
|
|
34
|
+
source_event_id: instance.last_event_id,
|
|
35
|
+
source_position: { ...instance.source_position },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FingerprintContextV3 } from "./canonical.js";
|
|
2
|
+
export declare const FINGERPRINT_KEY_STORE_RELATIVE_PATH: ".harnery/private/fingerprint-keys.json";
|
|
3
|
+
export interface FingerprintKeyEpochV3 {
|
|
4
|
+
epoch_id: `pep_${string}`;
|
|
5
|
+
key_base64url: string;
|
|
6
|
+
created_at: string;
|
|
7
|
+
}
|
|
8
|
+
export interface FingerprintKeyStoreV3 {
|
|
9
|
+
format: "harnery-v3-fingerprint-keys";
|
|
10
|
+
format_version: 1;
|
|
11
|
+
active_epoch_id: `pep_${string}`;
|
|
12
|
+
epochs: FingerprintKeyEpochV3[];
|
|
13
|
+
}
|
|
14
|
+
export interface RotateFingerprintEpochV3Options {
|
|
15
|
+
activeGenerationCount: number;
|
|
16
|
+
now?: () => Date;
|
|
17
|
+
}
|
|
18
|
+
export declare function fingerprintKeyStorePathV3(coordRoot: string): string;
|
|
19
|
+
/** Load the private key store, creating its first epoch under an exclusive publication lock. */
|
|
20
|
+
export declare function loadOrCreateFingerprintKeyStoreV3(coordRoot: string, now?: () => Date): FingerprintKeyStoreV3;
|
|
21
|
+
export declare function readFingerprintKeyStoreV3(coordRoot: string): FingerprintKeyStoreV3;
|
|
22
|
+
/** Start a new comparison epoch only when no generation can still emit under the prior key. */
|
|
23
|
+
export declare function rotateFingerprintEpochV3(coordRoot: string, options: RotateFingerprintEpochV3Options): FingerprintKeyStoreV3;
|
|
24
|
+
export declare function fingerprintContextV3(coordRoot: string, rootId: `root_${string}`, generationId?: `gen_${string}`, epochId?: `pep_${string}`): FingerprintContextV3;
|
|
25
|
+
//# sourceMappingURL=fingerprint-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint-keys.d.ts","sourceRoot":"","sources":["../../../../src/core/events/v3/fingerprint-keys.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAO3D,eAAO,MAAM,mCAAmC,EAC9C,wCAAiD,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,OAAO,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,6BAA6B,CAAC;IACtC,cAAc,EAAE,CAAC,CAAC;IAClB,eAAe,EAAE,OAAO,MAAM,EAAE,CAAC;IACjC,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,+BAA+B;IAC9C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,gGAAgG;AAChG,wBAAgB,iCAAiC,CAC/C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,IAAuB,GACjC,qBAAqB,CAiBvB;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,qBAAqB,CAGlF;AAgBD,+FAA+F;AAC/F,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,+BAA+B,GACvC,qBAAqB,CAmBvB;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,QAAQ,MAAM,EAAE,EACxB,YAAY,CAAC,EAAE,OAAO,MAAM,EAAE,EAC9B,OAAO,CAAC,EAAE,OAAO,MAAM,EAAE,GACxB,oBAAoB,CAWtB"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
2
|
+
import { chmodSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { fsyncParentDirectory } from "../../workflow/durable-record.js";
|
|
6
|
+
import { acquireNoClobberLease } from "../../workflow/workspaces/leases.js";
|
|
7
|
+
const KEY_BYTES = 32;
|
|
8
|
+
const LOCK_RETRIES = 200;
|
|
9
|
+
const LOCK_RETRY_MS = 5;
|
|
10
|
+
const sleepCell = new Int32Array(new SharedArrayBuffer(4));
|
|
11
|
+
export const FINGERPRINT_KEY_STORE_RELATIVE_PATH = ".harnery/private/fingerprint-keys.json";
|
|
12
|
+
export function fingerprintKeyStorePathV3(coordRoot) {
|
|
13
|
+
return join(resolve(coordRoot), FINGERPRINT_KEY_STORE_RELATIVE_PATH);
|
|
14
|
+
}
|
|
15
|
+
/** Load the private key store, creating its first epoch under an exclusive publication lock. */
|
|
16
|
+
export function loadOrCreateFingerprintKeyStoreV3(coordRoot, now = () => new Date()) {
|
|
17
|
+
const path = fingerprintKeyStorePathV3(coordRoot);
|
|
18
|
+
if (existsSync(path)) {
|
|
19
|
+
return readFingerprintKeyStoreV3(coordRoot);
|
|
20
|
+
}
|
|
21
|
+
return withKeyStoreLock(coordRoot, () => {
|
|
22
|
+
if (existsSync(path))
|
|
23
|
+
return readFingerprintKeyStoreV3(coordRoot);
|
|
24
|
+
const epoch = createEpoch(now);
|
|
25
|
+
const store = {
|
|
26
|
+
format: "harnery-v3-fingerprint-keys",
|
|
27
|
+
format_version: 1,
|
|
28
|
+
active_epoch_id: epoch.epoch_id,
|
|
29
|
+
epochs: [epoch],
|
|
30
|
+
};
|
|
31
|
+
publishKeyStore(path, store, false);
|
|
32
|
+
return store;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function readFingerprintKeyStoreV3(coordRoot) {
|
|
36
|
+
const path = fingerprintKeyStorePathV3(coordRoot);
|
|
37
|
+
return validateKeyStore(readKeyStoreValue(path));
|
|
38
|
+
}
|
|
39
|
+
function readKeyStoreValue(path) {
|
|
40
|
+
const mode = statSync(path).mode & 0o777;
|
|
41
|
+
if ((mode & 0o077) !== 0) {
|
|
42
|
+
throw new Error("fingerprint key store permissions are not owner-only");
|
|
43
|
+
}
|
|
44
|
+
let parsed;
|
|
45
|
+
try {
|
|
46
|
+
parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new Error("fingerprint key store is unreadable or malformed");
|
|
50
|
+
}
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
/** Start a new comparison epoch only when no generation can still emit under the prior key. */
|
|
54
|
+
export function rotateFingerprintEpochV3(coordRoot, options) {
|
|
55
|
+
if (!Number.isSafeInteger(options.activeGenerationCount) || options.activeGenerationCount < 0) {
|
|
56
|
+
throw new Error("active generation count must be a non-negative integer");
|
|
57
|
+
}
|
|
58
|
+
if (options.activeGenerationCount !== 0) {
|
|
59
|
+
throw new Error("fingerprint epoch rotation is blocked while generations are active");
|
|
60
|
+
}
|
|
61
|
+
loadOrCreateFingerprintKeyStoreV3(coordRoot, options.now);
|
|
62
|
+
return withKeyStoreLock(coordRoot, () => {
|
|
63
|
+
const current = readFingerprintKeyStoreV3(coordRoot);
|
|
64
|
+
const epoch = createEpoch(options.now ?? (() => new Date()));
|
|
65
|
+
const next = {
|
|
66
|
+
...current,
|
|
67
|
+
active_epoch_id: epoch.epoch_id,
|
|
68
|
+
epochs: [...current.epochs, epoch],
|
|
69
|
+
};
|
|
70
|
+
publishKeyStore(fingerprintKeyStorePathV3(coordRoot), next, true);
|
|
71
|
+
return next;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
export function fingerprintContextV3(coordRoot, rootId, generationId, epochId) {
|
|
75
|
+
const store = readFingerprintKeyStoreV3(coordRoot);
|
|
76
|
+
const selectedId = epochId ?? store.active_epoch_id;
|
|
77
|
+
const epoch = store.epochs.find((candidate) => candidate.epoch_id === selectedId);
|
|
78
|
+
if (!epoch)
|
|
79
|
+
throw new Error("requested fingerprint epoch is unavailable");
|
|
80
|
+
return {
|
|
81
|
+
epochId: epoch.epoch_id,
|
|
82
|
+
epochKey: Buffer.from(epoch.key_base64url, "base64url"),
|
|
83
|
+
rootId,
|
|
84
|
+
generationId,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function withKeyStoreLock(coordRoot, operation) {
|
|
88
|
+
const privateDir = join(resolve(coordRoot), ".harnery/private");
|
|
89
|
+
mkdirSync(privateDir, { recursive: true, mode: 0o700 });
|
|
90
|
+
chmodSync(privateDir, 0o700);
|
|
91
|
+
const leasePath = join(privateDir, "fingerprint-key-lease");
|
|
92
|
+
const authority = createHash("sha256").update(resolve(coordRoot)).digest("hex");
|
|
93
|
+
let lease;
|
|
94
|
+
for (let attempt = 0; attempt < LOCK_RETRIES; attempt += 1) {
|
|
95
|
+
try {
|
|
96
|
+
lease = acquireNoClobberLease({
|
|
97
|
+
path: leasePath,
|
|
98
|
+
scope: "event-v3-fingerprint-key",
|
|
99
|
+
authoritySha256: authority,
|
|
100
|
+
staleAfterMs: 5_000,
|
|
101
|
+
validateStaleOwner: (owner) => owner.host === hostname() && !pidIsAlive(owner.pid),
|
|
102
|
+
});
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (attempt === LOCK_RETRIES - 1)
|
|
107
|
+
throw error;
|
|
108
|
+
Atomics.wait(sleepCell, 0, 0, LOCK_RETRY_MS);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!lease)
|
|
112
|
+
throw new Error("fingerprint key store publication lease is busy");
|
|
113
|
+
try {
|
|
114
|
+
return operation();
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
lease.release();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function pidIsAlive(pid) {
|
|
121
|
+
if (!Number.isSafeInteger(pid) || pid < 1)
|
|
122
|
+
return false;
|
|
123
|
+
try {
|
|
124
|
+
process.kill(pid, 0);
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return error.code !== "ESRCH";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function publishKeyStore(path, store, replacing) {
|
|
132
|
+
if (!replacing && existsSync(path))
|
|
133
|
+
throw new Error("fingerprint key store already exists");
|
|
134
|
+
const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
|
|
135
|
+
let fd;
|
|
136
|
+
try {
|
|
137
|
+
fd = openSync(temporary, "wx", 0o600);
|
|
138
|
+
writeFileSync(fd, `${JSON.stringify(store)}\n`, "utf8");
|
|
139
|
+
fsyncSync(fd);
|
|
140
|
+
closeSync(fd);
|
|
141
|
+
fd = undefined;
|
|
142
|
+
chmodSync(temporary, 0o600);
|
|
143
|
+
if (!replacing && existsSync(path))
|
|
144
|
+
throw new Error("fingerprint key store already exists");
|
|
145
|
+
renameSync(temporary, path);
|
|
146
|
+
fsyncParentDirectory(path);
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
if (fd !== undefined)
|
|
150
|
+
closeSync(fd);
|
|
151
|
+
if (existsSync(temporary))
|
|
152
|
+
unlinkSync(temporary);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function createEpoch(now) {
|
|
156
|
+
return {
|
|
157
|
+
epoch_id: `pep_${randomUUID()}`,
|
|
158
|
+
key_base64url: randomBytes(KEY_BYTES).toString("base64url"),
|
|
159
|
+
created_at: now().toISOString(),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function validateKeyStore(value) {
|
|
163
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
164
|
+
throw new Error("fingerprint key store has an invalid envelope");
|
|
165
|
+
}
|
|
166
|
+
const record = value;
|
|
167
|
+
const keys = Object.keys(record).sort();
|
|
168
|
+
if (keys.join("\0") !== "active_epoch_id\0epochs\0format\0format_version") {
|
|
169
|
+
throw new Error("fingerprint key store has unsupported fields");
|
|
170
|
+
}
|
|
171
|
+
if (record.format !== "harnery-v3-fingerprint-keys" || record.format_version !== 1) {
|
|
172
|
+
throw new Error("fingerprint key store format is unsupported");
|
|
173
|
+
}
|
|
174
|
+
if (typeof record.active_epoch_id !== "string" ||
|
|
175
|
+
!/^pep_[a-zA-Z0-9._-]{1,128}$/.test(record.active_epoch_id)) {
|
|
176
|
+
throw new Error("fingerprint key store active epoch is invalid");
|
|
177
|
+
}
|
|
178
|
+
if (!Array.isArray(record.epochs) || record.epochs.length === 0) {
|
|
179
|
+
throw new Error("fingerprint key store has no epochs");
|
|
180
|
+
}
|
|
181
|
+
const seen = new Set();
|
|
182
|
+
const epochs = record.epochs.map((candidate) => {
|
|
183
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) {
|
|
184
|
+
throw new Error("fingerprint key epoch is invalid");
|
|
185
|
+
}
|
|
186
|
+
const epoch = candidate;
|
|
187
|
+
if (Object.keys(epoch).sort().join("\0") !== "created_at\0epoch_id\0key_base64url") {
|
|
188
|
+
throw new Error("fingerprint key epoch has unsupported fields");
|
|
189
|
+
}
|
|
190
|
+
if (typeof epoch.epoch_id !== "string" || !/^pep_[a-zA-Z0-9._-]{1,128}$/.test(epoch.epoch_id)) {
|
|
191
|
+
throw new Error("fingerprint key epoch ID is invalid");
|
|
192
|
+
}
|
|
193
|
+
if (seen.has(epoch.epoch_id))
|
|
194
|
+
throw new Error("fingerprint key epoch is duplicated");
|
|
195
|
+
seen.add(epoch.epoch_id);
|
|
196
|
+
if (typeof epoch.key_base64url !== "string") {
|
|
197
|
+
throw new Error("fingerprint key bytes are invalid");
|
|
198
|
+
}
|
|
199
|
+
const key = Buffer.from(epoch.key_base64url, "base64url");
|
|
200
|
+
if (key.length !== KEY_BYTES || key.toString("base64url") !== epoch.key_base64url) {
|
|
201
|
+
throw new Error("fingerprint key bytes are invalid");
|
|
202
|
+
}
|
|
203
|
+
if (typeof epoch.created_at !== "string" || Number.isNaN(Date.parse(epoch.created_at))) {
|
|
204
|
+
throw new Error("fingerprint key epoch time is invalid");
|
|
205
|
+
}
|
|
206
|
+
return epoch;
|
|
207
|
+
});
|
|
208
|
+
if (!seen.has(record.active_epoch_id)) {
|
|
209
|
+
throw new Error("fingerprint key store active epoch is missing");
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
format: "harnery-v3-fingerprint-keys",
|
|
213
|
+
format_version: 1,
|
|
214
|
+
active_epoch_id: record.active_epoch_id,
|
|
215
|
+
epochs,
|
|
216
|
+
};
|
|
217
|
+
}
|