harnery 0.36.0 → 0.38.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 +9 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +10 -1
- package/dist/commands/admission.d.ts +21 -0
- package/dist/commands/admission.d.ts.map +1 -0
- package/dist/commands/admission.js +565 -0
- package/dist/commands/agents.d.ts +7 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +148 -47
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +73 -2
- package/dist/commands/browse-ai.d.ts +2 -2
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +6 -4
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +360 -21
- package/dist/commands/diagnostics.d.ts +4 -0
- package/dist/commands/diagnostics.d.ts.map +1 -0
- package/dist/commands/diagnostics.js +229 -0
- package/dist/commands/fetch.js +1 -0
- package/dist/commands/files.d.ts +12 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -1
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +4 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +71 -2
- package/dist/commands/qa-record.d.ts +144 -0
- package/dist/commands/qa-record.d.ts.map +1 -0
- package/dist/commands/qa-record.js +0 -0
- package/dist/commands/qa-run.d.ts +8 -0
- package/dist/commands/qa-run.d.ts.map +1 -0
- package/dist/commands/qa-run.js +396 -0
- package/dist/commands/qa-status.d.ts +71 -0
- package/dist/commands/qa-status.d.ts.map +1 -0
- package/dist/commands/qa-status.js +490 -0
- package/dist/commands/qa-verify.d.ts +40 -0
- package/dist/commands/qa-verify.d.ts.map +1 -0
- package/dist/commands/qa-verify.js +180 -0
- package/dist/commands/resources.d.ts +4 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +29 -0
- package/dist/commands/review-pack.d.ts +4 -0
- package/dist/commands/review-pack.d.ts.map +1 -0
- package/dist/commands/review-pack.js +1001 -0
- package/dist/commands/supervisor.d.ts +4 -0
- package/dist/commands/supervisor.d.ts.map +1 -0
- package/dist/commands/supervisor.js +101 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +4 -0
- package/dist/core/agents/cli.js +7 -3
- package/dist/core/agents/health.d.ts +17 -0
- package/dist/core/agents/health.d.ts.map +1 -0
- package/dist/core/agents/health.js +109 -0
- package/dist/core/agents/mailbox.d.ts +92 -0
- package/dist/core/agents/mailbox.d.ts.map +1 -0
- package/dist/core/agents/mailbox.js +325 -0
- package/dist/core/agents/qa-signal.d.ts +111 -0
- package/dist/core/agents/qa-signal.d.ts.map +1 -0
- package/dist/core/agents/qa-signal.js +231 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts +44 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts.map +1 -0
- package/dist/core/agents/reconcile-coordination-v3.js +58 -0
- package/dist/core/agents/render/prompt-context.d.ts +5 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +34 -13
- package/dist/core/agents/render/session-context.d.ts +8 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +34 -3
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +50 -1
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +6 -10
- package/dist/core/agents/session-finalizer-v3.js +4 -1
- package/dist/core/agents/session-name-display.d.ts +20 -5
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +67 -7
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +11 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +17 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +5 -0
- package/dist/core/artifacts/constants.d.ts +1 -1
- package/dist/core/artifacts/constants.js +1 -1
- package/dist/core/artifacts/index.d.ts +82 -6
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +410 -15
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +59 -0
- package/dist/core/diagnostics/advice.d.ts +9 -0
- package/dist/core/diagnostics/advice.d.ts.map +1 -0
- package/dist/core/diagnostics/advice.js +112 -0
- package/dist/core/diagnostics/bundle.d.ts +51 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -0
- package/dist/core/diagnostics/bundle.js +968 -0
- package/dist/core/diagnostics/comparison.d.ts +5 -0
- package/dist/core/diagnostics/comparison.d.ts.map +1 -0
- package/dist/core/diagnostics/comparison.js +444 -0
- package/dist/core/diagnostics/contract.d.ts +245 -0
- package/dist/core/diagnostics/contract.d.ts.map +1 -0
- package/dist/core/diagnostics/contract.js +18 -0
- package/dist/core/diagnostics/identity.d.ts +3 -0
- package/dist/core/diagnostics/identity.d.ts.map +1 -0
- package/dist/core/diagnostics/identity.js +10 -0
- package/dist/core/diagnostics/index.d.ts +8 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +7 -0
- package/dist/core/diagnostics/replay.d.ts +8 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -0
- package/dist/core/diagnostics/replay.js +213 -0
- package/dist/core/diagnostics/sanitize.d.ts +9 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -0
- package/dist/core/diagnostics/sanitize.js +84 -0
- package/dist/core/events/legacy-storage/compression.d.ts +13 -0
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/compression.js +107 -0
- package/dist/core/events/legacy-storage/index.d.ts +1 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/index.js +1 -0
- package/dist/core/events/v3/archive-retention.d.ts +33 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -0
- package/dist/core/events/v3/archive-retention.js +195 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +10 -0
- package/dist/core/events/v3/capabilities.d.ts +1 -1
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +1 -0
- package/dist/core/events/v3/coordination-view.d.ts +3 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +69 -8
- package/dist/core/events/v3/index.d.ts +1 -0
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +13 -2
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +10 -2
- package/dist/core/events/v3/producers/recorder.d.ts +39 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +350 -17
- package/dist/core/hooks/adapter/output.d.ts +8 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +11 -1
- package/dist/core/hooks/cli.js +303 -219
- package/dist/core/hooks/health.d.ts +59 -0
- package/dist/core/hooks/health.d.ts.map +1 -0
- package/dist/core/hooks/health.js +84 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +10 -3
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +4 -1
- package/dist/core/qa-artifacts.d.ts +20 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -0
- package/dist/core/qa-artifacts.js +110 -0
- package/dist/core/resources/contract.d.ts +96 -0
- package/dist/core/resources/contract.d.ts.map +1 -0
- package/dist/core/resources/contract.js +2 -0
- package/dist/core/resources/index.d.ts +6 -0
- package/dist/core/resources/index.d.ts.map +1 -0
- package/dist/core/resources/index.js +5 -0
- package/dist/core/resources/sampler.d.ts +34 -0
- package/dist/core/resources/sampler.d.ts.map +1 -0
- package/dist/core/resources/sampler.js +458 -0
- package/dist/core/resources/service-status.d.ts +3 -0
- package/dist/core/resources/service-status.d.ts.map +1 -0
- package/dist/core/resources/service-status.js +48 -0
- package/dist/core/resources/service.d.ts +26 -0
- package/dist/core/resources/service.d.ts.map +1 -0
- package/dist/core/resources/service.js +292 -0
- package/dist/core/resources/storage.d.ts +13 -0
- package/dist/core/resources/storage.d.ts.map +1 -0
- package/dist/core/resources/storage.js +30 -0
- package/dist/core/storage/atomic-json.d.ts +3 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -0
- package/dist/core/storage/atomic-json.js +15 -0
- package/dist/core/storage/builtins.d.ts.map +1 -1
- package/dist/core/storage/builtins.js +45 -6
- package/dist/core/storage/logger.d.ts +2 -0
- package/dist/core/storage/logger.d.ts.map +1 -1
- package/dist/core/storage/logger.js +2 -0
- package/dist/core/storage/query.d.ts +14 -0
- package/dist/core/storage/query.d.ts.map +1 -1
- package/dist/core/storage/query.js +51 -0
- package/dist/core/supervisor/activity.d.ts +4 -0
- package/dist/core/supervisor/activity.d.ts.map +1 -0
- package/dist/core/supervisor/activity.js +141 -0
- package/dist/core/supervisor/contract.d.ts +268 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -0
- package/dist/core/supervisor/contract.js +35 -0
- package/dist/core/supervisor/explanations.d.ts +4 -0
- package/dist/core/supervisor/explanations.d.ts.map +1 -0
- package/dist/core/supervisor/explanations.js +71 -0
- package/dist/core/supervisor/findings.d.ts +20 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -0
- package/dist/core/supervisor/findings.js +399 -0
- package/dist/core/supervisor/history.d.ts +9 -0
- package/dist/core/supervisor/history.d.ts.map +1 -0
- package/dist/core/supervisor/history.js +46 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts +14 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-alerts.js +70 -0
- package/dist/core/supervisor/hook-health-storage.d.ts +5 -0
- package/dist/core/supervisor/hook-health-storage.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-storage.js +24 -0
- package/dist/core/supervisor/hook-health.d.ts +72 -0
- package/dist/core/supervisor/hook-health.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health.js +203 -0
- package/dist/core/supervisor/hooks.d.ts +10 -0
- package/dist/core/supervisor/hooks.d.ts.map +1 -0
- package/dist/core/supervisor/hooks.js +28 -0
- package/dist/core/supervisor/index.d.ts +15 -0
- package/dist/core/supervisor/index.d.ts.map +1 -0
- package/dist/core/supervisor/index.js +14 -0
- package/dist/core/supervisor/log-feed.d.ts +9 -0
- package/dist/core/supervisor/log-feed.d.ts.map +1 -0
- package/dist/core/supervisor/log-feed.js +103 -0
- package/dist/core/supervisor/service.d.ts +29 -0
- package/dist/core/supervisor/service.d.ts.map +1 -0
- package/dist/core/supervisor/service.js +450 -0
- package/dist/core/supervisor/services.d.ts +11 -0
- package/dist/core/supervisor/services.d.ts.map +1 -0
- package/dist/core/supervisor/services.js +155 -0
- package/dist/core/supervisor/status.d.ts +3 -0
- package/dist/core/supervisor/status.d.ts.map +1 -0
- package/dist/core/supervisor/status.js +48 -0
- package/dist/core/supervisor/storage.d.ts +30 -0
- package/dist/core/supervisor/storage.d.ts.map +1 -0
- package/dist/core/supervisor/storage.js +73 -0
- package/dist/core/supervisor/timeline.d.ts +3 -0
- package/dist/core/supervisor/timeline.d.ts.map +1 -0
- package/dist/core/supervisor/timeline.js +87 -0
- package/dist/core/workflow/admission.d.ts +23 -0
- package/dist/core/workflow/admission.d.ts.map +1 -0
- package/dist/core/workflow/admission.js +136 -0
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +77 -2
- package/dist/core/workflow/index.d.ts +3 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -1
- package/dist/core/workflow/proof.d.ts +2 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +39 -1
- package/dist/core/workflow/run-state.d.ts +3 -2
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +8 -1
- package/dist/core/workflow/types.d.ts +33 -1
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +2 -1
- package/dist/lib/admission.d.ts +71 -0
- package/dist/lib/admission.d.ts.map +1 -0
- package/dist/lib/admission.js +264 -0
- package/dist/lib/agent-browser/client.d.ts +1 -1
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +1 -5
- package/dist/lib/browser/capture-fidelity.d.ts +39 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -0
- package/dist/lib/browser/capture-fidelity.js +84 -0
- package/dist/lib/browser/client.d.ts +46 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +168 -9
- package/dist/lib/browser/critique.d.ts +38 -1
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +34 -6
- package/dist/lib/browser/index.d.ts +5 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +4 -0
- package/dist/lib/browser/page-review-judge.d.ts +64 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -0
- package/dist/lib/browser/page-review-judge.js +270 -0
- package/dist/lib/browser/page-review-pack.d.ts +613 -0
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -0
- package/dist/lib/browser/page-review-pack.js +1751 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +377 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
- package/dist/lib/browser/qa-run-contracts.js +361 -0
- package/dist/lib/browser/qa-run.d.ts +141 -0
- package/dist/lib/browser/qa-run.d.ts.map +1 -0
- package/dist/lib/browser/qa-run.js +1283 -0
- package/dist/lib/browser/request-diagnostics.d.ts +13 -0
- package/dist/lib/browser/request-diagnostics.d.ts.map +1 -0
- package/dist/lib/browser/request-diagnostics.js +18 -0
- package/dist/lib/browser/tiling.d.ts +19 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +28 -0
- package/dist/lib/cookies/client.d.ts +9 -0
- package/dist/lib/cookies/client.d.ts.map +1 -1
- package/dist/lib/cookies/client.js +197 -44
- package/dist/lib/cookies/extra.d.ts +18 -0
- package/dist/lib/cookies/extra.d.ts.map +1 -0
- package/dist/lib/cookies/extra.js +14 -0
- package/dist/lib/cookies/index.d.ts +2 -1
- package/dist/lib/cookies/index.d.ts.map +1 -1
- package/dist/lib/cookies/index.js +2 -1
- package/dist/lib/coord-root-id.d.ts +9 -0
- package/dist/lib/coord-root-id.d.ts.map +1 -0
- package/dist/lib/coord-root-id.js +17 -0
- package/dist/lib/durable-job.d.ts +124 -0
- package/dist/lib/durable-job.d.ts.map +1 -0
- package/dist/lib/durable-job.js +296 -0
- package/dist/lib/http/client.d.ts +7 -1
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +2 -0
- package/dist/lib/instructions/apply.d.ts +3 -1
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +74 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +11 -2
- package/package.json +19 -2
- package/src/commander.ts +75 -1
- package/src/commands/admission.ts +699 -0
- package/src/commands/agents.ts +189 -50
- package/src/commands/artifacts.ts +132 -18
- package/src/commands/browse-ai.ts +10 -5
- package/src/commands/browse.ts +496 -20
- package/src/commands/diagnostics.ts +271 -0
- package/src/commands/fetch.ts +1 -0
- package/src/commands/files.ts +102 -2
- package/src/commands/governor.ts +8 -0
- package/src/commands/ledger-v3.ts +82 -0
- package/src/commands/qa-record.ts +682 -0
- package/src/commands/qa-run.ts +503 -0
- package/src/commands/qa-status.ts +608 -0
- package/src/commands/qa-verify.ts +238 -0
- package/src/commands/resources.ts +38 -0
- package/src/commands/review-pack.ts +1281 -0
- package/src/commands/supervisor.ts +141 -0
- package/src/commands/web.ts +19 -0
- package/src/commands/workflow.ts +8 -0
- package/src/core/agents/cli.ts +7 -3
- package/src/core/agents/health.ts +142 -0
- package/src/core/agents/mailbox.ts +373 -0
- package/src/core/agents/qa-signal.ts +261 -0
- package/src/core/agents/reconcile-coordination-v3.ts +77 -0
- package/src/core/agents/render/prompt-context.ts +42 -12
- package/src/core/agents/render/session-context.ts +37 -3
- package/src/core/agents/rules/commit-conflict.ts +58 -1
- package/src/core/agents/rules/stop-hook.ts +6 -12
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/agents/session-name-display.ts +78 -7
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +23 -0
- package/src/core/agents/state/live-coordination-view.ts +1 -0
- package/src/core/agents/state/live-coordination-writer.ts +5 -0
- package/src/core/artifacts/constants.ts +1 -1
- package/src/core/artifacts/index.ts +565 -30
- package/src/core/config.ts +134 -2
- package/src/core/diagnostics/advice.ts +147 -0
- package/src/core/diagnostics/bundle.ts +1250 -0
- package/src/core/diagnostics/comparison.ts +565 -0
- package/src/core/diagnostics/contract.ts +311 -0
- package/src/core/diagnostics/identity.ts +11 -0
- package/src/core/diagnostics/index.ts +7 -0
- package/src/core/diagnostics/replay.ts +314 -0
- package/src/core/diagnostics/sanitize.ts +97 -0
- package/src/core/events/legacy-storage/compression.ts +130 -0
- package/src/core/events/legacy-storage/index.ts +1 -0
- package/src/core/events/v3/archive-retention.ts +251 -0
- package/src/core/events/v3/bootstrap.ts +10 -0
- package/src/core/events/v3/capabilities.ts +2 -0
- package/src/core/events/v3/coordination-view.ts +100 -11
- package/src/core/events/v3/index.ts +9 -0
- package/src/core/events/v3/live-routing.ts +1 -0
- package/src/core/events/v3/producers/hook-base.ts +14 -2
- package/src/core/events/v3/producers/intake.ts +10 -2
- package/src/core/events/v3/producers/recorder.ts +420 -17
- package/src/core/hooks/adapter/output.ts +12 -1
- package/src/core/hooks/cli.ts +332 -247
- package/src/core/hooks/health.ts +146 -0
- package/src/core/hooks/resolve/transcript.ts +10 -3
- package/src/core/hooks/session-name-presence.ts +6 -1
- package/src/core/qa-artifacts.ts +126 -0
- package/src/core/resources/contract.ts +105 -0
- package/src/core/resources/index.ts +5 -0
- package/src/core/resources/sampler.ts +590 -0
- package/src/core/resources/service-status.ts +62 -0
- package/src/core/resources/service.ts +337 -0
- package/src/core/resources/storage.ts +44 -0
- package/src/core/storage/atomic-json.ts +15 -0
- package/src/core/storage/builtins.ts +62 -6
- package/src/core/storage/logger.ts +2 -0
- package/src/core/storage/query.ts +58 -0
- package/src/core/supervisor/activity.ts +193 -0
- package/src/core/supervisor/contract.ts +312 -0
- package/src/core/supervisor/explanations.ts +104 -0
- package/src/core/supervisor/findings.ts +788 -0
- package/src/core/supervisor/history.ts +61 -0
- package/src/core/supervisor/hook-health-alerts.ts +108 -0
- package/src/core/supervisor/hook-health-storage.ts +25 -0
- package/src/core/supervisor/hook-health.ts +301 -0
- package/src/core/supervisor/hooks.ts +35 -0
- package/src/core/supervisor/index.ts +14 -0
- package/src/core/supervisor/log-feed.ts +131 -0
- package/src/core/supervisor/service.ts +511 -0
- package/src/core/supervisor/services.ts +203 -0
- package/src/core/supervisor/status.ts +59 -0
- package/src/core/supervisor/storage.ts +126 -0
- package/src/core/supervisor/timeline.ts +133 -0
- package/src/core/workflow/admission.ts +215 -0
- package/src/core/workflow/engine.ts +93 -1
- package/src/core/workflow/index.ts +10 -0
- package/src/core/workflow/proof.ts +54 -1
- package/src/core/workflow/run-state.ts +13 -1
- package/src/core/workflow/types.ts +39 -1
- package/src/lib/admission.ts +347 -0
- package/src/lib/agent-browser/client.ts +2 -10
- package/src/lib/browser/capture-fidelity.ts +98 -0
- package/src/lib/browser/client.ts +212 -10
- package/src/lib/browser/critique.ts +62 -7
- package/src/lib/browser/index.ts +65 -0
- package/src/lib/browser/page-review-judge.ts +360 -0
- package/src/lib/browser/page-review-pack.ts +2384 -0
- package/src/lib/browser/qa-run-contracts.ts +743 -0
- package/src/lib/browser/qa-run.ts +1462 -0
- package/src/lib/browser/request-diagnostics.ts +27 -0
- package/src/lib/browser/tiling.ts +32 -0
- package/src/lib/cookies/client.ts +228 -42
- package/src/lib/cookies/extra.ts +28 -0
- package/src/lib/cookies/index.ts +2 -0
- package/src/lib/coord-root-id.ts +23 -0
- package/src/lib/durable-job.ts +407 -0
- package/src/lib/http/client.ts +13 -1
- package/src/lib/instructions/apply.ts +81 -2
- package/src/lib/instructions/templates.ts +11 -2
package/dist/core/hooks/cli.js
CHANGED
|
@@ -21,15 +21,15 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
|
21
21
|
import { dirname, join } from "node:path";
|
|
22
22
|
import { coordEnv } from "../../lib/env.js";
|
|
23
23
|
import { buildInstructionBundle } from "../../lib/instructions/bundle.js";
|
|
24
|
-
import { coordBinPath } from "../agents/coord-bin.js";
|
|
25
24
|
import { resolveCoordRoot } from "../agents/coord-client.js";
|
|
26
25
|
import { classifyWriteClaimFinalization, formatWriteClaimFinalizationDenial, } from "../agents/finalization.js";
|
|
27
|
-
import { restoreLiveCoordinationStateAfterEpochV3 } from "../agents/live-authority-v3.js";
|
|
26
|
+
import { recordLiveClaimChangeV3, restoreLiveCoordinationStateAfterEpochV3, } from "../agents/live-authority-v3.js";
|
|
28
27
|
import { evaluateStopHook, STOP_REMEDIATION_MARKER } from "../agents/rules/stop-hook.js";
|
|
29
|
-
import { assistantTextStartsWithSessionNameBlock, isSessionNameRemediationCommand, sessionNameDisplayInstruction, sessionNameDisplayPending, sessionNameDisplayRecoveryInstruction, toolResponseMintedSessionName, } from "../agents/session-name-display.js";
|
|
30
|
-
import { readHeartbeat, stampSessionNameSeen } from "../agents/state/heartbeat-writer.js";
|
|
28
|
+
import { assistantTextStartsWithSessionNameBlock, isSessionNameRemediationCommand, matchSessionNameDisplay, sessionNameDisplayAcceptedNames, sessionNameDisplayInstruction, sessionNameDisplayPending, sessionNameDisplayRecoveryInstruction, toolResponseMintedSessionName, } from "../agents/session-name-display.js";
|
|
29
|
+
import { readHeartbeat, setAssignedNameCache, stampSessionNameRequested, stampSessionNameSeen, } from "../agents/state/heartbeat-writer.js";
|
|
31
30
|
import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
|
|
32
31
|
import { ensureLiveCoordinationHeartbeat } from "../agents/state/live-coordination-writer.js";
|
|
32
|
+
import { assignName } from "../agents/state/names.js";
|
|
33
33
|
import { writePidmapRow } from "../agents/state/pidmap.js";
|
|
34
34
|
import { agentsRequireGitFinalization, resolveBinName } from "../config.js";
|
|
35
35
|
import { checkpointContext, completeContextRecovery, extractContextSample, markContextCompactionCompleted, prepareContextRecovery, readContextState, recordContextSample, } from "../context/index.js";
|
|
@@ -46,12 +46,14 @@ import { codexWslFileLinkTelemetry, inspectCodexWslBridge, isWslUncPath, renderC
|
|
|
46
46
|
import { captureImages, detectPresence, imageJanitor, journalArchive, journalJanitor, journalRecoveryCue, playSound, recordImageArtifactsV3, resetSoundCounters, runSessionSyncExtension, soundForEvent, } from "./effects/index.js";
|
|
47
47
|
import { toolInputHash, toolTargetHash } from "./events/input-hash.js";
|
|
48
48
|
import { canonicalize } from "./guard-path.js";
|
|
49
|
+
import { beginHookHealth, observeHookDebug, observeHookError, writeHookHealthCompletion, } from "./health.js";
|
|
49
50
|
import { adapterPidFromEnv, parsePsChainLine, selectAnchorPid } from "./resolve/anchor.js";
|
|
50
51
|
import { extractIntentComment, resolveIntent } from "./resolve/intent.js";
|
|
51
52
|
import { resolveOwner } from "./resolve/owner.js";
|
|
52
53
|
import { inspectSessionNameDisplayImmediately, scanAssistantStatusBoxPresent, scanSessionNameDisplayedImmediately, scanStatusBoxPresent, scanTranscriptRuntime, } from "./resolve/transcript.js";
|
|
53
54
|
import { sessionNamePresence } from "./session-name-presence.js";
|
|
54
55
|
import { unsafeCrossShellReason } from "./unsafe-cross-shell.js";
|
|
56
|
+
let hookHealthState;
|
|
55
57
|
function parseArgv(argv) {
|
|
56
58
|
const out = { eventName: null, extra: [] };
|
|
57
59
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -90,16 +92,15 @@ async function readStdin() {
|
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
93
|
-
* Env for
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* without the pin a child could write state to a different .harnery than the
|
|
97
|
-
* one this hook resolved.
|
|
95
|
+
* Env for a detached hook retry worker, with the coord root pinned. The hook
|
|
96
|
+
* may run with the session shell's cwd (inside a submodule or journal dir), so
|
|
97
|
+
* the worker must retain the root this process already resolved.
|
|
98
98
|
*/
|
|
99
99
|
function childEnv(coordRoot) {
|
|
100
100
|
return { ...process.env, HARNERY_COORD_ROOT_OVERRIDE: coordRoot };
|
|
101
101
|
}
|
|
102
102
|
function appendDebug(coordRoot, entry) {
|
|
103
|
+
observeHookDebug(hookHealthState, entry);
|
|
103
104
|
if (coordEnv("SHARED_LOGS") !== "0") {
|
|
104
105
|
try {
|
|
105
106
|
processLogger(coordRoot, "agent-hook").debug("agent_hook.diagnostic", legacyLogFields(entry));
|
|
@@ -119,6 +120,7 @@ function appendDebug(coordRoot, entry) {
|
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
function logError(coordRoot, err, context) {
|
|
123
|
+
observeHookError(hookHealthState, context.phase);
|
|
122
124
|
if (!coordRoot)
|
|
123
125
|
return;
|
|
124
126
|
if (coordEnv("SHARED_LOGS") !== "0") {
|
|
@@ -145,38 +147,41 @@ function logError(coordRoot, err, context) {
|
|
|
145
147
|
}
|
|
146
148
|
}
|
|
147
149
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* session.started emission never breaks the adapter flow.
|
|
151
|
-
*
|
|
152
|
-
* Lives at agent-hooks side (not agent-coord) to keep emitter/consumer
|
|
153
|
-
* separation: we spawn rather than import.
|
|
150
|
+
* Mint or recover the hurricane-style name for this owner in-process. Returns
|
|
151
|
+
* null on any failure so session.started emission never breaks adapter flow.
|
|
154
152
|
*/
|
|
155
|
-
function
|
|
156
|
-
const binary = coordBinPath("agent-coord", coordRoot) ?? "";
|
|
157
|
-
if (!existsSync(binary))
|
|
158
|
-
return null;
|
|
153
|
+
function assignNameInProcess(coordRoot, instanceId, kind, forkedFrom) {
|
|
159
154
|
try {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
args.push("--forked-from", forkedFrom);
|
|
163
|
-
const result = spawnSync(binary, args, {
|
|
164
|
-
encoding: "utf8",
|
|
165
|
-
timeout: 2000,
|
|
166
|
-
env: childEnv(coordRoot),
|
|
167
|
-
});
|
|
168
|
-
if (result.status !== 0 || !result.stdout)
|
|
169
|
-
return null;
|
|
170
|
-
const parsed = JSON.parse(result.stdout.trim());
|
|
171
|
-
if (parsed.name && parsed.kind) {
|
|
172
|
-
return { name: parsed.name, kind: parsed.kind };
|
|
173
|
-
}
|
|
174
|
-
return null;
|
|
155
|
+
const name = assignName(coordRoot, instanceId, kind, forkedFrom ? { forkedFrom } : undefined);
|
|
156
|
+
return { name, kind };
|
|
175
157
|
}
|
|
176
158
|
catch {
|
|
177
159
|
return null;
|
|
178
160
|
}
|
|
179
161
|
}
|
|
162
|
+
/** Mid-flight sessions can emit tools before SessionStart assigns a pool name.
|
|
163
|
+
* Stamp the disposable cache so Codec does not render the 8-character id. */
|
|
164
|
+
function ensureSessionDisplayName(coordRoot, instanceId, sessionId, adapter) {
|
|
165
|
+
if (coordEnv("WORKFLOW_CHILD") === "1")
|
|
166
|
+
return;
|
|
167
|
+
const row = readLiveCoordinationRow(coordRoot, instanceId) ?? readHeartbeat(coordRoot, instanceId);
|
|
168
|
+
if (row?.kind === "subagent" || row?.kind === "transient" || row?.workflow_run_id)
|
|
169
|
+
return;
|
|
170
|
+
if (row?.name?.trim())
|
|
171
|
+
return;
|
|
172
|
+
const assigned = assignNameInProcess(coordRoot, instanceId, "session");
|
|
173
|
+
if (!assigned?.name)
|
|
174
|
+
return;
|
|
175
|
+
if (!readHeartbeat(coordRoot, instanceId)) {
|
|
176
|
+
try {
|
|
177
|
+
ensureLiveCoordinationHeartbeat(coordRoot, instanceId, sessionId, adapter);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
/* cache materialization is best-effort; history still holds the name */
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
setAssignedNameCache(coordRoot, instanceId, assigned.name, "session");
|
|
184
|
+
}
|
|
180
185
|
/**
|
|
181
186
|
* Direct (in-process) pidmap write, avoiding the spawn overhead of going via
|
|
182
187
|
* the agent-coord CLI for every session.started signal. Pid-map rows
|
|
@@ -227,9 +232,9 @@ function buildEventData(eventType, ctx) {
|
|
|
227
232
|
// tool.requested heal path instead. The forkedFrom plumbing below stays
|
|
228
233
|
// for adapters that DO report a parent at session start.
|
|
229
234
|
const forkedFrom = undefined;
|
|
230
|
-
// Assign (or recover) name + kind
|
|
235
|
+
// Assign (or recover) name + kind in-process. Idempotent: resume
|
|
231
236
|
// returns the original name; new owner consumes a counter slot.
|
|
232
|
-
const assigned =
|
|
237
|
+
const assigned = assignNameInProcess(ctx.coordRoot, ctx.instanceId, "session", forkedFrom);
|
|
233
238
|
// Write the adapter pid-map row so `harn agents whoami` ppid-walks find
|
|
234
239
|
// this owner. Prefer the payload pid (the actual claude binary), then the
|
|
235
240
|
// anchor walk (the `node` ancestor for Cursor, which has no payload pid),
|
|
@@ -288,12 +293,12 @@ function buildEventData(eventType, ctx) {
|
|
|
288
293
|
clean_exit: p?.clean_exit ?? true,
|
|
289
294
|
};
|
|
290
295
|
case "turn.started": {
|
|
291
|
-
//
|
|
292
|
-
//
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
// Mid-flight onboarding (any adapter) can observe a turn before
|
|
297
|
+
// SessionStart. Mint durable display identity here so a later
|
|
298
|
+
// SessionStart remains idempotent and Codec is not stuck on the
|
|
299
|
+
// 8-character native id.
|
|
300
|
+
if (!readLiveCoordinationRow(ctx.coordRoot, ctx.instanceId)?.name) {
|
|
301
|
+
assignNameInProcess(ctx.coordRoot, ctx.instanceId, "session");
|
|
297
302
|
}
|
|
298
303
|
const prompt = p?.prompt ?? "";
|
|
299
304
|
const { value, truncated } = clampString(prompt, 4000);
|
|
@@ -351,7 +356,7 @@ function buildEventData(eventType, ctx) {
|
|
|
351
356
|
// (agent-coord/state/names.ts → kind=transient). Use the call ID as the
|
|
352
357
|
// instance_id input; assignName falls through to transient.
|
|
353
358
|
const childInstanceId = subagentCallId ?? ctx.instanceId;
|
|
354
|
-
const assigned =
|
|
359
|
+
const assigned = assignNameInProcess(ctx.coordRoot, childInstanceId, "subagent");
|
|
355
360
|
return {
|
|
356
361
|
agent_type: p?.raw.agent_type ??
|
|
357
362
|
p?.raw.subagent_type ??
|
|
@@ -466,10 +471,18 @@ function numberField(value) {
|
|
|
466
471
|
}
|
|
467
472
|
async function main() {
|
|
468
473
|
const hookStartedAt = performance.now();
|
|
474
|
+
const hookStartedRss = process.memoryUsage().rss;
|
|
469
475
|
const hookClock = captureSpanClockV3();
|
|
470
476
|
const { eventName, extra } = parseArgv(process.argv.slice(2));
|
|
471
477
|
const adapter = detectAdapter(process.argv.slice(2));
|
|
472
478
|
const raw = await readStdin();
|
|
479
|
+
hookHealthState = beginHookHealth({
|
|
480
|
+
started_at_ms: hookStartedAt,
|
|
481
|
+
started_rss_bytes: hookStartedRss,
|
|
482
|
+
event_name: eventName,
|
|
483
|
+
adapter,
|
|
484
|
+
payload_bytes: raw.length,
|
|
485
|
+
});
|
|
473
486
|
// Cursor executes the Claude Code project hooks too on hosts wired for both
|
|
474
487
|
// adapters, piping them its own payload (identifiable by the top-level
|
|
475
488
|
// cursor_version envelope field). That stray `--adapter claude-code`
|
|
@@ -480,6 +493,7 @@ async function main() {
|
|
|
480
493
|
if (coordEnv("AGENT_COORD_OFF") !== "1") {
|
|
481
494
|
const coordRoot = resolveCoordRoot(process.cwd());
|
|
482
495
|
if (coordRoot) {
|
|
496
|
+
hookHealthState.coord_root = coordRoot;
|
|
483
497
|
appendDebug(coordRoot, {
|
|
484
498
|
ts: new Date().toISOString(),
|
|
485
499
|
event_name: eventName,
|
|
@@ -532,6 +546,7 @@ async function main() {
|
|
|
532
546
|
const coordRoot = resolveCoordRoot(process.cwd());
|
|
533
547
|
if (!coordRoot)
|
|
534
548
|
return 0;
|
|
549
|
+
hookHealthState.coord_root = coordRoot;
|
|
535
550
|
if (eventName === "runtime-context-retry") {
|
|
536
551
|
return runRuntimeContextRetryWorker(coordRoot, adapter, extra);
|
|
537
552
|
}
|
|
@@ -557,8 +572,9 @@ async function main() {
|
|
|
557
572
|
// that tool. It is not a transcript and therefore cannot prove that an
|
|
558
573
|
// earlier assistant response omitted the required session-name block.
|
|
559
574
|
// afterAgentResponse is the one native boundary that carries the completed
|
|
560
|
-
// assistant text
|
|
561
|
-
//
|
|
575
|
+
// assistant text. Preserve only privacy-safe ritual booleans in the V3
|
|
576
|
+
// producer's open-turn state; Stop consumes them into the authoritative
|
|
577
|
+
// turn.completed event. The response body never enters V3 or heartbeat.
|
|
562
578
|
if (adapter === "cursor" && eventName === "after-agent-response") {
|
|
563
579
|
const payload = parsePayload(raw, adapter);
|
|
564
580
|
const owner = resolveOwner({ payload: payload?.raw ?? null, coordRoot });
|
|
@@ -566,15 +582,82 @@ async function main() {
|
|
|
566
582
|
appendDebug(coordRoot, { ...debugBase, skipped: "no-owner-resolved" });
|
|
567
583
|
return 0;
|
|
568
584
|
}
|
|
569
|
-
const
|
|
585
|
+
const row = readLiveCoordinationRow(coordRoot, owner.instance_id);
|
|
586
|
+
const name = sessionNameDisplayPending(row);
|
|
570
587
|
const text = typeof payload?.raw.text === "string" ? payload.raw.text : "";
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
588
|
+
const sighting = matchSessionNameDisplay(row, text);
|
|
589
|
+
if (sighting) {
|
|
590
|
+
stampSessionNameSeen(coordRoot, owner.instance_id, sighting.pending);
|
|
591
|
+
appendDebug(coordRoot, {
|
|
592
|
+
...debugBase,
|
|
593
|
+
effect: "session-name-display-stamped",
|
|
594
|
+
session_name_pending: sighting.pending,
|
|
595
|
+
...(sighting.displayed === sighting.pending
|
|
596
|
+
? {}
|
|
597
|
+
: { session_name_displayed: sighting.displayed, session_name_drift: true }),
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
else if (!name) {
|
|
601
|
+
// Nothing was owed. Distinct from a miss: conflating the two is what made
|
|
602
|
+
// a latched Cursor session undiagnosable from this log.
|
|
603
|
+
appendDebug(coordRoot, { ...debugBase, skipped: "no-pending-session-name" });
|
|
574
604
|
}
|
|
575
605
|
else {
|
|
576
|
-
appendDebug(coordRoot, {
|
|
606
|
+
appendDebug(coordRoot, {
|
|
607
|
+
...debugBase,
|
|
608
|
+
skipped: "session-name-block-absent",
|
|
609
|
+
session_name_pending: name,
|
|
610
|
+
reply_bytes: text.length,
|
|
611
|
+
reply_leads_with_fence: /^\s*`{3,}/.test(text),
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
if (ledgerRoute.state === "blocked") {
|
|
615
|
+
appendDebug(coordRoot, {
|
|
616
|
+
...debugBase,
|
|
617
|
+
skipped: "v3-control-blocked",
|
|
618
|
+
reason: ledgerRoute.reason,
|
|
619
|
+
owner_source: owner.source,
|
|
620
|
+
});
|
|
621
|
+
return 0;
|
|
577
622
|
}
|
|
623
|
+
const statusBoxPresentStrict = scanAssistantStatusBoxPresent(undefined, text);
|
|
624
|
+
// The hook parser needs the completed reply long enough to scan it, but
|
|
625
|
+
// durable hook intake must never retain that body. Keep every other native
|
|
626
|
+
// field so turn correlation remains available to the producer.
|
|
627
|
+
const { text: _completedReply, ...privacySafeRaw } = payload?.raw ?? {};
|
|
628
|
+
const privacySafePayload = payload ? { ...payload, raw: privacySafeRaw } : null;
|
|
629
|
+
const v3Result = recordLiveHookSignalV3({
|
|
630
|
+
coordRoot,
|
|
631
|
+
route: ledgerRoute,
|
|
632
|
+
eventName,
|
|
633
|
+
payload: privacySafePayload,
|
|
634
|
+
adapter,
|
|
635
|
+
instanceId: owner.instance_id,
|
|
636
|
+
hook_name: eventName,
|
|
637
|
+
hook_duration_ms: Math.max(0, Math.floor(performance.now() - hookStartedAt)),
|
|
638
|
+
monotonic_ns: hookClock.monotonic_ns,
|
|
639
|
+
turn_ritual: {
|
|
640
|
+
status_box_present: statusBoxPresentStrict,
|
|
641
|
+
status_box_present_strict: statusBoxPresentStrict,
|
|
642
|
+
session_name_required: name !== undefined,
|
|
643
|
+
session_name_present: name ? assistantTextStartsWithSessionNameBlock(text, name) : false,
|
|
644
|
+
},
|
|
645
|
+
});
|
|
646
|
+
observeHookDebug(hookHealthState, { event_v3_state: v3Result.state });
|
|
647
|
+
appendDebug(coordRoot, {
|
|
648
|
+
...debugBase,
|
|
649
|
+
effect: "cursor-response-ritual-observed",
|
|
650
|
+
owner_source: owner.source,
|
|
651
|
+
event_v3_state: v3Result.state,
|
|
652
|
+
...(v3Result.state === "observed"
|
|
653
|
+
? {
|
|
654
|
+
generation_id: v3Result.generation_id,
|
|
655
|
+
turn_id: v3Result.turn_id,
|
|
656
|
+
response_observed_at: v3Result.observed_at,
|
|
657
|
+
status_box_present_strict: statusBoxPresentStrict,
|
|
658
|
+
}
|
|
659
|
+
: {}),
|
|
660
|
+
});
|
|
578
661
|
return 0;
|
|
579
662
|
}
|
|
580
663
|
const norm = normalizeEventName(eventName);
|
|
@@ -595,8 +678,17 @@ async function main() {
|
|
|
595
678
|
});
|
|
596
679
|
return 0;
|
|
597
680
|
}
|
|
681
|
+
hookHealthState.owner_id = owner.instance_id;
|
|
598
682
|
const sessionId = payload?.session_id ?? payload?.conversation_id ?? owner.instance_id;
|
|
599
683
|
const priorCoordination = readHeartbeat(coordRoot, owner.instance_id);
|
|
684
|
+
if (norm.event_type !== "session.ended" &&
|
|
685
|
+
coordEnv("WORKFLOW_CHILD") !== "1" &&
|
|
686
|
+
priorCoordination?.kind !== "subagent" &&
|
|
687
|
+
priorCoordination?.kind !== "transient" &&
|
|
688
|
+
!priorCoordination?.workflow_run_id &&
|
|
689
|
+
!priorCoordination?.name?.trim()) {
|
|
690
|
+
assignNameInProcess(coordRoot, owner.instance_id, "session");
|
|
691
|
+
}
|
|
600
692
|
const data = buildEventData(norm.event_type, {
|
|
601
693
|
coordRoot,
|
|
602
694
|
payload,
|
|
@@ -661,6 +753,9 @@ async function main() {
|
|
|
661
753
|
...(turnRitual ? { turn_ritual: turnRitual } : {}),
|
|
662
754
|
...(deferV3Drain ? { defer_drain: true } : {}),
|
|
663
755
|
});
|
|
756
|
+
observeHookDebug(hookHealthState, {
|
|
757
|
+
...(v3Result ? { event_v3_state: v3Result.state } : {}),
|
|
758
|
+
});
|
|
664
759
|
const recordedGenerationId = v3Result && "event" in v3Result && "generation_id" in v3Result.event.scope
|
|
665
760
|
? v3Result.event.scope.generation_id
|
|
666
761
|
: undefined;
|
|
@@ -679,6 +774,14 @@ async function main() {
|
|
|
679
774
|
logError(coordRoot, error, { phase: "epoch-coordination-restore" });
|
|
680
775
|
}
|
|
681
776
|
}
|
|
777
|
+
if (norm.event_type !== "session.ended") {
|
|
778
|
+
try {
|
|
779
|
+
ensureSessionDisplayName(coordRoot, owner.instance_id, sessionId, adapter);
|
|
780
|
+
}
|
|
781
|
+
catch (error) {
|
|
782
|
+
logError(coordRoot, error, { phase: "session-display-name" });
|
|
783
|
+
}
|
|
784
|
+
}
|
|
682
785
|
const v3EventId = v3Result && "event" in v3Result
|
|
683
786
|
? v3Result.event.event_id
|
|
684
787
|
: v3Result && "event_id" in v3Result
|
|
@@ -806,6 +909,7 @@ async function main() {
|
|
|
806
909
|
// Session start is the only caller of the artifact janitor and the storage
|
|
807
910
|
// maintenance pass, so both load here instead of on every tool call.
|
|
808
911
|
const { autoCleanArtifacts } = await import("../artifacts/index.js");
|
|
912
|
+
const { autoCleanEventV3Archives } = await import("../events/v3/archive-retention.js");
|
|
809
913
|
const { createAutomaticMaintenanceComposition, runAutomaticMaintenancePass } = await import("../storage/maintenance-providers.js");
|
|
810
914
|
// Effect: throttled daily sweep of expired artifact workspaces (guarded,
|
|
811
915
|
// managed-expired only; see autoCleanArtifacts). Best-effort like every
|
|
@@ -816,6 +920,14 @@ async function main() {
|
|
|
816
920
|
catch (err) {
|
|
817
921
|
logError(coordRoot, err, { phase: "artifact-auto-clean" });
|
|
818
922
|
}
|
|
923
|
+
// Effect: apply the same daily throttle to closed V3 epochs. The newest
|
|
924
|
+
// recovery epochs remain protected by the archive retention policy.
|
|
925
|
+
try {
|
|
926
|
+
autoCleanEventV3Archives(coordRoot);
|
|
927
|
+
}
|
|
928
|
+
catch (err) {
|
|
929
|
+
logError(coordRoot, err, { phase: "event-v3-archive-auto-clean" });
|
|
930
|
+
}
|
|
819
931
|
// Plan one bounded, claim-first global slice from cached pressure only.
|
|
820
932
|
// Existing owner janitors above remain the only active executors until
|
|
821
933
|
// each provider receives a separate production activation.
|
|
@@ -874,7 +986,7 @@ async function main() {
|
|
|
874
986
|
// agnostic since v0.5.0.
|
|
875
987
|
if (norm.event_type === "session.ended") {
|
|
876
988
|
try {
|
|
877
|
-
cleanupSessionEnd(coordRoot, owner.instance_id
|
|
989
|
+
cleanupSessionEnd(coordRoot, owner.instance_id);
|
|
878
990
|
}
|
|
879
991
|
catch (err) {
|
|
880
992
|
logError(coordRoot, err, { phase: "session-end-cleanup" });
|
|
@@ -900,40 +1012,17 @@ async function main() {
|
|
|
900
1012
|
if (norm.event_type === "agent.started") {
|
|
901
1013
|
try {
|
|
902
1014
|
const childInstanceId = data.agent_id ?? owner.instance_id;
|
|
903
|
-
|
|
904
|
-
if (existsSync(agentCoordBin)) {
|
|
905
|
-
spawnSync(agentCoordBin, ["project"], {
|
|
906
|
-
encoding: "utf8",
|
|
907
|
-
timeout: 3000,
|
|
908
|
-
env: childEnv(coordRoot),
|
|
909
|
-
});
|
|
910
|
-
spawnSync(agentCoordBin, [
|
|
911
|
-
"log",
|
|
912
|
-
`SUBAGENT_START agent_type=${data.agent_type ?? "unknown"} agent_id=${childInstanceId.slice(0, 8)} platform=${adapterPlatform(adapter)}`,
|
|
913
|
-
"--instance",
|
|
914
|
-
childInstanceId,
|
|
915
|
-
], { encoding: "utf8", timeout: 2000, env: childEnv(coordRoot) });
|
|
916
|
-
}
|
|
917
|
-
emitSubagentStartContext(coordRoot, childInstanceId, sessionId, data, adapter);
|
|
1015
|
+
await emitSubagentStartContext(coordRoot, childInstanceId, sessionId, data, adapter);
|
|
918
1016
|
}
|
|
919
1017
|
catch (err) {
|
|
920
|
-
logError(coordRoot, err, { phase: "subagent-start-
|
|
1018
|
+
logError(coordRoot, err, { phase: "subagent-start-context" });
|
|
921
1019
|
}
|
|
922
1020
|
}
|
|
923
1021
|
// Phase 8: SubagentStop: delete subagent heartbeat + log.
|
|
924
1022
|
if (norm.event_type === "agent.completed") {
|
|
925
1023
|
try {
|
|
926
1024
|
const childInstanceId = payload?.subagent_id ?? payload?.agent_id ?? owner.instance_id;
|
|
927
|
-
cleanupSessionEnd(coordRoot, childInstanceId
|
|
928
|
-
const agentCoordBin = coordBinPath("agent-coord", coordRoot) ?? "";
|
|
929
|
-
if (existsSync(agentCoordBin)) {
|
|
930
|
-
spawnSync(agentCoordBin, [
|
|
931
|
-
"log",
|
|
932
|
-
`SUBAGENT_STOP agent_id=${childInstanceId.slice(0, 8)} platform=${adapterPlatform(adapter)}`,
|
|
933
|
-
"--instance",
|
|
934
|
-
childInstanceId,
|
|
935
|
-
], { encoding: "utf8", timeout: 2000, env: childEnv(coordRoot) });
|
|
936
|
-
}
|
|
1025
|
+
cleanupSessionEnd(coordRoot, childInstanceId);
|
|
937
1026
|
const { reconcileSessionFinalizationV3 } = await import("../agents/session-finalizer-v3.js");
|
|
938
1027
|
reconcileSessionFinalizationV3(coordRoot, { archive_observations: [] });
|
|
939
1028
|
}
|
|
@@ -1147,6 +1236,11 @@ async function main() {
|
|
|
1147
1236
|
try {
|
|
1148
1237
|
const name = sessionNameDisplayPending(readLiveCoordinationRow(coordRoot, owner.instance_id));
|
|
1149
1238
|
if (name && toolResponseMintedSessionName(payload?.tool_response, name)) {
|
|
1239
|
+
// Record the title before asking for it. The suggestion can still
|
|
1240
|
+
// change afterwards (an assigned-name rewrite, a lifecycle re-mint, a
|
|
1241
|
+
// rebuilt cache), and the agent must not be stranded for displaying
|
|
1242
|
+
// exactly what it was handed.
|
|
1243
|
+
stampSessionNameRequested(coordRoot, owner.instance_id, name);
|
|
1150
1244
|
const { emitContext } = await import("./adapter/output.js");
|
|
1151
1245
|
emitContext(adapter, "PostToolUse", sessionNameDisplayInstruction(name));
|
|
1152
1246
|
}
|
|
@@ -1211,21 +1305,7 @@ async function enforcePendingSessionNameDisplay(coordRoot, instanceId, adapter,
|
|
|
1211
1305
|
const command = extractBashCommand(payload?.tool_name, payload?.tool_input);
|
|
1212
1306
|
if (isSessionNameRemediationCommand(command, resolveBinName(coordRoot)))
|
|
1213
1307
|
return true;
|
|
1214
|
-
const inspection = adapter
|
|
1215
|
-
? {
|
|
1216
|
-
state: assistantTextStartsWithSessionNameBlock(payload.agent_message, name)
|
|
1217
|
-
? "present"
|
|
1218
|
-
: "unavailable",
|
|
1219
|
-
}
|
|
1220
|
-
: inspectSessionNameDisplayImmediately(
|
|
1221
|
-
// Codex hook payloads omit transcript_path on every event, which
|
|
1222
|
-
// left this inspection permanently unavailable and the latch never
|
|
1223
|
-
// stamped. Discover the rollout by session id; the scan only runs
|
|
1224
|
-
// while a name is pending, so the latch closes after one success.
|
|
1225
|
-
payload?.transcript_path ??
|
|
1226
|
-
(adapter === "codex"
|
|
1227
|
-
? discoverCodexSessionTranscript(payload?.session_id ?? instanceId)
|
|
1228
|
-
: undefined), name, assistantTextStartsWithSessionNameBlock);
|
|
1308
|
+
const inspection = inspectDisplayEvidence(instanceId, adapter, payload, coordination);
|
|
1229
1309
|
if (inspection.state === "present") {
|
|
1230
1310
|
stampSessionNameSeen(coordRoot, instanceId, name);
|
|
1231
1311
|
return true;
|
|
@@ -1238,10 +1318,53 @@ async function enforcePendingSessionNameDisplay(coordRoot, instanceId, adapter,
|
|
|
1238
1318
|
// readable transcript can still verify it.
|
|
1239
1319
|
return true;
|
|
1240
1320
|
}
|
|
1321
|
+
// Record the refusal. Without this the gate was the one enforcement path
|
|
1322
|
+
// that left no trace, so a session reporting "the gate keeps denying me"
|
|
1323
|
+
// could not be confirmed or refuted from the hook log.
|
|
1324
|
+
appendDebug(coordRoot, {
|
|
1325
|
+
ts: new Date().toISOString(),
|
|
1326
|
+
event_name: "pre-tool-use",
|
|
1327
|
+
adapter,
|
|
1328
|
+
effect: "session-name-display-denied",
|
|
1329
|
+
session_name_pending: name,
|
|
1330
|
+
tool_name: payload?.tool_name,
|
|
1331
|
+
});
|
|
1241
1332
|
const { emitDeny } = await import("./adapter/output.js");
|
|
1242
1333
|
emitDeny(adapter, sessionNameDisplayRecoveryInstruction(name, resolveBinName(coordRoot)));
|
|
1243
1334
|
return false;
|
|
1244
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Evidence for the pending display, over every title whose display counts.
|
|
1338
|
+
*
|
|
1339
|
+
* Cursor supplies the current narration directly; Claude Code and Codex are
|
|
1340
|
+
* resolved from their JSONL transcripts. Absent is the only state that denies,
|
|
1341
|
+
* so a title is refused only when a readable surface positively shows some
|
|
1342
|
+
* other opening text for every accepted title.
|
|
1343
|
+
*/
|
|
1344
|
+
function inspectDisplayEvidence(instanceId, adapter, payload, coordination) {
|
|
1345
|
+
if (adapter === "cursor" && payload?.agent_message !== undefined) {
|
|
1346
|
+
return matchSessionNameDisplay(coordination, payload.agent_message)
|
|
1347
|
+
? { state: "present" }
|
|
1348
|
+
: { state: "unavailable", reason: "transcript_not_ready" };
|
|
1349
|
+
}
|
|
1350
|
+
// Codex hook payloads omit transcript_path on every event, which left this
|
|
1351
|
+
// inspection permanently unavailable and the latch never stamped. Discover
|
|
1352
|
+
// the rollout by session id; the scan only runs while a name is pending, so
|
|
1353
|
+
// the latch closes after one success.
|
|
1354
|
+
const transcriptPath = payload?.transcript_path ??
|
|
1355
|
+
(adapter === "codex"
|
|
1356
|
+
? discoverCodexSessionTranscript(payload?.session_id ?? instanceId)
|
|
1357
|
+
: undefined);
|
|
1358
|
+
let verdict = { state: "absent" };
|
|
1359
|
+
for (const candidate of sessionNameDisplayAcceptedNames(coordination)) {
|
|
1360
|
+
const inspection = inspectSessionNameDisplayImmediately(transcriptPath, candidate, assistantTextStartsWithSessionNameBlock);
|
|
1361
|
+
if (inspection.state === "present")
|
|
1362
|
+
return inspection;
|
|
1363
|
+
if (inspection.state === "unavailable")
|
|
1364
|
+
verdict = inspection;
|
|
1365
|
+
}
|
|
1366
|
+
return verdict;
|
|
1367
|
+
}
|
|
1245
1368
|
function generationBoundHeartbeat(heartbeat, generationId) {
|
|
1246
1369
|
return generationId && heartbeat?.v3_generation_id === generationId ? heartbeat : null;
|
|
1247
1370
|
}
|
|
@@ -1273,40 +1396,19 @@ async function runPreToolUseGuard(coordRoot, instanceId, sessionId, data, adapte
|
|
|
1273
1396
|
}
|
|
1274
1397
|
if (targets.length === 0)
|
|
1275
1398
|
return true;
|
|
1276
|
-
const
|
|
1277
|
-
if (!existsSync(agentCoordBin)) {
|
|
1278
|
-
if (agentsRequireGitFinalization(coordRoot)) {
|
|
1279
|
-
const { emitDeny } = await import("./adapter/output.js");
|
|
1280
|
-
emitDeny(adapter, "Harnery denied the write before mutation because the claim coordinator is unavailable; repair the project's Harnery installation and retry.");
|
|
1281
|
-
return false;
|
|
1282
|
-
}
|
|
1283
|
-
return true;
|
|
1284
|
-
}
|
|
1399
|
+
const { evaluateClaim } = await import("../agents/rules/claim-conflict.js");
|
|
1285
1400
|
// For apply_patch (multi-file), collect siblings so the deny reason names
|
|
1286
1401
|
// them. For single-file tools the array has one entry.
|
|
1287
1402
|
for (const target of targets) {
|
|
1288
|
-
const verdictReq = JSON.stringify({
|
|
1289
|
-
rule: "claim",
|
|
1290
|
-
instance_id: instanceId,
|
|
1291
|
-
session_id: sessionId,
|
|
1292
|
-
path: target.path,
|
|
1293
|
-
});
|
|
1294
|
-
const result = spawnSync(agentCoordBin, ["verdict"], {
|
|
1295
|
-
input: verdictReq,
|
|
1296
|
-
encoding: "utf8",
|
|
1297
|
-
timeout: 3000,
|
|
1298
|
-
env: childEnv(coordRoot),
|
|
1299
|
-
});
|
|
1300
|
-
if (result.status !== 0 || !result.stdout)
|
|
1301
|
-
continue;
|
|
1302
|
-
let parsed = {};
|
|
1303
1403
|
try {
|
|
1304
|
-
parsed =
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1404
|
+
const parsed = evaluateClaim(coordRoot, {
|
|
1405
|
+
rule: "claim",
|
|
1406
|
+
instance_id: instanceId,
|
|
1407
|
+
session_id: sessionId,
|
|
1408
|
+
path: target.path,
|
|
1409
|
+
});
|
|
1410
|
+
if (parsed.allow !== false)
|
|
1411
|
+
continue;
|
|
1310
1412
|
let reason = parsed.reason ?? `Path ${target.path} is currently being edited by another agent.`;
|
|
1311
1413
|
if (targets.length > 1) {
|
|
1312
1414
|
const siblings = targets
|
|
@@ -1322,6 +1424,7 @@ async function runPreToolUseGuard(coordRoot, instanceId, sessionId, data, adapte
|
|
|
1322
1424
|
emitDeny(adapter, reason);
|
|
1323
1425
|
return false;
|
|
1324
1426
|
}
|
|
1427
|
+
catch { }
|
|
1325
1428
|
}
|
|
1326
1429
|
return true;
|
|
1327
1430
|
}
|
|
@@ -1520,16 +1623,23 @@ function releaseClaimOnFailure(coordRoot, instanceId, data, rawPayload) {
|
|
|
1520
1623
|
const row = readLiveCoordinationRow(coordRoot, instanceId);
|
|
1521
1624
|
if (!row?.files_touched?.includes(canonical))
|
|
1522
1625
|
return;
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1626
|
+
const before = readHeartbeat(coordRoot, instanceId);
|
|
1627
|
+
try {
|
|
1628
|
+
recordLiveClaimChangeV3({
|
|
1629
|
+
coordRoot,
|
|
1630
|
+
owner: instanceId,
|
|
1631
|
+
nativeSessionId: before?.session_id ?? instanceId,
|
|
1632
|
+
adapter: adapterFromPlatform(before?.platform),
|
|
1633
|
+
operation: "released",
|
|
1634
|
+
path: canonical,
|
|
1635
|
+
access: "write",
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
catch {
|
|
1639
|
+
/* best-effort release must not break adapter flow */
|
|
1640
|
+
}
|
|
1531
1641
|
}
|
|
1532
|
-
function cleanupSessionEnd(coordRoot, instanceId
|
|
1642
|
+
function cleanupSessionEnd(coordRoot, instanceId) {
|
|
1533
1643
|
// Sweep pid-map entries pointing to this instance
|
|
1534
1644
|
const pidmapDir = join(coordRoot, ".harnery", "pid-map");
|
|
1535
1645
|
if (existsSync(pidmapDir)) {
|
|
@@ -1553,44 +1663,20 @@ function cleanupSessionEnd(coordRoot, instanceId, reason) {
|
|
|
1553
1663
|
/* swallow */
|
|
1554
1664
|
}
|
|
1555
1665
|
}
|
|
1556
|
-
// Activity log
|
|
1557
|
-
const agentCoordBin = coordBinPath("agent-coord", coordRoot) ?? "";
|
|
1558
|
-
if (existsSync(agentCoordBin)) {
|
|
1559
|
-
spawnSync(agentCoordBin, ["log", `SESSION_END reason=${reason}`, "--instance", instanceId], { encoding: "utf8", timeout: 2000 });
|
|
1560
|
-
}
|
|
1561
1666
|
}
|
|
1562
1667
|
async function emitUserPromptSubmitSystemMessage(coordRoot, instanceId, sessionId, adapter, workspaceCwd, recoveryBriefing = "") {
|
|
1563
|
-
const
|
|
1564
|
-
let additionalContext =
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
if (adapter === "codex")
|
|
1576
|
-
args.push("--host-prompt-reminder");
|
|
1577
|
-
// Codex gets a fresh status-footer reminder on every prompt. Its Stop hook
|
|
1578
|
-
// stays observe-only, so missing the footer never replaces the answer.
|
|
1579
|
-
// Claude Code gets a fresh per-turn ritual reminder: satisfying the
|
|
1580
|
-
// contract up front is far cheaper than the bounce-and-retry the Stop hook
|
|
1581
|
-
// otherwise forces. Cursor's beforeSubmitPrompt cannot inject context, so
|
|
1582
|
-
// its Stop follow-up remains the supported enforcement channel.
|
|
1583
|
-
args.push("--session-name-nudge");
|
|
1584
|
-
if (adapter === "cursor" || adapter === "codex")
|
|
1585
|
-
args.push("--task-nudge");
|
|
1586
|
-
if (adapter === "codex")
|
|
1587
|
-
args.push("--status-footer-nudge");
|
|
1588
|
-
if (adapter === "claude-code")
|
|
1589
|
-
args.push("--turn-ritual-nudge", adapter);
|
|
1590
|
-
const result = spawnSync(agentCoordBin, args, { encoding: "utf8", timeout: 3000 });
|
|
1591
|
-
if (result.status === 0 && result.stdout)
|
|
1592
|
-
additionalContext = result.stdout.trim();
|
|
1593
|
-
}
|
|
1668
|
+
const { renderPromptContext } = await import("../agents/render/prompt-context.js");
|
|
1669
|
+
let additionalContext = renderPromptContext({
|
|
1670
|
+
coordRoot,
|
|
1671
|
+
instanceId,
|
|
1672
|
+
sessionId,
|
|
1673
|
+
adapter,
|
|
1674
|
+
sessionNameNudge: true,
|
|
1675
|
+
taskNudge: adapter === "cursor" || adapter === "codex",
|
|
1676
|
+
hostPromptReminder: adapter === "codex",
|
|
1677
|
+
statusFooterNudge: adapter === "codex",
|
|
1678
|
+
turnRitualNudge: adapter === "claude-code" ? adapter : undefined,
|
|
1679
|
+
}).trim();
|
|
1594
1680
|
if (adapter === "codex") {
|
|
1595
1681
|
const fileLinkContext = renderCodexWslFileLinkContext(coordRoot, workspaceCwd);
|
|
1596
1682
|
if (fileLinkContext) {
|
|
@@ -1606,8 +1692,8 @@ async function emitUserPromptSubmitSystemMessage(coordRoot, instanceId, sessionI
|
|
|
1606
1692
|
emitContext(adapter, "UserPromptSubmit", additionalContext);
|
|
1607
1693
|
return true;
|
|
1608
1694
|
}
|
|
1609
|
-
function emitSubagentStartContext(coordRoot, instanceId, sessionId, data, adapter) {
|
|
1610
|
-
// Look up the subagent's assigned name (just-written by
|
|
1695
|
+
async function emitSubagentStartContext(coordRoot, instanceId, sessionId, data, adapter) {
|
|
1696
|
+
// Look up the subagent's assigned name (just-written by the in-process name
|
|
1611
1697
|
// in session.started data) + the parent's short id for the "you are a subagent
|
|
1612
1698
|
// of X" framing.
|
|
1613
1699
|
const subagentName = data.name ?? "";
|
|
@@ -1619,69 +1705,55 @@ function emitSubagentStartContext(coordRoot, instanceId, sessionId, data, adapte
|
|
|
1619
1705
|
// Render peer table inline since the subagent might want to know who else
|
|
1620
1706
|
// is around. Reuse prompt-context (which dedups against the per-owner hash);
|
|
1621
1707
|
// first call will always emit.
|
|
1622
|
-
const agentCoordBin = coordBinPath("agent-coord", coordRoot) ?? "";
|
|
1623
1708
|
let combined = message;
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1709
|
+
const { renderPromptContext } = await import("../agents/render/prompt-context.js");
|
|
1710
|
+
const context = renderPromptContext({
|
|
1711
|
+
coordRoot,
|
|
1712
|
+
instanceId,
|
|
1713
|
+
sessionId,
|
|
1714
|
+
agentName: subagentName,
|
|
1715
|
+
}).trim();
|
|
1716
|
+
if (context)
|
|
1717
|
+
combined = `${message}\n\n${context}`;
|
|
1630
1718
|
// Use SubagentStart event-name in CC's hookSpecificOutput shape; cursor's
|
|
1631
1719
|
// flat `additional_context` works the same way.
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
});
|
|
1720
|
+
const { emitContext } = await import("./adapter/output.js");
|
|
1721
|
+
emitContext(adapter, "SubagentStart", combined);
|
|
1635
1722
|
}
|
|
1636
1723
|
function adapterPlatform(adapter) {
|
|
1637
1724
|
if (adapter === "claude-code")
|
|
1638
1725
|
return "claude-code";
|
|
1639
1726
|
return adapter;
|
|
1640
1727
|
}
|
|
1728
|
+
function adapterFromPlatform(platform) {
|
|
1729
|
+
if (platform === "cursor")
|
|
1730
|
+
return "cursor";
|
|
1731
|
+
if (platform === "codex")
|
|
1732
|
+
return "codex";
|
|
1733
|
+
return "claude-code";
|
|
1734
|
+
}
|
|
1641
1735
|
async function emitSessionStartSystemMessage(coordRoot, instanceId, sessionId, emittedData, adapter, recoveryBriefing = "") {
|
|
1642
|
-
const agentCoordBin = coordBinPath("agent-coord", coordRoot) ?? "";
|
|
1643
1736
|
const workflowChild = coordEnv("WORKFLOW_CHILD") === "1";
|
|
1644
1737
|
let additionalContext = "";
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
const platform = adapterPlatform(adapter);
|
|
1660
|
-
spawnSync(agentCoordBin, [
|
|
1661
|
-
"log",
|
|
1662
|
-
`SESSION_START model=${model} source=${source} platform=${platform}`,
|
|
1663
|
-
"--instance",
|
|
1738
|
+
// Opportunistic reconciliation makes normal session starts a failsafe for
|
|
1739
|
+
// archive, idle, cascade, and host lifecycle observations. It also runs the
|
|
1740
|
+
// stale cache sweep through the shared ADR 0077 composition.
|
|
1741
|
+
const { reconcileCoordinationV3 } = await import("../agents/reconcile-coordination-v3.js");
|
|
1742
|
+
reconcileCoordinationV3(coordRoot);
|
|
1743
|
+
// Workflow children retain lifecycle/event capture but do not receive
|
|
1744
|
+
// operator-facing peer, council, or init-remediation context. Injecting
|
|
1745
|
+
// that context can make a bounded child follow housekeeping instructions
|
|
1746
|
+
// instead of its assigned prompt.
|
|
1747
|
+
if (!workflowChild) {
|
|
1748
|
+
const agentName = emittedData.name ?? "";
|
|
1749
|
+
const { renderSessionContext } = await import("../agents/render/session-context.js");
|
|
1750
|
+
additionalContext = renderSessionContext({
|
|
1751
|
+
coordRoot,
|
|
1664
1752
|
instanceId,
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
// instead of its assigned prompt.
|
|
1670
|
-
if (!workflowChild) {
|
|
1671
|
-
const agentName = emittedData.name ?? "";
|
|
1672
|
-
const args = ["session-context", "--instance", instanceId, "--session", sessionId];
|
|
1673
|
-
if (agentName)
|
|
1674
|
-
args.push("--name", agentName);
|
|
1675
|
-
// The "You are agent-X." prefix in session-context renders unqualified by
|
|
1676
|
-
// default (claude-code-style). For cursor/codex the bash dispatchers add
|
|
1677
|
-
// a "(Cursor)" / "(Codex)" suffix; pass it through as --platform-label.
|
|
1678
|
-
if (adapter !== "claude-code") {
|
|
1679
|
-
args.push("--platform-label", platform === "cursor" ? "Cursor" : "Codex");
|
|
1680
|
-
}
|
|
1681
|
-
const result = spawnSync(agentCoordBin, args, { encoding: "utf8", timeout: 3000 });
|
|
1682
|
-
if (result.status === 0 && result.stdout)
|
|
1683
|
-
additionalContext = result.stdout.trim();
|
|
1684
|
-
}
|
|
1753
|
+
sessionId,
|
|
1754
|
+
agentName: agentName || undefined,
|
|
1755
|
+
platformLabel: adapter === "claude-code" ? undefined : adapter === "cursor" ? "Cursor" : "Codex",
|
|
1756
|
+
}).trim();
|
|
1685
1757
|
}
|
|
1686
1758
|
// Effect (claude-code): merge the journal recovery cue into the session-start
|
|
1687
1759
|
// context. Was a standalone additionalContext emission from the previous
|
|
@@ -1722,6 +1794,11 @@ function completeRecoveryInjection(coordRoot, instanceId, sessionId, recovery) {
|
|
|
1722
1794
|
}
|
|
1723
1795
|
main()
|
|
1724
1796
|
.then(async (code) => {
|
|
1797
|
+
writeHookHealthCompletion(hookHealthState, {
|
|
1798
|
+
finished_at_ms: performance.now(),
|
|
1799
|
+
finished_rss_bytes: process.memoryUsage().rss,
|
|
1800
|
+
pid: process.pid,
|
|
1801
|
+
});
|
|
1725
1802
|
await closeProcessLoggers();
|
|
1726
1803
|
process.exit(code);
|
|
1727
1804
|
})
|
|
@@ -1729,6 +1806,13 @@ main()
|
|
|
1729
1806
|
logError(resolveCoordRoot(process.cwd()), err, {
|
|
1730
1807
|
argv: process.argv.slice(2),
|
|
1731
1808
|
pid: process.pid,
|
|
1809
|
+
phase: "top-level",
|
|
1810
|
+
});
|
|
1811
|
+
writeHookHealthCompletion(hookHealthState, {
|
|
1812
|
+
finished_at_ms: performance.now(),
|
|
1813
|
+
finished_rss_bytes: process.memoryUsage().rss,
|
|
1814
|
+
pid: process.pid,
|
|
1815
|
+
faulted: true,
|
|
1732
1816
|
});
|
|
1733
1817
|
await closeProcessLoggers();
|
|
1734
1818
|
process.exit(0);
|