@telora/daemon 0.22.146 → 0.22.169
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/build-info.json +15 -3
- package/dist/audit/audit-phase.d.ts +11 -1
- package/dist/audit/audit-phase.d.ts.map +1 -1
- package/dist/audit/audit-phase.js +2 -14
- package/dist/audit/audit-phase.js.map +1 -1
- package/dist/audit/audit-prompt.d.ts +7 -4
- package/dist/audit/audit-prompt.d.ts.map +1 -1
- package/dist/audit/audit-prompt.js +34 -23
- package/dist/audit/audit-prompt.js.map +1 -1
- package/dist/backends/codex/codex-mcp-proxy.d.ts +4 -6
- package/dist/backends/codex/codex-mcp-proxy.d.ts.map +1 -1
- package/dist/backends/codex/codex-mcp-proxy.js.map +1 -1
- package/dist/backends/codex/mcp-preflight.d.ts +2 -2
- package/dist/backends/codex/mcp-preflight.d.ts.map +1 -1
- package/dist/backends/codex/mcp-preflight.js.map +1 -1
- package/dist/completion/advancement-stall-watchdog.d.ts +12 -0
- package/dist/completion/advancement-stall-watchdog.d.ts.map +1 -0
- package/dist/completion/advancement-stall-watchdog.js +79 -0
- package/dist/completion/advancement-stall-watchdog.js.map +1 -0
- package/dist/completion/arm-visible-progress-inputs.d.ts +51 -0
- package/dist/completion/arm-visible-progress-inputs.d.ts.map +1 -0
- package/dist/completion/arm-visible-progress-inputs.js +19 -0
- package/dist/completion/arm-visible-progress-inputs.js.map +1 -0
- package/dist/completion/completion-phase-registry.d.ts +1 -0
- package/dist/completion/completion-phase-registry.d.ts.map +1 -1
- package/dist/completion/completion-phase-registry.js +7 -5
- package/dist/completion/completion-phase-registry.js.map +1 -1
- package/dist/completion/delivery-advancement-guard.d.ts.map +1 -1
- package/dist/completion/delivery-advancement-guard.js +1 -0
- package/dist/completion/delivery-advancement-guard.js.map +1 -1
- package/dist/completion/escalation-provenance.d.ts.map +1 -1
- package/dist/completion/escalation-provenance.js +5 -2
- package/dist/completion/escalation-provenance.js.map +1 -1
- package/dist/completion/event-entry-phases.d.ts.map +1 -1
- package/dist/completion/event-entry-phases.js +9 -2
- package/dist/completion/event-entry-phases.js.map +1 -1
- package/dist/completion/event-phases.d.ts +15 -8
- package/dist/completion/event-phases.d.ts.map +1 -1
- package/dist/completion/event-phases.js +26 -64
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +7 -1
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/exit-classification.d.ts +1 -1
- package/dist/completion/exit-classification.d.ts.map +1 -1
- package/dist/completion/exit-classification.js +7 -1
- package/dist/completion/exit-classification.js.map +1 -1
- package/dist/completion/review-cycle-cap.d.ts +81 -35
- package/dist/completion/review-cycle-cap.d.ts.map +1 -1
- package/dist/completion/review-cycle-cap.js +60 -132
- package/dist/completion/review-cycle-cap.js.map +1 -1
- package/dist/completion/review-exit-deps.d.ts +3 -1
- package/dist/completion/review-exit-deps.d.ts.map +1 -1
- package/dist/completion/review-exit-deps.js +3 -1
- package/dist/completion/review-exit-deps.js.map +1 -1
- package/dist/completion/review-exit-phase.d.ts.map +1 -1
- package/dist/completion/review-exit-phase.js +5 -4
- package/dist/completion/review-exit-phase.js.map +1 -1
- package/dist/completion/shutdown-attribution.d.ts +107 -0
- package/dist/completion/shutdown-attribution.d.ts.map +1 -0
- package/dist/completion/shutdown-attribution.js +106 -0
- package/dist/completion/shutdown-attribution.js.map +1 -0
- package/dist/completion/state-cascade.d.ts.map +1 -1
- package/dist/completion/state-cascade.js +3 -7
- package/dist/completion/state-cascade.js.map +1 -1
- package/dist/completion/team-lifecycle.d.ts.map +1 -1
- package/dist/completion/team-lifecycle.js +16 -0
- package/dist/completion/team-lifecycle.js.map +1 -1
- package/dist/delivery/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery/delivery-lifecycle.js +1 -0
- package/dist/delivery/delivery-lifecycle.js.map +1 -1
- package/dist/directive/directive-assembly.d.ts +19 -1
- package/dist/directive/directive-assembly.d.ts.map +1 -1
- package/dist/directive/directive-assembly.js +15 -3
- package/dist/directive/directive-assembly.js.map +1 -1
- package/dist/directive/directive-dispatch.d.ts +67 -2
- package/dist/directive/directive-dispatch.d.ts.map +1 -1
- package/dist/directive/directive-dispatch.js +188 -45
- package/dist/directive/directive-dispatch.js.map +1 -1
- package/dist/directive/directive-executor.d.ts +2 -2
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +49 -12
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/directive/directive-queue.d.ts.map +1 -1
- package/dist/directive/directive-queue.js +1 -0
- package/dist/directive/directive-queue.js.map +1 -1
- package/dist/directive/stage-tracker.d.ts +20 -0
- package/dist/directive/stage-tracker.d.ts.map +1 -1
- package/dist/directive/stage-tracker.js +29 -1
- package/dist/directive/stage-tracker.js.map +1 -1
- package/dist/focus/focus-engine.d.ts +16 -0
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +42 -18
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/focus/focus-executor.d.ts.map +1 -1
- package/dist/focus/focus-executor.js +21 -3
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/focus-phase.d.ts +11 -1
- package/dist/focus/focus-phase.d.ts.map +1 -1
- package/dist/focus/focus-phase.js +12 -2
- package/dist/focus/focus-phase.js.map +1 -1
- package/dist/focus/focus-spawn-decision.d.ts +5 -3
- package/dist/focus/focus-spawn-decision.d.ts.map +1 -1
- package/dist/focus/focus-spawn-decision.js.map +1 -1
- package/dist/focus/focus-team-state.js +1 -1
- package/dist/focus/listener-auto-advance.d.ts.map +1 -1
- package/dist/focus/listener-auto-advance.js +1 -0
- package/dist/focus/listener-auto-advance.js.map +1 -1
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +37 -13
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus/listener.d.ts +15 -0
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +79 -17
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/live-arm-facts.d.ts +10 -0
- package/dist/focus/live-arm-facts.d.ts.map +1 -0
- package/dist/focus/live-arm-facts.js +47 -0
- package/dist/focus/live-arm-facts.js.map +1 -0
- package/dist/focus/recorded-new-intent.d.ts +81 -0
- package/dist/focus/recorded-new-intent.d.ts.map +1 -0
- package/dist/focus/recorded-new-intent.js +147 -0
- package/dist/focus/recorded-new-intent.js.map +1 -0
- package/dist/focus/review-cycle-cap-hold.d.ts +15 -94
- package/dist/focus/review-cycle-cap-hold.d.ts.map +1 -1
- package/dist/focus/review-cycle-cap-hold.js +54 -112
- package/dist/focus/review-cycle-cap-hold.js.map +1 -1
- package/dist/focus/session-health.d.ts +22 -1
- package/dist/focus/session-health.d.ts.map +1 -1
- package/dist/focus/session-health.js +28 -3
- package/dist/focus/session-health.js.map +1 -1
- package/dist/focus/session-process-reap.d.ts +3 -1
- package/dist/focus/session-process-reap.d.ts.map +1 -1
- package/dist/focus/session-process-reap.js +20 -0
- package/dist/focus/session-process-reap.js.map +1 -1
- package/dist/focus/stage-watermark-seeding.d.ts +39 -0
- package/dist/focus/stage-watermark-seeding.d.ts.map +1 -0
- package/dist/focus/stage-watermark-seeding.js +60 -0
- package/dist/focus/stage-watermark-seeding.js.map +1 -0
- package/dist/focus-stage-lifecycle/index.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/index.js +1 -0
- package/dist/focus-stage-lifecycle/index.js.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts +29 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.js +46 -6
- package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
- package/dist/git/focus-integration-sync.d.ts +42 -3
- package/dist/git/focus-integration-sync.d.ts.map +1 -1
- package/dist/git/focus-integration-sync.js +38 -2
- package/dist/git/focus-integration-sync.js.map +1 -1
- package/dist/merge/abandoned-merge-recovery.d.ts.map +1 -1
- package/dist/merge/abandoned-merge-recovery.js +10 -0
- package/dist/merge/abandoned-merge-recovery.js.map +1 -1
- package/dist/merge/merge-back-loop.d.ts +1 -0
- package/dist/merge/merge-back-loop.d.ts.map +1 -1
- package/dist/merge/merge-back-loop.js +3 -3
- package/dist/merge/merge-back-loop.js.map +1 -1
- package/dist/prompt/focus-prompt-builder.d.ts +2 -1
- package/dist/prompt/focus-prompt-builder.d.ts.map +1 -1
- package/dist/prompt/focus-prompt-builder.js +10 -1
- package/dist/prompt/focus-prompt-builder.js.map +1 -1
- package/dist/prompt/team-prompt-base.d.ts +2 -1
- package/dist/prompt/team-prompt-base.d.ts.map +1 -1
- package/dist/prompt/team-prompt-base.js +8 -20
- package/dist/prompt/team-prompt-base.js.map +1 -1
- package/dist/prompt-sections/execution-sections.d.ts +22 -1
- package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
- package/dist/prompt-sections/execution-sections.js +23 -2
- package/dist/prompt-sections/execution-sections.js.map +1 -1
- package/dist/prompt-sections/integration-reconcile-section.d.ts +45 -0
- package/dist/prompt-sections/integration-reconcile-section.d.ts.map +1 -0
- package/dist/prompt-sections/integration-reconcile-section.js +69 -0
- package/dist/prompt-sections/integration-reconcile-section.js.map +1 -0
- package/dist/prompt-sections/persona-sections.d.ts +0 -20
- package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
- package/dist/prompt-sections/persona-sections.js +4 -49
- package/dist/prompt-sections/persona-sections.js.map +1 -1
- package/dist/prompt-sections/shared.d.ts +9 -0
- package/dist/prompt-sections/shared.d.ts.map +1 -1
- package/dist/prompt-sections/shared.js +2 -1
- package/dist/prompt-sections/shared.js.map +1 -1
- package/dist/prompt-sections/testing-standard.d.ts +51 -0
- package/dist/prompt-sections/testing-standard.d.ts.map +1 -0
- package/dist/prompt-sections/testing-standard.js +132 -0
- package/dist/prompt-sections/testing-standard.js.map +1 -0
- package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
- package/dist/queries/agent-resolvable-promotion.js +7 -5
- package/dist/queries/agent-resolvable-promotion.js.map +1 -1
- package/dist/queries/arm-covered-targets.d.ts +84 -0
- package/dist/queries/arm-covered-targets.d.ts.map +1 -0
- package/dist/queries/arm-covered-targets.js +129 -0
- package/dist/queries/arm-covered-targets.js.map +1 -0
- package/dist/queries/deliveries.d.ts +3 -0
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +10 -3
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +10 -0
- package/dist/queries/delivery-gate-state.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state.js +1 -1
- package/dist/queries/delivery-gate-state.js.map +1 -1
- package/dist/queries/delivery-write-discipline.d.ts.map +1 -1
- package/dist/queries/delivery-write-discipline.js +2 -1
- package/dist/queries/delivery-write-discipline.js.map +1 -1
- package/dist/queries/directive-undelivered.d.ts +104 -0
- package/dist/queries/directive-undelivered.d.ts.map +1 -0
- package/dist/queries/directive-undelivered.js +162 -0
- package/dist/queries/directive-undelivered.js.map +1 -0
- package/dist/queries/ended-arm.d.ts +47 -0
- package/dist/queries/ended-arm.d.ts.map +1 -0
- package/dist/queries/ended-arm.js +35 -0
- package/dist/queries/ended-arm.js.map +1 -0
- package/dist/queries/escalation-consumption.d.ts.map +1 -1
- package/dist/queries/escalation-consumption.js +0 -1
- package/dist/queries/escalation-consumption.js.map +1 -1
- package/dist/queries/focus-discovery.d.ts +30 -0
- package/dist/queries/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focus-discovery.js +4 -0
- package/dist/queries/focus-discovery.js.map +1 -1
- package/dist/queries/focus-integration-conflict.d.ts +78 -0
- package/dist/queries/focus-integration-conflict.d.ts.map +1 -0
- package/dist/queries/focus-integration-conflict.js +136 -0
- package/dist/queries/focus-integration-conflict.js.map +1 -0
- package/dist/queries/focuses.d.ts +6 -3
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +14 -5
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/incident-correlation.d.ts +1 -2
- package/dist/queries/incident-correlation.d.ts.map +1 -1
- package/dist/queries/incident-correlation.js +1 -3
- package/dist/queries/incident-correlation.js.map +1 -1
- package/dist/queries/issues.d.ts.map +1 -1
- package/dist/queries/issues.js +1 -0
- package/dist/queries/issues.js.map +1 -1
- package/dist/queries/local-models.js +1 -1
- package/dist/queries/local-models.js.map +1 -1
- package/dist/queries/recorded-targets-record.d.ts +46 -0
- package/dist/queries/recorded-targets-record.d.ts.map +1 -0
- package/dist/queries/recorded-targets-record.js +29 -0
- package/dist/queries/recorded-targets-record.js.map +1 -0
- package/dist/queries/schemas-local-model.d.ts +47 -0
- package/dist/queries/schemas-local-model.d.ts.map +1 -0
- package/dist/queries/schemas-local-model.js +57 -0
- package/dist/queries/schemas-local-model.js.map +1 -0
- package/dist/queries/schemas.d.ts +14 -32
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +24 -41
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/sessions.d.ts +120 -12
- package/dist/queries/sessions.d.ts.map +1 -1
- package/dist/queries/sessions.js +104 -11
- package/dist/queries/sessions.js.map +1 -1
- package/dist/queries/shared.d.ts +1 -0
- package/dist/queries/shared.d.ts.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/shared.js.map +1 -1
- package/dist/queries/system-session.d.ts.map +1 -1
- package/dist/queries/system-session.js +3 -1
- package/dist/queries/system-session.js.map +1 -1
- package/dist/queries/verification.js +1 -1
- package/dist/queries/workflows.d.ts.map +1 -1
- package/dist/queries/workflows.js +1 -0
- package/dist/queries/workflows.js.map +1 -1
- package/dist/resolvers/assembly-engine.d.ts +33 -1
- package/dist/resolvers/assembly-engine.d.ts.map +1 -1
- package/dist/resolvers/assembly-engine.js +74 -23
- package/dist/resolvers/assembly-engine.js.map +1 -1
- package/dist/resolvers/compose/loop-delivery-index-compose.d.ts +23 -3
- package/dist/resolvers/compose/loop-delivery-index-compose.d.ts.map +1 -1
- package/dist/resolvers/compose/loop-delivery-index-compose.js +90 -43
- package/dist/resolvers/compose/loop-delivery-index-compose.js.map +1 -1
- package/dist/resolvers/delivery-listing.d.ts +27 -0
- package/dist/resolvers/delivery-listing.d.ts.map +1 -1
- package/dist/resolvers/delivery-listing.js +52 -36
- package/dist/resolvers/delivery-listing.js.map +1 -1
- package/dist/resolvers/loop-delivery-index.d.ts +8 -0
- package/dist/resolvers/loop-delivery-index.d.ts.map +1 -1
- package/dist/resolvers/loop-delivery-index.js +68 -7
- package/dist/resolvers/loop-delivery-index.js.map +1 -1
- package/dist/resolvers/shared/loop.d.ts +7 -0
- package/dist/resolvers/shared/loop.d.ts.map +1 -1
- package/dist/resolvers/shared/loop.js.map +1 -1
- package/dist/resolvers/wiki-topic.d.ts +6 -5
- package/dist/resolvers/wiki-topic.d.ts.map +1 -1
- package/dist/resolvers/wiki-topic.js +43 -27
- package/dist/resolvers/wiki-topic.js.map +1 -1
- package/dist/session/session-lineage.d.ts.map +1 -1
- package/dist/session/session-lineage.js +1 -0
- package/dist/session/session-lineage.js.map +1 -1
- package/dist/shell/crash-recovery.d.ts +4 -2
- package/dist/shell/crash-recovery.d.ts.map +1 -1
- package/dist/shell/crash-recovery.js +15 -14
- package/dist/shell/crash-recovery.js.map +1 -1
- package/dist/shell/daemon-instance.d.ts +176 -0
- package/dist/shell/daemon-instance.d.ts.map +1 -0
- package/dist/shell/daemon-instance.js +281 -0
- package/dist/shell/daemon-instance.js.map +1 -0
- package/dist/shell/graceful-shutdown.d.ts +12 -1
- package/dist/shell/graceful-shutdown.d.ts.map +1 -1
- package/dist/shell/graceful-shutdown.js +7 -4
- package/dist/shell/graceful-shutdown.js.map +1 -1
- package/dist/shell/shutdown-ownership.d.ts +34 -0
- package/dist/shell/shutdown-ownership.d.ts.map +1 -0
- package/dist/shell/shutdown-ownership.js +51 -0
- package/dist/shell/shutdown-ownership.js.map +1 -0
- package/dist/shell/unified-shell.d.ts.map +1 -1
- package/dist/shell/unified-shell.js +12 -5
- package/dist/shell/unified-shell.js.map +1 -1
- package/dist/shell/worker-pidfile.d.ts +127 -11
- package/dist/shell/worker-pidfile.d.ts.map +1 -1
- package/dist/shell/worker-pidfile.js +349 -58
- package/dist/shell/worker-pidfile.js.map +1 -1
- package/dist/spawn/helpers.d.ts.map +1 -1
- package/dist/spawn/helpers.js +4 -2
- package/dist/spawn/helpers.js.map +1 -1
- package/dist/spawn/lead-continuation.d.ts.map +1 -1
- package/dist/spawn/lead-continuation.js +8 -2
- package/dist/spawn/lead-continuation.js.map +1 -1
- package/dist/spawn/lead-launch.d.ts +17 -1
- package/dist/spawn/lead-launch.d.ts.map +1 -1
- package/dist/spawn/lead-launch.js +56 -7
- package/dist/spawn/lead-launch.js.map +1 -1
- package/dist/spawn/lead-process-ownership.d.ts +5 -4
- package/dist/spawn/lead-process-ownership.d.ts.map +1 -1
- package/dist/spawn/lead-process-ownership.js +7 -4
- package/dist/spawn/lead-process-ownership.js.map +1 -1
- package/dist/spawn/lead-send.d.ts +97 -0
- package/dist/spawn/lead-send.d.ts.map +1 -0
- package/dist/spawn/lead-send.js +80 -0
- package/dist/spawn/lead-send.js.map +1 -0
- package/dist/spawn/lifecycle.d.ts +0 -12
- package/dist/spawn/lifecycle.d.ts.map +1 -1
- package/dist/spawn/lifecycle.js +76 -19
- package/dist/spawn/lifecycle.js.map +1 -1
- package/dist/spawn/liveness.d.ts.map +1 -1
- package/dist/spawn/liveness.js +3 -1
- package/dist/spawn/liveness.js.map +1 -1
- package/dist/spawn/one-shot-process-ownership.d.ts +46 -2
- package/dist/spawn/one-shot-process-ownership.d.ts.map +1 -1
- package/dist/spawn/one-shot-process-ownership.js +78 -3
- package/dist/spawn/one-shot-process-ownership.js.map +1 -1
- package/dist/spawn/process-group-kill.d.ts.map +1 -1
- package/dist/spawn/process-group-kill.js +15 -2
- package/dist/spawn/process-group-kill.js.map +1 -1
- package/dist/spawn/process-spawn.d.ts +5 -15
- package/dist/spawn/process-spawn.d.ts.map +1 -1
- package/dist/spawn/process-spawn.js +8 -1
- package/dist/spawn/process-spawn.js.map +1 -1
- package/dist/spawn/prompt-assembly.d.ts +35 -2
- package/dist/spawn/prompt-assembly.d.ts.map +1 -1
- package/dist/spawn/prompt-assembly.js +67 -44
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts +25 -1
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +19 -3
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/spawn/worktree-session.d.ts +49 -2
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +59 -5
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/testing/fixtures/conflicting-repo.d.ts +30 -0
- package/dist/testing/fixtures/conflicting-repo.d.ts.map +1 -0
- package/dist/testing/fixtures/conflicting-repo.js +89 -0
- package/dist/testing/fixtures/conflicting-repo.js.map +1 -0
- package/dist/testing/fixtures/index.d.ts.map +1 -1
- package/dist/testing/fixtures/index.js +2 -1
- package/dist/testing/fixtures/index.js.map +1 -1
- package/dist/testing/fixtures/pending-spawn-world.js +2 -2
- package/dist/testing/fixtures/pending-spawn-world.js.map +1 -1
- package/dist/types/exit-category.d.ts +59 -0
- package/dist/types/exit-category.d.ts.map +1 -0
- package/dist/types/exit-category.js +133 -0
- package/dist/types/exit-category.js.map +1 -0
- package/dist/types/focus.d.ts +19 -0
- package/dist/types/focus.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/session.d.ts +5 -1
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/verify/injection-stamp.d.ts +30 -0
- package/dist/verify/injection-stamp.d.ts.map +1 -1
- package/dist/verify/injection-stamp.js +37 -1
- package/dist/verify/injection-stamp.js.map +1 -1
- package/dist/verify/recorded-targets.d.ts +103 -0
- package/dist/verify/recorded-targets.d.ts.map +1 -0
- package/dist/verify/recorded-targets.js +159 -0
- package/dist/verify/recorded-targets.js.map +1 -0
- package/dist/verify/stall-detector-config.d.ts +5 -1
- package/dist/verify/stall-detector-config.d.ts.map +1 -1
- package/dist/verify/stall-detector-config.js +5 -1
- package/dist/verify/stall-detector-config.js.map +1 -1
- package/dist/verify/verification-deps-default.d.ts.map +1 -1
- package/dist/verify/verification-deps-default.js +15 -2
- package/dist/verify/verification-deps-default.js.map +1 -1
- package/dist/verify/verification-deps.d.ts +17 -1
- package/dist/verify/verification-deps.d.ts.map +1 -1
- package/dist/verify/verification-engine.d.ts.map +1 -1
- package/dist/verify/verification-engine.js +51 -47
- package/dist/verify/verification-engine.js.map +1 -1
- package/dist/verify/verify-restatement.d.ts +27 -33
- package/dist/verify/verify-restatement.d.ts.map +1 -1
- package/dist/verify/verify-restatement.js +74 -1
- package/dist/verify/verify-restatement.js.map +1 -1
- package/dist/worktree/state.d.ts +75 -1
- package/dist/worktree/state.d.ts.map +1 -1
- package/dist/worktree/state.js +89 -17
- package/dist/worktree/state.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DeliveryArmCoveredTargets } from '../queries/arm-covered-targets.js';
|
|
1
2
|
import { type ReconcileInputs, type ReconcileJudgment, type ReconcileOptions, type VerifyEvidence } from './verify-reconciliation.js';
|
|
2
3
|
export type { VerifyEvidence } from './verify-reconciliation.js';
|
|
3
4
|
/**
|
|
@@ -72,44 +73,37 @@ export interface ReconcileTargetsResult {
|
|
|
72
73
|
* in any active tree (then restatements/shortfalls are both empty too).
|
|
73
74
|
*/
|
|
74
75
|
realityTreeId?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Targets this reconciliation DID NOT judge, because the focus's arm did not
|
|
78
|
+
* cover them: nodes added to the in-flight injection after the human armed,
|
|
79
|
+
* serving no effect the arm covers (see
|
|
80
|
+
* `supabase/functions/_shared/arm-covered-effects.ts`). They produce no
|
|
81
|
+
* shortfall, no hold and no re-work issue -- they wait for the next arm.
|
|
82
|
+
*
|
|
83
|
+
* Carried back rather than silently dropped so the caller can put them ON THE
|
|
84
|
+
* RECORD. What was set aside has to be visible somewhere, or narrowing the
|
|
85
|
+
* judgement becomes indistinguishable from losing track of it.
|
|
86
|
+
*
|
|
87
|
+
* Empty whenever the arm could not be reasoned about, which is also when
|
|
88
|
+
* every target is judged -- the two always agree.
|
|
89
|
+
*/
|
|
90
|
+
recordedTargetNodeIds?: string[];
|
|
75
91
|
}
|
|
76
92
|
export type ReconcileFn = (inputs: ReconcileInputs, opts?: ReconcileOptions) => Promise<ReconcileJudgment>;
|
|
77
93
|
export interface AuthorTargetRestatementsDeps {
|
|
78
94
|
callApi?: <T>(action: string, params?: Record<string, unknown>) => Promise<T>;
|
|
79
95
|
/** Reconciles declared-vs-achieved and classifies. Defaults to the verify-reconciliation helper. */
|
|
80
96
|
reconcile?: ReconcileFn;
|
|
97
|
+
/**
|
|
98
|
+
* Which of the delivery's injection targets the focus's CURRENT arm covers.
|
|
99
|
+
* Defaults to the product-api read (queries/arm-covered-targets.ts), which
|
|
100
|
+
* never throws and answers `null` when the arm cannot be reasoned about.
|
|
101
|
+
*
|
|
102
|
+
* `null` means JUDGE EVERYTHING -- the pre-change behaviour. This module
|
|
103
|
+
* never decides coverage itself: "covered" has one definition, edge-side,
|
|
104
|
+
* shared with the create path.
|
|
105
|
+
*/
|
|
106
|
+
readArmCoveredTargets?: (deliveryId: string) => Promise<DeliveryArmCoveredTargets | null>;
|
|
81
107
|
}
|
|
82
|
-
|
|
83
|
-
* Reconcile the achieved outcome against the declared desired effect for each
|
|
84
|
-
* UDE the injection targets.
|
|
85
|
-
*
|
|
86
|
-
* For each targeted UDE:
|
|
87
|
-
* - The DECLARED desired effect is the UDE's preserved `frtStatement` (intent
|
|
88
|
-
* of record). When absent, there is no declared intent to fall short of, so
|
|
89
|
-
* the achieved DE authored from evidence is treated as a match.
|
|
90
|
-
* - The ACHIEVED desired effect is authored from the supplied `evidence`
|
|
91
|
-
* (diff/tests/inspection), NOT from the UDE problem text.
|
|
92
|
-
* - The judgment classifies match / legitimate_divergence / shortfall.
|
|
93
|
-
*
|
|
94
|
-
* match / legitimate_divergence -> `restatements` (carried into verify).
|
|
95
|
-
* shortfall -> `shortfalls` (caller holds gate + escalates).
|
|
96
|
-
*
|
|
97
|
-
* Best-effort per target: a reconciliation FAILURE (model error / parse error)
|
|
98
|
-
* is treated as a SHORTFALL -- we cannot prove the achieved outcome realizes the
|
|
99
|
-
* declared intent, so we do not flip it and we surface it to a human. (This is
|
|
100
|
-
* the asymmetric-safe default: never flip what you could not reconcile.)
|
|
101
|
-
*
|
|
102
|
-
* SCOPE BOUNDARY (intentional): this reconciles ONLY the UDEs the injection
|
|
103
|
-
* DIRECTLY targets (its `targets` edges). Downstream consequences that resolve
|
|
104
|
-
* by causal PROPAGATION at verify are NOT reconciled here -- they have no
|
|
105
|
-
* declared DE to measure against, and their forward prose is authored by the
|
|
106
|
-
* injection-conditioned draft-assist loop (cascade-restatement.ts), not from raw
|
|
107
|
-
* code evidence. Verify flips their node_type but leaves verify_classification
|
|
108
|
-
* null; display falls back to the draft-assist frt_statement. See the matching
|
|
109
|
-
* note in graph-verification.ts (verifyInjectionImpl, Step 6).
|
|
110
|
-
*
|
|
111
|
-
* Returns empty result when focusId is null or the injection is not in the
|
|
112
|
-
* focus's active tree(s).
|
|
113
|
-
*/
|
|
114
|
-
export declare function authorTargetRestatements(injectionNodeId: string, focusId: string | null, evidence: VerifyEvidence, deps?: AuthorTargetRestatementsDeps, evidenceIncomplete?: boolean): Promise<ReconcileTargetsResult>;
|
|
108
|
+
export declare function authorTargetRestatements(injectionNodeId: string, focusId: string | null, evidence: VerifyEvidence, deps?: AuthorTargetRestatementsDeps, evidenceIncomplete?: boolean, deliveryId?: string | null): Promise<ReconcileTargetsResult>;
|
|
115
109
|
//# sourceMappingURL=verify-restatement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-restatement.d.ts","sourceRoot":"","sources":["../../src/verify/verify-restatement.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verify-restatement.d.ts","sourceRoot":"","sources":["../../src/verify/verify-restatement.ts"],"names":[],"mappings":"AAgDA,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EAErB,KAAK,cAAc,EACpB,MAAM,4BAA4B,CAAC;AAYpC,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,GAAG,uBAAuB,CAAC;IAClD,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,gEAAgE;IAChE,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;OAaG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE,gBAAgB,KACpB,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEhC,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9E,oGAAoG;IACpG,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAC;CAC3F;AAyGD,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,QAAQ,EAAE,cAAc,EACxB,IAAI,GAAE,4BAAiC,EACvC,kBAAkB,UAAQ,EAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAoHjC"}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
// packages/daemon/src/verify/shortfall-park.test.ts, packages/daemon/src/verify/shortfall-repeat.test.ts,
|
|
10
10
|
// packages/daemon/src/verify/shortfall-routing.test.ts,
|
|
11
11
|
// packages/daemon/src/verify/shortfall-rulings.test.ts,
|
|
12
|
+
// packages/daemon/src/verify/stamp-withholds-recorded-targets.test.ts,
|
|
13
|
+
// packages/daemon/src/verify/verification-deps-default.test.ts,
|
|
12
14
|
// packages/daemon/src/verify/verification-engine-rulings.test.ts,
|
|
13
15
|
// packages/daemon/src/verify/verification-feedback.test.ts,
|
|
14
16
|
// packages/daemon/src/verify/verify-restatement.test.ts
|
|
@@ -42,7 +44,10 @@
|
|
|
42
44
|
* @module verify-restatement
|
|
43
45
|
*/
|
|
44
46
|
import { callApi as defaultCallApi } from '../queries/shared.js';
|
|
47
|
+
import { readArmCoveredTargets as defaultReadArmCoveredTargets, heldTargetsOrAll, } from '../queries/arm-covered-targets.js';
|
|
45
48
|
import { reconcileAchievedEffect as defaultReconcile, judgeEvidenceIsEmpty, } from './verify-reconciliation.js';
|
|
49
|
+
import { createLogger } from '../shell/log.js';
|
|
50
|
+
const log = createLogger({ module: 'verify-restatement' });
|
|
46
51
|
/**
|
|
47
52
|
* Reconcile the achieved outcome against the declared desired effect for each
|
|
48
53
|
* UDE the injection targets.
|
|
@@ -74,13 +79,74 @@ import { reconcileAchievedEffect as defaultReconcile, judgeEvidenceIsEmpty, } fr
|
|
|
74
79
|
*
|
|
75
80
|
* Returns empty result when focusId is null or the injection is not in the
|
|
76
81
|
* focus's active tree(s).
|
|
82
|
+
*
|
|
83
|
+
* `deliveryId` (6th argument): supplied => the reconciliation is narrowed to
|
|
84
|
+
* the targets the focus's ARM COVERED (see narrowToArmCoverage); omitted =>
|
|
85
|
+
* every target is judged, as before. Optional so a caller with no delivery in
|
|
86
|
+
* hand behaves exactly as it did.
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* Which targets the focus's arm covers, resolved ONCE per reconciliation.
|
|
90
|
+
*
|
|
91
|
+
* Hoisted out of `authorTargetRestatements` so that function stays within its
|
|
92
|
+
* recorded size floor, and because the answer is a property of the DELIVERY and
|
|
93
|
+
* its focus -- not of any one tree the reconciliation happens to walk.
|
|
94
|
+
*
|
|
95
|
+
* `null` means JUDGE EVERYTHING: no delivery id was supplied, the read failed,
|
|
96
|
+
* or the arm could not be reasoned about. The gate never narrows what it judges
|
|
97
|
+
* on a question it could not answer.
|
|
77
98
|
*/
|
|
78
|
-
|
|
99
|
+
async function resolveArmCoverageForDelivery(deliveryId, deps) {
|
|
100
|
+
if (!deliveryId)
|
|
101
|
+
return null;
|
|
102
|
+
const read = deps.readArmCoveredTargets ?? defaultReadArmCoveredTargets;
|
|
103
|
+
return await read(deliveryId);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Narrow an injection's targets to the ones the arm COVERED, recording the rest
|
|
107
|
+
* on `result`, and return the held set.
|
|
108
|
+
*
|
|
109
|
+
* A target added to an in-flight injection after the human armed -- serving no
|
|
110
|
+
* effect the arm covers -- is not owed work: it produces no shortfall, no hold
|
|
111
|
+
* and no re-work issue, and waits for the next arm. It is recorded rather than
|
|
112
|
+
* dropped, so what was set aside is visible on the delivery's record instead of
|
|
113
|
+
* merely absent from it.
|
|
114
|
+
*
|
|
115
|
+
* The caller applies this BEFORE the evidence-blindness check, deliberately: a
|
|
116
|
+
* set-aside target must not make the bundle look unjudgeable either. With every
|
|
117
|
+
* target recorded there is nothing left to judge, so the evidence question does
|
|
118
|
+
* not arise and the caller flips exactly as it would with no targets at all.
|
|
119
|
+
*
|
|
120
|
+
* Mutates `result` rather than returning a pair because the recorded set
|
|
121
|
+
* accumulates across trees, and threading an accumulator through the walk buys
|
|
122
|
+
* nothing over the one write.
|
|
123
|
+
*/
|
|
124
|
+
function narrowToArmCoverage(injectionNodeId, edges, coverage, result) {
|
|
125
|
+
const targets = edges
|
|
126
|
+
.filter((e) => e.edgeType === 'targets' && e.fromNodeId === injectionNodeId)
|
|
127
|
+
.map((e) => e.toNodeId);
|
|
128
|
+
const { held, recorded, unclassified } = heldTargetsOrAll(targets, coverage);
|
|
129
|
+
if (recorded.length > 0) {
|
|
130
|
+
result.recordedTargetNodeIds = [...(result.recordedTargetNodeIds ?? []), ...recorded];
|
|
131
|
+
}
|
|
132
|
+
if (unclassified.length > 0) {
|
|
133
|
+
// The split was stale: the edge answered about a tree that did not yet
|
|
134
|
+
// carry these targets. They are judged (heldTargetsOrAll already put them
|
|
135
|
+
// in `held`); this line is so the race is visible rather than inferred
|
|
136
|
+
// from a target that is judged while the answer never mentioned it.
|
|
137
|
+
log.warn(`[verify] Arm coverage did not classify ${unclassified.length} target(s) the ` +
|
|
138
|
+
`reconciler resolved (${unclassified.join(', ')}) -- the split predates them. ` +
|
|
139
|
+
`Judging them, as a gate must when its own answer is stale.`);
|
|
140
|
+
}
|
|
141
|
+
return new Set(held);
|
|
142
|
+
}
|
|
143
|
+
export async function authorTargetRestatements(injectionNodeId, focusId, evidence, deps = {}, evidenceIncomplete = false, deliveryId) {
|
|
79
144
|
const callApi = deps.callApi ?? defaultCallApi;
|
|
80
145
|
const reconcile = deps.reconcile ?? defaultReconcile;
|
|
81
146
|
const result = { restatements: [], shortfalls: [] };
|
|
82
147
|
if (!focusId)
|
|
83
148
|
return result;
|
|
149
|
+
const coverage = await resolveArmCoverageForDelivery(deliveryId, deps);
|
|
84
150
|
const treesResp = await callApi('reality_tree_list', { focusId });
|
|
85
151
|
const trees = (treesResp.items ?? []).filter((t) => t.status === 'active');
|
|
86
152
|
for (const tree of trees) {
|
|
@@ -106,9 +172,14 @@ export async function authorTargetRestatements(injectionNodeId, focusId, evidenc
|
|
|
106
172
|
// the instrument-fault signal instead of running the model (which, blind or
|
|
107
173
|
// half-blind, would manufacture a shortfall). With no targets there is
|
|
108
174
|
// nothing to judge -- fall through and let the caller flip as before.
|
|
175
|
+
// Narrow to what the arm covered BEFORE anything is judged; see
|
|
176
|
+
// splitTargetsByCoverage.
|
|
177
|
+
const heldTargets = narrowToArmCoverage(injectionNodeId, edges, coverage, result);
|
|
109
178
|
const hasTarget = edges.some((e) => {
|
|
110
179
|
if (e.edgeType !== 'targets' || e.fromNodeId !== injectionNodeId)
|
|
111
180
|
return false;
|
|
181
|
+
if (!heldTargets.has(e.toNodeId))
|
|
182
|
+
return false;
|
|
112
183
|
const t = nodeById.get(e.toNodeId);
|
|
113
184
|
return !!t && t.nodeType === 'undesired_effect';
|
|
114
185
|
});
|
|
@@ -119,6 +190,8 @@ export async function authorTargetRestatements(injectionNodeId, focusId, evidenc
|
|
|
119
190
|
for (const e of edges) {
|
|
120
191
|
if (e.edgeType !== 'targets' || e.fromNodeId !== injectionNodeId)
|
|
121
192
|
continue;
|
|
193
|
+
if (!heldTargets.has(e.toNodeId))
|
|
194
|
+
continue; // recorded after the arm: not judged
|
|
122
195
|
const target = nodeById.get(e.toNodeId);
|
|
123
196
|
if (!target || target.nodeType !== 'undesired_effect')
|
|
124
197
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-restatement.js","sourceRoot":"","sources":["../../src/verify/verify-restatement.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,yFAAyF;AACzF,4FAA4F;AAC5F,sEAAsE;AACtE,6EAA6E;AAC7E,2DAA2D;AAC3D,kEAAkE;AAClE,kEAAkE;AAClE,4GAA4G;AAC5G,0DAA0D;AAC1D,0DAA0D;AAC1D,oEAAoE;AACpE,8DAA8D;AAC9D,0DAA0D;AAC1D,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,uBAAuB,IAAI,gBAAgB,EAC3C,oBAAoB,GAMrB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"verify-restatement.js","sourceRoot":"","sources":["../../src/verify/verify-restatement.ts"],"names":[],"mappings":"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"}
|
package/dist/worktree/state.d.ts
CHANGED
|
@@ -1,10 +1,69 @@
|
|
|
1
|
+
import { type SessionProcessLiveness } from '../shell/daemon-instance.js';
|
|
1
2
|
export interface WorktreeWriteReason {
|
|
2
3
|
code: string;
|
|
3
4
|
message: string;
|
|
4
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* What the focus's own session process was found to be, for a consumer that
|
|
8
|
+
* needs the INPUT rather than the answer.
|
|
9
|
+
*
|
|
10
|
+
* `not_read` means the question never arose (an in-memory team settled it, or
|
|
11
|
+
* there is no worktree); `no_session` means no active agent_sessions row claims
|
|
12
|
+
* this focus. The rest are the liveness verdict verbatim.
|
|
13
|
+
*/
|
|
14
|
+
export type WorktreeWriterLiveness = SessionProcessLiveness | 'no_session' | 'not_read';
|
|
5
15
|
export interface WorktreeWriteSignal {
|
|
16
|
+
/**
|
|
17
|
+
* Whether it is unsafe to write to this worktree right now.
|
|
18
|
+
*
|
|
19
|
+
* Deliberately WIDER than "a process is writing": it is true for a writer that
|
|
20
|
+
* was observed AND for content a write would destroy. A team that committed and
|
|
21
|
+
* died leaves a dirty tree with no writer in it, and the honest answer to "is
|
|
22
|
+
* anything writing" there is no -- but answering `false` would license a merge
|
|
23
|
+
* that clobbers that work, so the residue holds the gate. What it does NOT do is
|
|
24
|
+
* claim a writer: those two branches carry `provable: false`, and a reader that
|
|
25
|
+
* wants the literal writer state reads {@link processLiveness} instead.
|
|
26
|
+
*/
|
|
6
27
|
active: boolean;
|
|
7
28
|
reason: WorktreeWriteReason | null;
|
|
29
|
+
/**
|
|
30
|
+
* Whether this answer rests on OBSERVATION.
|
|
31
|
+
*
|
|
32
|
+
* `active` is a boolean because its consumers want one, but not every path to
|
|
33
|
+
* it is equally known. Three answers are OBSERVED: a live in-memory team, a
|
|
34
|
+
* verified live process, a missing worktree -- and, at the other end, a
|
|
35
|
+
* decidable session process over a tree with no residue at all, which is
|
|
36
|
+
* observed ABSENCE of a writer.
|
|
37
|
+
*
|
|
38
|
+
* An `active: true` drawn from repository RESIDUE is not, EVER. A dirty tree
|
|
39
|
+
* and a commit that landed seconds ago are things a writer LEFT; a team that
|
|
40
|
+
* committed and then died leaves exactly that HEAD and exactly that tree. So
|
|
41
|
+
* proving the session's process STOPPED does not upgrade its residue -- it
|
|
42
|
+
* makes the residue's writer more doubtful, not less. `provable` is false on
|
|
43
|
+
* every residue branch regardless of what the liveness read decided, and the
|
|
44
|
+
* remaining unknown is carried only into the quiescent answer, where a live
|
|
45
|
+
* child that has not written yet leaves the same clean tree.
|
|
46
|
+
*
|
|
47
|
+
* Rather than coerce that into a confident boolean, the signal says so. A
|
|
48
|
+
* consumer that acts DESTRUCTIVELY on `active: false` -- the merge-back gate --
|
|
49
|
+
* must require `provable` as well; a consumer that only reports may use
|
|
50
|
+
* `active` alone. A consumer asking the DIFFERENT question "could this focus's
|
|
51
|
+
* process be decided at all" wants {@link processLiveness}, not this: the
|
|
52
|
+
* abandoned-merge restore acts on a worktree that is necessarily dirty, so a
|
|
53
|
+
* flag that reads false for every dirty tree would spare every mid-merge
|
|
54
|
+
* worktree forever and the recovery would never run.
|
|
55
|
+
*/
|
|
56
|
+
provable: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The liveness verdict this answer was derived from, passed through unreduced.
|
|
59
|
+
*
|
|
60
|
+
* The reason it is here rather than re-read: crash recovery and this reader
|
|
61
|
+
* consume the same record with OPPOSITE safe directions -- recovery only ever
|
|
62
|
+
* withholds a write, while a reader treats an active row as positive proof.
|
|
63
|
+
* Neither can borrow the other's bias, so the record is read once and each
|
|
64
|
+
* consumer applies its own rule to the verdict itself.
|
|
65
|
+
*/
|
|
66
|
+
processLiveness: WorktreeWriterLiveness;
|
|
8
67
|
}
|
|
9
68
|
export interface WorktreeStateDeps {
|
|
10
69
|
hasActiveTeam: (focusId: string) => boolean;
|
|
@@ -17,6 +76,15 @@ export interface WorktreeStateDeps {
|
|
|
17
76
|
id: string;
|
|
18
77
|
status: string;
|
|
19
78
|
} | null>;
|
|
79
|
+
/**
|
|
80
|
+
* What that session's own team PROCESS is doing, from the host's durable lead
|
|
81
|
+
* record (shell/daemon-instance.ts). A row's status alone cannot answer "is
|
|
82
|
+
* this worktree being written": a stale `running` row outlives its team, and
|
|
83
|
+
* this reader treats an active row as positive proof of a writer -- the
|
|
84
|
+
* opposite safe direction from crash recovery, which only ever withholds a
|
|
85
|
+
* write. Both now read ONE record and apply their own direction to it.
|
|
86
|
+
*/
|
|
87
|
+
classifySessionProcess: (sessionId: string) => SessionProcessLiveness;
|
|
20
88
|
worktreeHasUncommittedChanges: (worktreePath: string) => boolean;
|
|
21
89
|
getLastCommitTimestampMs: (worktreePath: string) => number | null;
|
|
22
90
|
now?: () => number;
|
|
@@ -33,10 +101,16 @@ export interface WorktreeStateDeps {
|
|
|
33
101
|
* Order of checks (returns on first hit):
|
|
34
102
|
* 1. in-memory active team (non-terminal phase) -> active_team
|
|
35
103
|
* 2. no persistent worktree -> { active: false, no_worktree }
|
|
36
|
-
* 3. DB session row in active
|
|
104
|
+
* 3. DB session row in an active status AND its team process provably alive
|
|
105
|
+
* -> active_session (anything less falls through to the worktree's own evidence)
|
|
37
106
|
* 4. recent commit within threshold -> recent_commit
|
|
38
107
|
* 5. dirty worktree -> dirty_worktree
|
|
39
108
|
* 6. otherwise -> { active: false, null }
|
|
109
|
+
*
|
|
110
|
+
* Steps 4 and 5 answer from RESIDUE, so neither is ever `provable`: what they
|
|
111
|
+
* observe is that something wrote, which is not the question asked. Step 6 --
|
|
112
|
+
* observed absence, no residue at all -- is provable exactly when step 3 could
|
|
113
|
+
* decide the session's process.
|
|
40
114
|
*/
|
|
41
115
|
export declare function isWorktreeBeingWritten(focusId: string, opts?: {
|
|
42
116
|
recentCommitThresholdMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/worktree/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/worktree/state.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAuD,KAAK,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE/H,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,sBAAsB,GAAG,YAAY,GAAG,UAAU,CAAC;AAExF,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;OAUG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,eAAe,EAAE,sBAAsB,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5C,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACvD,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAChG,wBAAwB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC9F;;;;;;;OAOG;IACH,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,sBAAsB,CAAC;IACtE,6BAA6B,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;IACjE,wBAAwB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAClE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAwFD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,uBAAuB,CAAC,EAAE,MAAM,CAAA;CAAO,EAC/C,IAAI,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACpC,OAAO,CAAC,mBAAmB,CAAC,CAmF9B"}
|
package/dist/worktree/state.js
CHANGED
|
@@ -19,7 +19,8 @@ import { hasActiveTeam, getActiveTeams } from '../focus/focus-team-state.js';
|
|
|
19
19
|
import { getFocusWorktree } from '../focus/focus-worktree-state.js';
|
|
20
20
|
import { worktreeHasUncommittedChanges } from './safety.js';
|
|
21
21
|
import { runGitSync } from '../git/index.js';
|
|
22
|
-
import { getActiveSessionForFocus } from '../queries/sessions.js';
|
|
22
|
+
import { getActiveSessionForFocus, isActiveSessionStatus } from '../queries/sessions.js';
|
|
23
|
+
import { classifySessionProcess, defaultSessionProcessProbes } from '../shell/daemon-instance.js';
|
|
23
24
|
const DEFAULT_RECENT_COMMIT_THRESHOLD_MS = 30_000;
|
|
24
25
|
/**
|
|
25
26
|
* Read the unix-epoch milliseconds timestamp of the worktree's HEAD commit.
|
|
@@ -52,10 +53,58 @@ const defaultDeps = {
|
|
|
52
53
|
return { worktreePath: info.worktreePath, branchName: info.branchName };
|
|
53
54
|
},
|
|
54
55
|
getActiveSessionForFocus,
|
|
56
|
+
classifySessionProcess: (sessionId) => classifySessionProcess(sessionId, defaultSessionProcessProbes()),
|
|
55
57
|
worktreeHasUncommittedChanges,
|
|
56
58
|
getLastCommitTimestampMs: defaultGetLastCommitTimestampMs,
|
|
57
59
|
now: () => Date.now(),
|
|
58
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* What the focus's active session says about a writer.
|
|
63
|
+
*
|
|
64
|
+
* Returns a signal when the session settles it (a verified live process), or the
|
|
65
|
+
* VERDICT the fall-through must carry when it does not -- unreduced, because the
|
|
66
|
+
* residue checks below and the consumers past them ask different questions of it.
|
|
67
|
+
*/
|
|
68
|
+
async function sessionWriterSignal(focusId, d) {
|
|
69
|
+
// Test the SAME active-status set the query boundary filters on. The former
|
|
70
|
+
// local list here named only 'active' and 'starting', so a session in
|
|
71
|
+
// 'running' -- the status a team actually spends its life in, and one the
|
|
72
|
+
// server does return -- answered "not being written" for a worktree that was
|
|
73
|
+
// being written.
|
|
74
|
+
const session = await d.getActiveSessionForFocus(focusId);
|
|
75
|
+
if (!session || !isActiveSessionStatus(session.status))
|
|
76
|
+
return { liveness: 'no_session' };
|
|
77
|
+
// An active row is a CLAIM, not a writer. Ask the durable lead record whether
|
|
78
|
+
// this session's own process is actually running, so a stale row -- one whose
|
|
79
|
+
// team stopped, or whose pid the OS handed to something unrelated -- stops
|
|
80
|
+
// nominating an unrelated process as the writer of a quiescent worktree.
|
|
81
|
+
const liveness = d.classifySessionProcess(session.id);
|
|
82
|
+
if (liveness === 'alive') {
|
|
83
|
+
return {
|
|
84
|
+
signal: {
|
|
85
|
+
active: true,
|
|
86
|
+
provable: true,
|
|
87
|
+
processLiveness: 'alive',
|
|
88
|
+
reason: {
|
|
89
|
+
code: 'active_session',
|
|
90
|
+
message: `agent_sessions row ${session.id} is status=${session.status} and its team process is alive`,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// 'unprovable' falls through too, DELIBERATELY. Answering active:true there
|
|
96
|
+
// turned every unknown into a permanent writer -- a reservation whose daemon
|
|
97
|
+
// was hard-killed, an unreadable record -- and held the worktree open for
|
|
98
|
+
// nothing. The fix attempted then was to retract those records at boot, which
|
|
99
|
+
// erased the one piece of evidence a live post-spawn child had. So the record
|
|
100
|
+
// is kept (recovery still refuses to close an unprovable row, a write it can
|
|
101
|
+
// never take back) and THIS reader, which is asking about the worktree, reads
|
|
102
|
+
// the worktree. 'stopped' / 'no_process_recorded' fall through the same way, and
|
|
103
|
+
// the verdict rides along UNREDUCED rather than collapsed to a boolean here:
|
|
104
|
+
// the residue checks below and the consumers past them ask different questions
|
|
105
|
+
// of it, and the last attempt to pre-answer for all of them got both wrong.
|
|
106
|
+
return { liveness };
|
|
107
|
+
}
|
|
59
108
|
/**
|
|
60
109
|
* Observe whether a focus's worktree is currently being written.
|
|
61
110
|
*
|
|
@@ -68,20 +117,31 @@ const defaultDeps = {
|
|
|
68
117
|
* Order of checks (returns on first hit):
|
|
69
118
|
* 1. in-memory active team (non-terminal phase) -> active_team
|
|
70
119
|
* 2. no persistent worktree -> { active: false, no_worktree }
|
|
71
|
-
* 3. DB session row in active
|
|
120
|
+
* 3. DB session row in an active status AND its team process provably alive
|
|
121
|
+
* -> active_session (anything less falls through to the worktree's own evidence)
|
|
72
122
|
* 4. recent commit within threshold -> recent_commit
|
|
73
123
|
* 5. dirty worktree -> dirty_worktree
|
|
74
124
|
* 6. otherwise -> { active: false, null }
|
|
125
|
+
*
|
|
126
|
+
* Steps 4 and 5 answer from RESIDUE, so neither is ever `provable`: what they
|
|
127
|
+
* observe is that something wrote, which is not the question asked. Step 6 --
|
|
128
|
+
* observed absence, no residue at all -- is provable exactly when step 3 could
|
|
129
|
+
* decide the session's process.
|
|
75
130
|
*/
|
|
76
131
|
export async function isWorktreeBeingWritten(focusId, opts = {}, deps = {}) {
|
|
77
132
|
const d = { ...defaultDeps, ...deps };
|
|
78
133
|
const thresholdMs = opts.recentCommitThresholdMs ?? DEFAULT_RECENT_COMMIT_THRESHOLD_MS;
|
|
134
|
+
// The session's own verdict, carried into the residue tail below and out to the
|
|
135
|
+
// caller unreduced. 'not_read' until step 3 asks.
|
|
136
|
+
let liveness = 'not_read';
|
|
79
137
|
// 1. In-memory active team
|
|
80
138
|
if (d.hasActiveTeam(focusId)) {
|
|
81
139
|
const phase = d.getActiveTeamPhase(focusId);
|
|
82
140
|
if (phase !== null && phase !== 'shutting_down' && phase !== 'terminated') {
|
|
83
141
|
return {
|
|
84
142
|
active: true,
|
|
143
|
+
provable: true,
|
|
144
|
+
processLiveness: 'not_read',
|
|
85
145
|
reason: {
|
|
86
146
|
code: 'active_team',
|
|
87
147
|
message: `in-memory team phase=${phase}`,
|
|
@@ -94,27 +154,30 @@ export async function isWorktreeBeingWritten(focusId, opts = {}, deps = {}) {
|
|
|
94
154
|
if (!worktree) {
|
|
95
155
|
return {
|
|
96
156
|
active: false,
|
|
157
|
+
provable: true,
|
|
158
|
+
processLiveness: 'not_read',
|
|
97
159
|
reason: { code: 'no_worktree', message: 'focus has no worktree' },
|
|
98
160
|
};
|
|
99
161
|
}
|
|
100
|
-
// 3. Active DB session for this focus
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
return
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// 4. Recent commit
|
|
162
|
+
// 3. Active DB session for this focus.
|
|
163
|
+
const fromSession = await sessionWriterSignal(focusId, d);
|
|
164
|
+
if ('signal' in fromSession)
|
|
165
|
+
return fromSession.signal;
|
|
166
|
+
liveness = fromSession.liveness;
|
|
167
|
+
// 4. Recent commit -- residue, never an observation of a writer. This branch
|
|
168
|
+
// claimed `provable: true` outright at first, then borrowed the liveness read's
|
|
169
|
+
// certainty, and both were wrong the same way: a commit says something WROTE.
|
|
170
|
+
// Over a session proven STOPPED that points AWAY from a current writer -- the
|
|
171
|
+
// team committed and died, leaving this HEAD -- so borrowing made the most
|
|
172
|
+
// doubtful case read as the most certain one.
|
|
112
173
|
const lastCommitMs = d.getLastCommitTimestampMs(worktree.worktreePath);
|
|
113
174
|
if (lastCommitMs !== null) {
|
|
114
175
|
const ageMs = (d.now ?? Date.now)() - lastCommitMs;
|
|
115
176
|
if (ageMs >= 0 && ageMs <= thresholdMs) {
|
|
116
177
|
return {
|
|
117
178
|
active: true,
|
|
179
|
+
provable: false,
|
|
180
|
+
processLiveness: liveness,
|
|
118
181
|
reason: {
|
|
119
182
|
code: 'recent_commit',
|
|
120
183
|
message: `last commit ${ageMs}ms ago`,
|
|
@@ -122,17 +185,26 @@ export async function isWorktreeBeingWritten(focusId, opts = {}, deps = {}) {
|
|
|
122
185
|
};
|
|
123
186
|
}
|
|
124
187
|
}
|
|
125
|
-
// 5. Dirty worktree
|
|
188
|
+
// 5. Dirty worktree -- uncommitted content IS a writer's residue, but it does
|
|
189
|
+
// not say the writer is still there. A stopped team leaves the same tree, which
|
|
190
|
+
// is why a stopped session cannot make this answer provable either. The `active`
|
|
191
|
+
// still holds: that content is real, and a merge into it would clobber work.
|
|
126
192
|
if (d.worktreeHasUncommittedChanges(worktree.worktreePath)) {
|
|
127
193
|
return {
|
|
128
194
|
active: true,
|
|
195
|
+
provable: false,
|
|
196
|
+
processLiveness: liveness,
|
|
129
197
|
reason: {
|
|
130
198
|
code: 'dirty_worktree',
|
|
131
199
|
message: 'git status --porcelain non-empty',
|
|
132
200
|
},
|
|
133
201
|
};
|
|
134
202
|
}
|
|
135
|
-
// 6. Quiescent
|
|
136
|
-
|
|
203
|
+
// 6. Quiescent -- the one place the liveness read still lands. A decidable
|
|
204
|
+
// process over a tree with NO residue is observed absence of a writer; an
|
|
205
|
+
// undecidable one is not, because a live child that has not written yet leaves
|
|
206
|
+
// exactly this tree. This is also the only answer a destructive consumer acts
|
|
207
|
+
// ON, so making it unconditionally unprovable would wedge every merge-back.
|
|
208
|
+
return { active: false, provable: liveness !== 'unprovable', processLiveness: liveness, reason: null };
|
|
137
209
|
}
|
|
138
210
|
//# sourceMappingURL=state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/worktree/state.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,0FAA0F;AAC1F,gBAAgB;AAEhB;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/worktree/state.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telora/daemon",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.169",
|
|
4
4
|
"description": "Agent orchestration daemon for Telora - spawns and manages Claude Code instances",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
},
|
|
38
38
|
"//testRunner": "Uses Node.js built-in test runner (node:test) via tsx for TypeScript support. The root package uses Vitest; this is a deliberate choice for the daemon package to avoid framework dependencies. Test files live beside the modules they exercise (owner-directory layout); the runner discovers them recursively.",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@telora/daemon-core": "^0.2.
|
|
41
|
-
"@telora/mcp-products": "^0.22.
|
|
40
|
+
"@telora/daemon-core": "^0.2.99",
|
|
41
|
+
"@telora/mcp-products": "^0.22.157",
|
|
42
42
|
"commander": "^14.0.3",
|
|
43
43
|
"yaml": "^2.4.0",
|
|
44
44
|
"zod": "^4.3.6"
|