@openrig/cli 0.1.11 → 0.2.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/daemon/assets/openrig-activity-hook-relay.cjs +104 -0
- package/daemon/dist/adapters/claude-code-adapter.d.ts +14 -6
- package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-code-adapter.js +192 -60
- package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
- package/daemon/dist/adapters/claude-resume.d.ts +5 -0
- package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-resume.js +15 -2
- package/daemon/dist/adapters/claude-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-resume.d.ts +8 -1
- package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-resume.js +74 -5
- package/daemon/dist/adapters/codex-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts +11 -6
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +322 -34
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/terminal-adapter.d.ts +2 -1
- package/daemon/dist/adapters/terminal-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/terminal-adapter.js +7 -1
- package/daemon/dist/adapters/terminal-adapter.js.map +1 -1
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +53 -5
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/db/migrations/021_seat_handover_observability.d.ts +3 -0
- package/daemon/dist/db/migrations/021_seat_handover_observability.d.ts.map +1 -0
- package/daemon/dist/db/migrations/021_seat_handover_observability.js +11 -0
- package/daemon/dist/db/migrations/021_seat_handover_observability.js.map +1 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.d.ts +3 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.d.ts.map +1 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.js +7 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.js.map +1 -0
- package/daemon/dist/db/migrations/023_stream_items.d.ts +16 -0
- package/daemon/dist/db/migrations/023_stream_items.d.ts.map +1 -0
- package/daemon/dist/db/migrations/023_stream_items.js +37 -0
- package/daemon/dist/db/migrations/023_stream_items.js.map +1 -0
- package/daemon/dist/db/migrations/024_queue_items.d.ts +19 -0
- package/daemon/dist/db/migrations/024_queue_items.d.ts.map +1 -0
- package/daemon/dist/db/migrations/024_queue_items.js +52 -0
- package/daemon/dist/db/migrations/024_queue_items.js.map +1 -0
- package/daemon/dist/db/migrations/025_queue_transitions.d.ts +13 -0
- package/daemon/dist/db/migrations/025_queue_transitions.d.ts.map +1 -0
- package/daemon/dist/db/migrations/025_queue_transitions.js +28 -0
- package/daemon/dist/db/migrations/025_queue_transitions.js.map +1 -0
- package/daemon/dist/db/migrations/026_inbox_entries.d.ts +14 -0
- package/daemon/dist/db/migrations/026_inbox_entries.d.ts.map +1 -0
- package/daemon/dist/db/migrations/026_inbox_entries.js +35 -0
- package/daemon/dist/db/migrations/026_inbox_entries.js.map +1 -0
- package/daemon/dist/db/migrations/027_outbox_entries.d.ts +12 -0
- package/daemon/dist/db/migrations/027_outbox_entries.d.ts.map +1 -0
- package/daemon/dist/db/migrations/027_outbox_entries.js +30 -0
- package/daemon/dist/db/migrations/027_outbox_entries.js.map +1 -0
- package/daemon/dist/db/migrations/028_project_classifications.d.ts +26 -0
- package/daemon/dist/db/migrations/028_project_classifications.d.ts.map +1 -0
- package/daemon/dist/db/migrations/028_project_classifications.js +44 -0
- package/daemon/dist/db/migrations/028_project_classifications.js.map +1 -0
- package/daemon/dist/db/migrations/029_classifier_leases.d.ts +22 -0
- package/daemon/dist/db/migrations/029_classifier_leases.d.ts.map +1 -0
- package/daemon/dist/db/migrations/029_classifier_leases.js +41 -0
- package/daemon/dist/db/migrations/029_classifier_leases.js.map +1 -0
- package/daemon/dist/db/migrations/030_views_custom.d.ts +15 -0
- package/daemon/dist/db/migrations/030_views_custom.d.ts.map +1 -0
- package/daemon/dist/db/migrations/030_views_custom.js +27 -0
- package/daemon/dist/db/migrations/030_views_custom.js.map +1 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.d.ts +34 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.d.ts.map +1 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.js +59 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.js.map +1 -0
- package/daemon/dist/db/migrations/032_watchdog_history.d.ts +28 -0
- package/daemon/dist/db/migrations/032_watchdog_history.d.ts.map +1 -0
- package/daemon/dist/db/migrations/032_watchdog_history.js +46 -0
- package/daemon/dist/db/migrations/032_watchdog_history.js.map +1 -0
- package/daemon/dist/db/migrations/033_workflow_specs.d.ts +30 -0
- package/daemon/dist/db/migrations/033_workflow_specs.d.ts.map +1 -0
- package/daemon/dist/db/migrations/033_workflow_specs.js +50 -0
- package/daemon/dist/db/migrations/033_workflow_specs.js.map +1 -0
- package/daemon/dist/db/migrations/034_workflow_instances.d.ts +42 -0
- package/daemon/dist/db/migrations/034_workflow_instances.d.ts.map +1 -0
- package/daemon/dist/db/migrations/034_workflow_instances.js +63 -0
- package/daemon/dist/db/migrations/034_workflow_instances.js.map +1 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.d.ts +29 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.d.ts.map +1 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.js +48 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.js.map +1 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.d.ts +35 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.d.ts.map +1 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.js +43 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.js.map +1 -0
- package/daemon/dist/domain/agent-activity-store.d.ts +42 -0
- package/daemon/dist/domain/agent-activity-store.d.ts.map +1 -0
- package/daemon/dist/domain/agent-activity-store.js +177 -0
- package/daemon/dist/domain/agent-activity-store.js.map +1 -0
- package/daemon/dist/domain/agent-manifest.d.ts.map +1 -1
- package/daemon/dist/domain/agent-manifest.js +3 -0
- package/daemon/dist/domain/agent-manifest.js.map +1 -1
- package/daemon/dist/domain/agent-starter-resolver.d.ts +100 -0
- package/daemon/dist/domain/agent-starter-resolver.d.ts.map +1 -0
- package/daemon/dist/domain/agent-starter-resolver.js +200 -0
- package/daemon/dist/domain/agent-starter-resolver.js.map +1 -0
- package/daemon/dist/domain/classifier-lease-manager.d.ts +130 -0
- package/daemon/dist/domain/classifier-lease-manager.d.ts.map +1 -0
- package/daemon/dist/domain/classifier-lease-manager.js +285 -0
- package/daemon/dist/domain/classifier-lease-manager.js.map +1 -0
- package/daemon/dist/domain/codex-thread-id.d.ts.map +1 -1
- package/daemon/dist/domain/codex-thread-id.js +44 -15
- package/daemon/dist/domain/codex-thread-id.js.map +1 -1
- package/daemon/dist/domain/context-monitor.d.ts +12 -7
- package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
- package/daemon/dist/domain/context-monitor.js +51 -3
- package/daemon/dist/domain/context-monitor.js.map +1 -1
- package/daemon/dist/domain/context-usage-store.d.ts +1 -1
- package/daemon/dist/domain/context-usage-store.js +1 -1
- package/daemon/dist/domain/context-usage-store.js.map +1 -1
- package/daemon/dist/domain/hot-potato-enforcer.d.ts +45 -0
- package/daemon/dist/domain/hot-potato-enforcer.d.ts.map +1 -0
- package/daemon/dist/domain/hot-potato-enforcer.js +94 -0
- package/daemon/dist/domain/hot-potato-enforcer.js.map +1 -0
- package/daemon/dist/domain/inbox-handler.d.ts +68 -0
- package/daemon/dist/domain/inbox-handler.d.ts.map +1 -0
- package/daemon/dist/domain/inbox-handler.js +177 -0
- package/daemon/dist/domain/inbox-handler.js.map +1 -0
- package/daemon/dist/domain/native-resume-probe.d.ts +1 -1
- package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
- package/daemon/dist/domain/native-resume-probe.js +89 -4
- package/daemon/dist/domain/native-resume-probe.js.map +1 -1
- package/daemon/dist/domain/node-inventory.d.ts +29 -1
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +208 -31
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/node-launcher.d.ts +2 -0
- package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/node-launcher.js +14 -2
- package/daemon/dist/domain/node-launcher.js.map +1 -1
- package/daemon/dist/domain/outbox-handler.d.ts +48 -0
- package/daemon/dist/domain/outbox-handler.d.ts.map +1 -0
- package/daemon/dist/domain/outbox-handler.js +106 -0
- package/daemon/dist/domain/outbox-handler.js.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.d.ts +64 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.d.ts.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.js +226 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.js.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.d.ts +3 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.d.ts.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.js +41 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.js.map +1 -0
- package/daemon/dist/domain/policies/edge-artifact-required.d.ts +3 -0
- package/daemon/dist/domain/policies/edge-artifact-required.d.ts.map +1 -0
- package/daemon/dist/domain/policies/edge-artifact-required.js +90 -0
- package/daemon/dist/domain/policies/edge-artifact-required.js.map +1 -0
- package/daemon/dist/domain/policies/periodic-reminder.d.ts +3 -0
- package/daemon/dist/domain/policies/periodic-reminder.d.ts.map +1 -0
- package/daemon/dist/domain/policies/periodic-reminder.js +30 -0
- package/daemon/dist/domain/policies/periodic-reminder.js.map +1 -0
- package/daemon/dist/domain/policies/types.d.ts +51 -0
- package/daemon/dist/domain/policies/types.d.ts.map +1 -0
- package/daemon/dist/domain/policies/types.js +9 -0
- package/daemon/dist/domain/policies/types.js.map +1 -0
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts +7 -0
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -0
- package/daemon/dist/domain/policies/workflow-keepalive.js +123 -0
- package/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -0
- package/daemon/dist/domain/project-classifier.d.ts +75 -0
- package/daemon/dist/domain/project-classifier.d.ts.map +1 -0
- package/daemon/dist/domain/project-classifier.js +132 -0
- package/daemon/dist/domain/project-classifier.js.map +1 -0
- package/daemon/dist/domain/projection-planner.d.ts +1 -0
- package/daemon/dist/domain/projection-planner.d.ts.map +1 -1
- package/daemon/dist/domain/projection-planner.js +3 -0
- package/daemon/dist/domain/projection-planner.js.map +1 -1
- package/daemon/dist/domain/ps-projection.d.ts +31 -0
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +38 -0
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +322 -0
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -0
- package/daemon/dist/domain/queue-repository.js +686 -0
- package/daemon/dist/domain/queue-repository.js.map +1 -0
- package/daemon/dist/domain/queue-transition-log.d.ts +38 -0
- package/daemon/dist/domain/queue-transition-log.d.ts.map +1 -0
- package/daemon/dist/domain/queue-transition-log.js +52 -0
- package/daemon/dist/domain/queue-transition-log.js.map +1 -0
- package/daemon/dist/domain/restore-check-service.d.ts +203 -0
- package/daemon/dist/domain/restore-check-service.d.ts.map +1 -0
- package/daemon/dist/domain/restore-check-service.js +1047 -0
- package/daemon/dist/domain/restore-check-service.js.map +1 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts +50 -2
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +476 -24
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/resume-metadata-refresher.d.ts.map +1 -1
- package/daemon/dist/domain/resume-metadata-refresher.js +27 -7
- package/daemon/dist/domain/resume-metadata-refresher.js.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.js +13 -0
- package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
- package/daemon/dist/domain/rig-repository.d.ts +17 -1
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +63 -5
- package/daemon/dist/domain/rig-repository.js.map +1 -1
- package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-codec.js +13 -0
- package/daemon/dist/domain/rigspec-codec.js.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.js +2 -0
- package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.js +63 -1
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-schema.js +196 -0
- package/daemon/dist/domain/rigspec-schema.js.map +1 -1
- package/daemon/dist/domain/runtime-adapter.d.ts +30 -1
- package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/domain/runtime-adapter.js +14 -0
- package/daemon/dist/domain/runtime-adapter.js.map +1 -1
- package/daemon/dist/domain/seat-handover-planner.d.ts +84 -0
- package/daemon/dist/domain/seat-handover-planner.d.ts.map +1 -0
- package/daemon/dist/domain/seat-handover-planner.js +188 -0
- package/daemon/dist/domain/seat-handover-planner.js.map +1 -0
- package/daemon/dist/domain/seat-handover-service.d.ts +104 -0
- package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -0
- package/daemon/dist/domain/seat-handover-service.js +343 -0
- package/daemon/dist/domain/seat-handover-service.js.map +1 -0
- package/daemon/dist/domain/seat-status-service.d.ts +50 -0
- package/daemon/dist/domain/seat-status-service.d.ts.map +1 -0
- package/daemon/dist/domain/seat-status-service.js +66 -0
- package/daemon/dist/domain/seat-status-service.js.map +1 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.d.ts +53 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.d.ts.map +1 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.js +59 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.js.map +1 -0
- package/daemon/dist/domain/session-transport.d.ts +30 -0
- package/daemon/dist/domain/session-transport.d.ts.map +1 -1
- package/daemon/dist/domain/session-transport.js +322 -12
- package/daemon/dist/domain/session-transport.js.map +1 -1
- package/daemon/dist/domain/snapshot-repository.d.ts +18 -0
- package/daemon/dist/domain/snapshot-repository.d.ts.map +1 -1
- package/daemon/dist/domain/snapshot-repository.js +77 -0
- package/daemon/dist/domain/snapshot-repository.js.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.d.ts +27 -3
- package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.js +125 -40
- package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
- package/daemon/dist/domain/stream-store.d.ts +56 -0
- package/daemon/dist/domain/stream-store.d.ts.map +1 -0
- package/daemon/dist/domain/stream-store.js +108 -0
- package/daemon/dist/domain/stream-store.js.map +1 -0
- package/daemon/dist/domain/transcript-redaction.d.ts +13 -0
- package/daemon/dist/domain/transcript-redaction.d.ts.map +1 -0
- package/daemon/dist/domain/transcript-redaction.js +34 -0
- package/daemon/dist/domain/transcript-redaction.js.map +1 -0
- package/daemon/dist/domain/transcript-store.d.ts +15 -0
- package/daemon/dist/domain/transcript-store.d.ts.map +1 -1
- package/daemon/dist/domain/transcript-store.js +76 -1
- package/daemon/dist/domain/transcript-store.js.map +1 -1
- package/daemon/dist/domain/types.d.ts +323 -3
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/view-event-bridge.d.ts +12 -0
- package/daemon/dist/domain/view-event-bridge.d.ts.map +1 -0
- package/daemon/dist/domain/view-event-bridge.js +92 -0
- package/daemon/dist/domain/view-event-bridge.js.map +1 -0
- package/daemon/dist/domain/view-projector.d.ts +83 -0
- package/daemon/dist/domain/view-projector.d.ts.map +1 -0
- package/daemon/dist/domain/view-projector.js +296 -0
- package/daemon/dist/domain/view-projector.js.map +1 -0
- package/daemon/dist/domain/watchdog-history-log.d.ts +49 -0
- package/daemon/dist/domain/watchdog-history-log.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-history-log.js +67 -0
- package/daemon/dist/domain/watchdog-history-log.js.map +1 -0
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts +81 -0
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-jobs-repository.js +164 -0
- package/daemon/dist/domain/watchdog-jobs-repository.js.map +1 -0
- package/daemon/dist/domain/watchdog-policy-engine.d.ts +92 -0
- package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-policy-engine.js +442 -0
- package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -0
- package/daemon/dist/domain/watchdog-scheduler.d.ts +76 -0
- package/daemon/dist/domain/watchdog-scheduler.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-scheduler.js +112 -0
- package/daemon/dist/domain/watchdog-scheduler.js.map +1 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts +46 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-instance-store.js +116 -0
- package/daemon/dist/domain/workflow-instance-store.js.map +1 -0
- package/daemon/dist/domain/workflow-projector.d.ts +64 -0
- package/daemon/dist/domain/workflow-projector.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-projector.js +424 -0
- package/daemon/dist/domain/workflow-projector.js.map +1 -0
- package/daemon/dist/domain/workflow-runtime.d.ts +63 -0
- package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-runtime.js +150 -0
- package/daemon/dist/domain/workflow-runtime.js.map +1 -0
- package/daemon/dist/domain/workflow-spec-cache.d.ts +35 -0
- package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-spec-cache.js +171 -0
- package/daemon/dist/domain/workflow-spec-cache.js.map +1 -0
- package/daemon/dist/domain/workflow-step-trail-log.d.ts +27 -0
- package/daemon/dist/domain/workflow-step-trail-log.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-step-trail-log.js +73 -0
- package/daemon/dist/domain/workflow-step-trail-log.js.map +1 -0
- package/daemon/dist/domain/workflow-types.d.ts +108 -0
- package/daemon/dist/domain/workflow-types.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-types.js +11 -0
- package/daemon/dist/domain/workflow-types.js.map +1 -0
- package/daemon/dist/domain/workflow-validator.d.ts +31 -0
- package/daemon/dist/domain/workflow-validator.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-validator.js +115 -0
- package/daemon/dist/domain/workflow-validator.js.map +1 -0
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +21 -2
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/activity.d.ts +3 -0
- package/daemon/dist/routes/activity.d.ts.map +1 -0
- package/daemon/dist/routes/activity.js +47 -0
- package/daemon/dist/routes/activity.js.map +1 -0
- package/daemon/dist/routes/projects.d.ts +12 -0
- package/daemon/dist/routes/projects.d.ts.map +1 -0
- package/daemon/dist/routes/projects.js +178 -0
- package/daemon/dist/routes/projects.js.map +1 -0
- package/daemon/dist/routes/queue.d.ts +10 -0
- package/daemon/dist/routes/queue.d.ts.map +1 -0
- package/daemon/dist/routes/queue.js +374 -0
- package/daemon/dist/routes/queue.js.map +1 -0
- package/daemon/dist/routes/restore-check.d.ts +3 -0
- package/daemon/dist/routes/restore-check.d.ts.map +1 -0
- package/daemon/dist/routes/restore-check.js +200 -0
- package/daemon/dist/routes/restore-check.js.map +1 -0
- package/daemon/dist/routes/rigs.d.ts.map +1 -1
- package/daemon/dist/routes/rigs.js +60 -4
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/seat.d.ts +3 -0
- package/daemon/dist/routes/seat.d.ts.map +1 -0
- package/daemon/dist/routes/seat.js +69 -0
- package/daemon/dist/routes/seat.js.map +1 -0
- package/daemon/dist/routes/sessions.d.ts.map +1 -1
- package/daemon/dist/routes/sessions.js +41 -5
- package/daemon/dist/routes/sessions.js.map +1 -1
- package/daemon/dist/routes/snapshots.js +66 -17
- package/daemon/dist/routes/snapshots.js.map +1 -1
- package/daemon/dist/routes/stream.d.ts +9 -0
- package/daemon/dist/routes/stream.d.ts.map +1 -0
- package/daemon/dist/routes/stream.js +119 -0
- package/daemon/dist/routes/stream.js.map +1 -0
- package/daemon/dist/routes/transcripts.d.ts.map +1 -1
- package/daemon/dist/routes/transcripts.js +38 -0
- package/daemon/dist/routes/transcripts.js.map +1 -1
- package/daemon/dist/routes/transport.d.ts.map +1 -1
- package/daemon/dist/routes/transport.js +21 -0
- package/daemon/dist/routes/transport.js.map +1 -1
- package/daemon/dist/routes/up.js +24 -3
- package/daemon/dist/routes/up.js.map +1 -1
- package/daemon/dist/routes/views.d.ts +13 -0
- package/daemon/dist/routes/views.d.ts.map +1 -0
- package/daemon/dist/routes/views.js +120 -0
- package/daemon/dist/routes/views.js.map +1 -0
- package/daemon/dist/routes/watchdog.d.ts +18 -0
- package/daemon/dist/routes/watchdog.d.ts.map +1 -0
- package/daemon/dist/routes/watchdog.js +148 -0
- package/daemon/dist/routes/watchdog.js.map +1 -0
- package/daemon/dist/routes/workflow.d.ts +20 -0
- package/daemon/dist/routes/workflow.d.ts.map +1 -0
- package/daemon/dist/routes/workflow.js +184 -0
- package/daemon/dist/routes/workflow.js.map +1 -0
- package/daemon/dist/server.d.ts +30 -0
- package/daemon/dist/server.d.ts.map +1 -1
- package/daemon/dist/server.js +33 -0
- package/daemon/dist/server.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +202 -8
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-spec.md +12 -5
- package/daemon/docs/reference/agent-startup-guide.md +9 -9
- package/daemon/specs/agents/apps/vault-specialist/agent.yaml +1 -1
- package/daemon/specs/agents/design/product-designer/agent.yaml +1 -1
- package/daemon/specs/agents/development/implementer/agent.yaml +1 -1
- package/daemon/specs/agents/development/qa/agent.yaml +1 -1
- package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +1 -1
- package/daemon/specs/agents/product-management/pm/agent.yaml +4 -0
- package/daemon/specs/agents/research/analyst/agent.yaml +1 -1
- package/daemon/specs/agents/research/synthesizer/agent.yaml +1 -1
- package/daemon/specs/agents/review/independent-reviewer/agent.yaml +1 -1
- package/daemon/specs/agents/shared/agent.yaml +17 -0
- package/daemon/specs/agents/shared/runtime/claude-mcp.fragment.json +12 -0
- package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +16 -0
- package/daemon/specs/agents/shared/runtime/codex-config.fragment.toml +5 -0
- package/daemon/specs/agents/shared/skills/claude-compact-in-place/SKILL.md +100 -0
- package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +110 -0
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +44 -1
- package/daemon/specs/agents/shared/skills/mental-model-ha/SKILL.md +3 -0
- package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +3 -0
- package/dist/commands/capture.d.ts +7 -1
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +59 -1
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/compact-plan.d.ts +9 -0
- package/dist/commands/compact-plan.d.ts.map +1 -0
- package/dist/commands/compact-plan.js +354 -0
- package/dist/commands/compact-plan.js.map +1 -0
- package/dist/commands/context.d.ts +9 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +220 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +19 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/expand.d.ts.map +1 -1
- package/dist/commands/expand.js +15 -4
- package/dist/commands/expand.js.map +1 -1
- package/dist/commands/heartbeat.d.ts +99 -0
- package/dist/commands/heartbeat.d.ts.map +1 -0
- package/dist/commands/heartbeat.js +393 -0
- package/dist/commands/heartbeat.js.map +1 -0
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +2 -1
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/preflight.js +1 -1
- package/dist/commands/preflight.js.map +1 -1
- package/dist/commands/project.d.ts +14 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +157 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/ps.d.ts +20 -3
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +455 -33
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +16 -0
- package/dist/commands/queue.d.ts.map +1 -0
- package/dist/commands/queue.js +401 -0
- package/dist/commands/queue.js.map +1 -0
- package/dist/commands/restore-check.d.ts +9 -0
- package/dist/commands/restore-check.d.ts.map +1 -0
- package/dist/commands/restore-check.js +234 -0
- package/dist/commands/restore-check.js.map +1 -0
- package/dist/commands/restore-packet.d.ts +9 -0
- package/dist/commands/restore-packet.d.ts.map +1 -0
- package/dist/commands/restore-packet.js +383 -0
- package/dist/commands/restore-packet.js.map +1 -0
- package/dist/commands/restore.d.ts.map +1 -1
- package/dist/commands/restore.js +69 -1
- package/dist/commands/restore.js.map +1 -1
- package/dist/commands/seat.d.ts +5 -0
- package/dist/commands/seat.d.ts.map +1 -0
- package/dist/commands/seat.js +170 -0
- package/dist/commands/seat.js.map +1 -0
- package/dist/commands/send.d.ts +12 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +93 -5
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +20 -8
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/specs.d.ts.map +1 -1
- package/dist/commands/specs.js +99 -16
- package/dist/commands/specs.js.map +1 -1
- package/dist/commands/stream.d.ts +12 -0
- package/dist/commands/stream.d.ts.map +1 -0
- package/dist/commands/stream.js +111 -0
- package/dist/commands/stream.js.map +1 -0
- package/dist/commands/up.d.ts +1 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +65 -4
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/view.d.ts +12 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +82 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/commands/watchdog.d.ts +15 -0
- package/dist/commands/watchdog.d.ts.map +1 -0
- package/dist/commands/watchdog.js +120 -0
- package/dist/commands/watchdog.js.map +1 -0
- package/dist/commands/whoami.d.ts +8 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +60 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workflow.d.ts +17 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +138 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/cross-host-cli-helpers.d.ts +12 -0
- package/dist/cross-host-cli-helpers.d.ts.map +1 -0
- package/dist/cross-host-cli-helpers.js +48 -0
- package/dist/cross-host-cli-helpers.js.map +1 -0
- package/dist/cross-host-executor.d.ts +84 -0
- package/dist/cross-host-executor.d.ts.map +1 -0
- package/dist/cross-host-executor.js +138 -0
- package/dist/cross-host-executor.js.map +1 -0
- package/dist/host-registry.d.ts +50 -0
- package/dist/host-registry.d.ts.map +1 -0
- package/dist/host-registry.js +116 -0
- package/dist/host-registry.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +22 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/restore-packet/claude-transcript-parser.d.ts +12 -0
- package/dist/restore-packet/claude-transcript-parser.d.ts.map +1 -0
- package/dist/restore-packet/claude-transcript-parser.js +221 -0
- package/dist/restore-packet/claude-transcript-parser.js.map +1 -0
- package/dist/restore-packet/codex-jsonl-parser.d.ts +11 -0
- package/dist/restore-packet/codex-jsonl-parser.d.ts.map +1 -0
- package/dist/restore-packet/codex-jsonl-parser.js +159 -0
- package/dist/restore-packet/codex-jsonl-parser.js.map +1 -0
- package/dist/restore-packet/omitted-records.d.ts +60 -0
- package/dist/restore-packet/omitted-records.d.ts.map +1 -0
- package/dist/restore-packet/omitted-records.js +116 -0
- package/dist/restore-packet/omitted-records.js.map +1 -0
- package/dist/restore-packet/packet-writer.d.ts +59 -0
- package/dist/restore-packet/packet-writer.d.ts.map +1 -0
- package/dist/restore-packet/packet-writer.js +224 -0
- package/dist/restore-packet/packet-writer.js.map +1 -0
- package/dist/restore-packet/redaction.d.ts +30 -0
- package/dist/restore-packet/redaction.d.ts.map +1 -0
- package/dist/restore-packet/redaction.js +71 -0
- package/dist/restore-packet/redaction.js.map +1 -0
- package/dist/restore-packet/runtime-detect.d.ts +19 -0
- package/dist/restore-packet/runtime-detect.d.ts.map +1 -0
- package/dist/restore-packet/runtime-detect.js +81 -0
- package/dist/restore-packet/runtime-detect.js.map +1 -0
- package/dist/restore-packet/schema-validator.d.ts +13 -0
- package/dist/restore-packet/schema-validator.d.ts.map +1 -0
- package/dist/restore-packet/schema-validator.js +245 -0
- package/dist/restore-packet/schema-validator.js.map +1 -0
- package/dist/restore-packet/types.d.ts +76 -0
- package/dist/restore-packet/types.d.ts.map +1 -0
- package/dist/restore-packet/types.js +15 -0
- package/dist/restore-packet/types.js.map +1 -0
- package/dist/schemas/restore-summary.schema.json +98 -0
- package/dist/system-preflight.d.ts.map +1 -1
- package/dist/system-preflight.js +16 -5
- package/dist/system-preflight.js.map +1 -1
- package/dist/tmux-health.d.ts +16 -0
- package/dist/tmux-health.d.ts.map +1 -0
- package/dist/tmux-health.js +105 -0
- package/dist/tmux-health.js.map +1 -0
- package/package.json +10 -3
- package/scripts/check-abi.mjs +123 -0
- package/ui/dist/assets/{index-DlMH-REm.css → index-Dec25siz.css} +1 -1
- package/ui/dist/assets/{index-lEO-zBxz.js → index-GNYaWmBj.js} +9 -9
- package/ui/dist/index.html +2 -2
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
import type { WorkflowInstance, WorkflowInstanceStatus } from "./workflow-types.js";
|
|
3
|
+
export interface CreateWorkflowInstanceInput {
|
|
4
|
+
workflowName: string;
|
|
5
|
+
workflowVersion: string;
|
|
6
|
+
createdBySession: string;
|
|
7
|
+
initialFrontier?: string[];
|
|
8
|
+
/** R2: durable current-step binding set at instantiate time. */
|
|
9
|
+
currentStepId?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class WorkflowInstanceError extends Error {
|
|
12
|
+
readonly code: string;
|
|
13
|
+
readonly details?: Record<string, unknown> | undefined;
|
|
14
|
+
constructor(code: string, message: string, details?: Record<string, unknown> | undefined);
|
|
15
|
+
}
|
|
16
|
+
export declare class WorkflowInstanceStore {
|
|
17
|
+
private readonly db;
|
|
18
|
+
private readonly now;
|
|
19
|
+
constructor(db: Database.Database, now?: () => Date);
|
|
20
|
+
create(input: CreateWorkflowInstanceInput): WorkflowInstance;
|
|
21
|
+
getById(instanceId: string): WorkflowInstance | null;
|
|
22
|
+
getByIdOrThrow(instanceId: string): WorkflowInstance;
|
|
23
|
+
listByStatus(status: WorkflowInstanceStatus): WorkflowInstance[];
|
|
24
|
+
listAll(): WorkflowInstance[];
|
|
25
|
+
/**
|
|
26
|
+
* Update frontier + status atomically. Caller is responsible for
|
|
27
|
+
* wrapping in a transaction when this needs to compose with other
|
|
28
|
+
* mutations (e.g., workflow-projector folds this into the
|
|
29
|
+
* close + create + frontier-update transaction).
|
|
30
|
+
*/
|
|
31
|
+
updateFrontier(instanceId: string, nextFrontier: string[], nextStatus: WorkflowInstanceStatus, opts?: {
|
|
32
|
+
bumpHopCount?: boolean;
|
|
33
|
+
lastContinuationDecision?: Record<string, unknown> | null;
|
|
34
|
+
fallbackSynthesis?: string | null;
|
|
35
|
+
completedAt?: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* R2: explicit next current_step_id. When provided, OVERWRITES
|
|
38
|
+
* the column (including to NULL by passing the empty string for
|
|
39
|
+
* "clear"). When omitted, current_step_id is preserved (the
|
|
40
|
+
* frontier packet is reused, e.g., on waiting). To clear pass
|
|
41
|
+
* the symbol "clear-current-step" (typed as the literal below).
|
|
42
|
+
*/
|
|
43
|
+
currentStepId?: string | "preserve" | "clear";
|
|
44
|
+
}): void;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=workflow-instance-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-instance-store.d.ts","sourceRoot":"","sources":["../../src/domain/workflow-instance-store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAiB7B,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,IAAI,EAAE,MAAM;aAEZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAFjC,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAKpD;AAED,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,GAAG,GAAE,MAAM,IAAuB;IAGrD,MAAM,CAAC,KAAK,EAAE,2BAA2B,GAAG,gBAAgB;IAuB5D,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAOpD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;IAYpD,YAAY,CAAC,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,EAAE;IAShE,OAAO,IAAI,gBAAgB,EAAE;IAO7B;;;;;OAKG;IACH,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EAAE,EACtB,UAAU,EAAE,sBAAsB,EAClC,IAAI,GAAE;QACJ,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;QAC1D,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B;;;;;;WAMG;QACH,aAAa,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;KAC1C,GACL,IAAI;CAyCR"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// PL-004 Phase D: workflow instance store.
|
|
2
|
+
//
|
|
3
|
+
// Owns CRUD on workflow_instances. Frontier tracking uses
|
|
4
|
+
// current_frontier_json (serialized JSON array of qitem_ids). Survives
|
|
5
|
+
// daemon restart without filesystem reconciliation: list/getById query
|
|
6
|
+
// SQLite directly.
|
|
7
|
+
import { ulid } from "ulid";
|
|
8
|
+
export class WorkflowInstanceError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
details;
|
|
11
|
+
constructor(code, message, details) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.details = details;
|
|
15
|
+
this.name = "WorkflowInstanceError";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class WorkflowInstanceStore {
|
|
19
|
+
db;
|
|
20
|
+
now;
|
|
21
|
+
constructor(db, now = () => new Date()) {
|
|
22
|
+
this.db = db;
|
|
23
|
+
this.now = now;
|
|
24
|
+
}
|
|
25
|
+
create(input) {
|
|
26
|
+
const instanceId = ulid();
|
|
27
|
+
const createdAt = this.now().toISOString();
|
|
28
|
+
const frontier = input.initialFrontier ?? [];
|
|
29
|
+
this.db
|
|
30
|
+
.prepare(`INSERT INTO workflow_instances (
|
|
31
|
+
instance_id, workflow_name, workflow_version, created_by_session,
|
|
32
|
+
created_at, status, current_frontier_json, current_step_id, hop_count
|
|
33
|
+
) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, 0)`)
|
|
34
|
+
.run(instanceId, input.workflowName, input.workflowVersion, input.createdBySession, createdAt, JSON.stringify(frontier), input.currentStepId ?? null);
|
|
35
|
+
return this.getByIdOrThrow(instanceId);
|
|
36
|
+
}
|
|
37
|
+
getById(instanceId) {
|
|
38
|
+
const row = this.db
|
|
39
|
+
.prepare(`SELECT * FROM workflow_instances WHERE instance_id = ?`)
|
|
40
|
+
.get(instanceId);
|
|
41
|
+
return row ? rowToInstance(row) : null;
|
|
42
|
+
}
|
|
43
|
+
getByIdOrThrow(instanceId) {
|
|
44
|
+
const inst = this.getById(instanceId);
|
|
45
|
+
if (!inst) {
|
|
46
|
+
throw new WorkflowInstanceError("instance_not_found", `workflow instance ${instanceId} not found`, { instanceId });
|
|
47
|
+
}
|
|
48
|
+
return inst;
|
|
49
|
+
}
|
|
50
|
+
listByStatus(status) {
|
|
51
|
+
const rows = this.db
|
|
52
|
+
.prepare(`SELECT * FROM workflow_instances WHERE status = ? ORDER BY created_at ASC`)
|
|
53
|
+
.all(status);
|
|
54
|
+
return rows.map(rowToInstance);
|
|
55
|
+
}
|
|
56
|
+
listAll() {
|
|
57
|
+
const rows = this.db
|
|
58
|
+
.prepare(`SELECT * FROM workflow_instances ORDER BY created_at ASC`)
|
|
59
|
+
.all();
|
|
60
|
+
return rows.map(rowToInstance);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update frontier + status atomically. Caller is responsible for
|
|
64
|
+
* wrapping in a transaction when this needs to compose with other
|
|
65
|
+
* mutations (e.g., workflow-projector folds this into the
|
|
66
|
+
* close + create + frontier-update transaction).
|
|
67
|
+
*/
|
|
68
|
+
updateFrontier(instanceId, nextFrontier, nextStatus, opts = {}) {
|
|
69
|
+
const setHop = opts.bumpHopCount ? "hop_count = hop_count + 1, " : "";
|
|
70
|
+
let currentStepClause = "";
|
|
71
|
+
let currentStepValue;
|
|
72
|
+
if (opts.currentStepId === "preserve" || opts.currentStepId === undefined) {
|
|
73
|
+
currentStepClause = "";
|
|
74
|
+
currentStepValue = undefined;
|
|
75
|
+
}
|
|
76
|
+
else if (opts.currentStepId === "clear") {
|
|
77
|
+
currentStepClause = "current_step_id = NULL, ";
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
currentStepClause = "current_step_id = ?, ";
|
|
81
|
+
currentStepValue = opts.currentStepId;
|
|
82
|
+
}
|
|
83
|
+
const sql = `UPDATE workflow_instances SET
|
|
84
|
+
${setHop}${currentStepClause}status = ?, current_frontier_json = ?,
|
|
85
|
+
last_continuation_decision_json = COALESCE(?, last_continuation_decision_json),
|
|
86
|
+
fallback_synthesis = COALESCE(?, fallback_synthesis),
|
|
87
|
+
completed_at = COALESCE(?, completed_at)
|
|
88
|
+
WHERE instance_id = ?`;
|
|
89
|
+
const stmt = this.db.prepare(sql);
|
|
90
|
+
if (currentStepValue !== undefined) {
|
|
91
|
+
stmt.run(currentStepValue, nextStatus, JSON.stringify(nextFrontier), opts.lastContinuationDecision ? JSON.stringify(opts.lastContinuationDecision) : null, opts.fallbackSynthesis ?? null, opts.completedAt ?? null, instanceId);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
stmt.run(nextStatus, JSON.stringify(nextFrontier), opts.lastContinuationDecision ? JSON.stringify(opts.lastContinuationDecision) : null, opts.fallbackSynthesis ?? null, opts.completedAt ?? null, instanceId);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function rowToInstance(row) {
|
|
99
|
+
return {
|
|
100
|
+
instanceId: row.instance_id,
|
|
101
|
+
workflowName: row.workflow_name,
|
|
102
|
+
workflowVersion: row.workflow_version,
|
|
103
|
+
createdBySession: row.created_by_session,
|
|
104
|
+
createdAt: row.created_at,
|
|
105
|
+
status: row.status,
|
|
106
|
+
currentFrontier: JSON.parse(row.current_frontier_json),
|
|
107
|
+
currentStepId: row.current_step_id,
|
|
108
|
+
hopCount: row.hop_count,
|
|
109
|
+
fallbackSynthesis: row.fallback_synthesis,
|
|
110
|
+
lastContinuationDecision: row.last_continuation_decision_json
|
|
111
|
+
? JSON.parse(row.last_continuation_decision_json)
|
|
112
|
+
: null,
|
|
113
|
+
completedAt: row.completed_at,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=workflow-instance-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-instance-store.js","sourceRoot":"","sources":["../../src/domain/workflow-instance-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
import type { EventBus } from "./event-bus.js";
|
|
3
|
+
import type { QueueRepository } from "./queue-repository.js";
|
|
4
|
+
import type { WorkflowInstanceStore } from "./workflow-instance-store.js";
|
|
5
|
+
import type { WorkflowSpecCache } from "./workflow-spec-cache.js";
|
|
6
|
+
import type { WorkflowStepTrailLog } from "./workflow-step-trail-log.js";
|
|
7
|
+
import type { WorkflowExitKind, WorkflowInstance } from "./workflow-types.js";
|
|
8
|
+
export declare class WorkflowProjectorError extends Error {
|
|
9
|
+
readonly code: string;
|
|
10
|
+
readonly details?: Record<string, unknown> | undefined;
|
|
11
|
+
constructor(code: string, message: string, details?: Record<string, unknown> | undefined);
|
|
12
|
+
}
|
|
13
|
+
export interface ProjectStepInput {
|
|
14
|
+
instanceId: string;
|
|
15
|
+
/** The qitem being closed (must be in instance.currentFrontier). */
|
|
16
|
+
currentPacketId: string;
|
|
17
|
+
/** What kind of exit closes this packet. */
|
|
18
|
+
exit: WorkflowExitKind;
|
|
19
|
+
/** Free-form closure result text (POC: --result). */
|
|
20
|
+
resultNote?: string;
|
|
21
|
+
/** For waiting exits: the blocker reference (qitem id, gate name). */
|
|
22
|
+
blockedOn?: string;
|
|
23
|
+
/** Operator-supplied evidence for the closure record (audit). */
|
|
24
|
+
closureEvidence?: Record<string, unknown>;
|
|
25
|
+
/** Session that closed the packet (owner-as-author). */
|
|
26
|
+
actorSession: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional explicit override for the next-step destination session.
|
|
29
|
+
* When omitted, the projector resolves from the next step's
|
|
30
|
+
* actor_role + role.preferred_targets[]. Required when no
|
|
31
|
+
* preferred_targets are declared OR none are operator-resolvable.
|
|
32
|
+
*/
|
|
33
|
+
nextOwnerSession?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ProjectStepResult {
|
|
36
|
+
instance: WorkflowInstance;
|
|
37
|
+
closurePriorPacketId: string;
|
|
38
|
+
closureReason: WorkflowExitKind;
|
|
39
|
+
/** null on terminal closures (waiting / done / failed / no-successor). */
|
|
40
|
+
nextQitemId: string | null;
|
|
41
|
+
/** null on terminal closures. */
|
|
42
|
+
nextOwnerSession: string | null;
|
|
43
|
+
/** null on terminal closures. */
|
|
44
|
+
nextStepId: string | null;
|
|
45
|
+
/** Composite fired events (step_closed + optional next_qitem_projected + optional completed). */
|
|
46
|
+
emittedEventTypes: string[];
|
|
47
|
+
}
|
|
48
|
+
export declare class WorkflowProjector {
|
|
49
|
+
private readonly db;
|
|
50
|
+
private readonly eventBus;
|
|
51
|
+
private readonly queueRepo;
|
|
52
|
+
private readonly instanceStore;
|
|
53
|
+
private readonly trailLog;
|
|
54
|
+
private readonly specCache;
|
|
55
|
+
private readonly now;
|
|
56
|
+
constructor(db: Database.Database, eventBus: EventBus, queueRepo: QueueRepository, instanceStore: WorkflowInstanceStore, trailLog: WorkflowStepTrailLog, specCache: WorkflowSpecCache, now?: () => Date);
|
|
57
|
+
/**
|
|
58
|
+
* Close the current packet AND create/project the next-step packet
|
|
59
|
+
* IN THE SAME TRANSACTION. The load-bearing transactional-scribe
|
|
60
|
+
* call site.
|
|
61
|
+
*/
|
|
62
|
+
project(input: ProjectStepInput): Promise<ProjectStepResult>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=workflow-projector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-projector.d.ts","sourceRoot":"","sources":["../../src/domain/workflow-projector.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAGjB,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,sBAAuB,SAAQ,KAAK;aAE7B,IAAI,EAAE,MAAM;aAEZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAFjC,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAKpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,IAAI,EAAE,gBAAgB,CAAC;IACvB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,gBAAgB,CAAC;IAChC,0EAA0E;IAC1E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iGAAiG;IACjG,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;gBANH,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,eAAe,EAC1B,aAAa,EAAE,qBAAqB,EACpC,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,iBAAiB,EAC5B,GAAG,GAAE,MAAM,IAAuB;IAGrD;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAuSnE"}
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
// PL-004 Phase D: workflow projector — transactional-scribe contract.
|
|
2
|
+
//
|
|
3
|
+
// LOAD-BEARING. The single most important Phase D contract.
|
|
4
|
+
//
|
|
5
|
+
// Per PRD § L4 + audit row 16: every code path that closes a
|
|
6
|
+
// `workflow_instances.current_frontier` qitem AND every code path that
|
|
7
|
+
// creates the next-step qitem MUST happen inside the SAME daemon-managed
|
|
8
|
+
// transaction. If two separate transactions can be observed, that is a
|
|
9
|
+
// contract violation. Lost handoffs are impossible by design.
|
|
10
|
+
//
|
|
11
|
+
// Composition (one db.transaction):
|
|
12
|
+
// 1. Verify spec + instance + current packet are consistent.
|
|
13
|
+
// 2. Resolve next step from spec (one-hop default per PRD).
|
|
14
|
+
// 3. Update queue_items: close current packet (handoff/waiting/done).
|
|
15
|
+
// 4. Create next-step queue item via QueueRepository.createWithinTransaction.
|
|
16
|
+
// 5. Append workflow_step_trails entry with prior + next ids.
|
|
17
|
+
// 6. Update workflow_instances frontier + status.
|
|
18
|
+
// 7. Persist workflow.* events (step_closed, next_qitem_projected, completed).
|
|
19
|
+
//
|
|
20
|
+
// All in one db.transaction. If any step throws, all rollback. After
|
|
21
|
+
// commit, fan out events to subscribers + nudge next owner.
|
|
22
|
+
export class WorkflowProjectorError extends Error {
|
|
23
|
+
code;
|
|
24
|
+
details;
|
|
25
|
+
constructor(code, message, details) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.code = code;
|
|
28
|
+
this.details = details;
|
|
29
|
+
this.name = "WorkflowProjectorError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class WorkflowProjector {
|
|
33
|
+
db;
|
|
34
|
+
eventBus;
|
|
35
|
+
queueRepo;
|
|
36
|
+
instanceStore;
|
|
37
|
+
trailLog;
|
|
38
|
+
specCache;
|
|
39
|
+
now;
|
|
40
|
+
constructor(db, eventBus, queueRepo, instanceStore, trailLog, specCache, now = () => new Date()) {
|
|
41
|
+
this.db = db;
|
|
42
|
+
this.eventBus = eventBus;
|
|
43
|
+
this.queueRepo = queueRepo;
|
|
44
|
+
this.instanceStore = instanceStore;
|
|
45
|
+
this.trailLog = trailLog;
|
|
46
|
+
this.specCache = specCache;
|
|
47
|
+
this.now = now;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Close the current packet AND create/project the next-step packet
|
|
51
|
+
* IN THE SAME TRANSACTION. The load-bearing transactional-scribe
|
|
52
|
+
* call site.
|
|
53
|
+
*/
|
|
54
|
+
async project(input) {
|
|
55
|
+
const instance = this.instanceStore.getByIdOrThrow(input.instanceId);
|
|
56
|
+
if (instance.status !== "active" && instance.status !== "waiting") {
|
|
57
|
+
throw new WorkflowProjectorError("instance_not_active", `workflow instance ${instance.instanceId} has status ${instance.status}; only active|waiting instances accept project`, { instanceId: instance.instanceId, status: instance.status });
|
|
58
|
+
}
|
|
59
|
+
if (!instance.currentFrontier.includes(input.currentPacketId)) {
|
|
60
|
+
throw new WorkflowProjectorError("packet_not_on_frontier", `qitem ${input.currentPacketId} is not in workflow instance ${instance.instanceId} frontier ${JSON.stringify(instance.currentFrontier)}; either the packet is already closed or belongs to a different instance`, { instanceId: instance.instanceId, currentPacketId: input.currentPacketId, frontier: instance.currentFrontier });
|
|
61
|
+
}
|
|
62
|
+
const specRow = this.specCache.getByNameVersion(instance.workflowName, instance.workflowVersion);
|
|
63
|
+
if (!specRow) {
|
|
64
|
+
throw new WorkflowProjectorError("spec_not_cached", `workflow spec ${instance.workflowName}@${instance.workflowVersion} is not in the spec cache. Re-run validate to refresh the cache.`, { workflowName: instance.workflowName, workflowVersion: instance.workflowVersion });
|
|
65
|
+
}
|
|
66
|
+
const spec = specRow.spec;
|
|
67
|
+
// Look up the qitem being closed to identify the current step.
|
|
68
|
+
const currentPacket = this.queueRepo.getById(input.currentPacketId);
|
|
69
|
+
if (!currentPacket) {
|
|
70
|
+
throw new WorkflowProjectorError("packet_not_found", `qitem ${input.currentPacketId} not found in queue_items`, { currentPacketId: input.currentPacketId });
|
|
71
|
+
}
|
|
72
|
+
// R2 fix (guard blocker 1): read durable current_step_id from instance
|
|
73
|
+
// rather than inferring "last_trail_step + 1". Reused-frontier packets
|
|
74
|
+
// (waiting then resume) now correctly resume the SAME step.
|
|
75
|
+
const currentStep = resolveCurrentStep(spec, instance);
|
|
76
|
+
if (!currentStep) {
|
|
77
|
+
throw new WorkflowProjectorError("current_step_unknown", `workflow instance ${instance.instanceId} has no resolvable current step (current_step_id=${JSON.stringify(instance.currentStepId)}). The instance may be in a terminal state, or the spec ${spec.id}@${spec.version} may have changed shape mid-instance.`, { instanceId: instance.instanceId, currentStepId: instance.currentStepId, frontier: instance.currentFrontier });
|
|
78
|
+
}
|
|
79
|
+
// R2 fix (guard blocker 2): enforce currentStep.allowed_exits at
|
|
80
|
+
// projection time. POC contract: an exit not in the step's
|
|
81
|
+
// allowed_exits is rejected with a structured error and NO state
|
|
82
|
+
// mutation. Validation happens BEFORE any side effect (queue close,
|
|
83
|
+
// trail append, frontier update, event persist). When allowed_exits
|
|
84
|
+
// is omitted on the step, no enforcement (operator opted out at
|
|
85
|
+
// spec authoring time).
|
|
86
|
+
if (currentStep.allowed_exits &&
|
|
87
|
+
currentStep.allowed_exits.length > 0 &&
|
|
88
|
+
!currentStep.allowed_exits.includes(input.exit)) {
|
|
89
|
+
throw new WorkflowProjectorError("exit_not_allowed", `step "${currentStep.id}" allows exits ${JSON.stringify(currentStep.allowed_exits)}; got "${input.exit}". Either close with a permitted exit, or amend the spec.`, {
|
|
90
|
+
instanceId: instance.instanceId,
|
|
91
|
+
stepId: currentStep.id,
|
|
92
|
+
attemptedExit: input.exit,
|
|
93
|
+
allowedExits: currentStep.allowed_exits,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// Determine next step (one-hop default; multi-hop is graduation).
|
|
97
|
+
const nextStep = resolveNextStep(spec, currentStep);
|
|
98
|
+
const evaluatedAt = this.now().toISOString();
|
|
99
|
+
let nextQitemId = null;
|
|
100
|
+
let nextOwnerSession = null;
|
|
101
|
+
let nextStepId = null;
|
|
102
|
+
let nextQitemCreatePostCommit = null;
|
|
103
|
+
const persistedEvents = [];
|
|
104
|
+
const txn = this.db.transaction(() => {
|
|
105
|
+
// 1. Resolve next owner BEFORE closing prior so closure_target is set.
|
|
106
|
+
let resolvedNextOwner = null;
|
|
107
|
+
if (input.exit === "handoff") {
|
|
108
|
+
if (!nextStep) {
|
|
109
|
+
throw new WorkflowProjectorError("no_next_step", `workflow instance ${instance.instanceId} reached terminal step "${currentStep.id}" but exit was handoff; use exit=done for terminal steps or extend the spec with a next step`, { instanceId: instance.instanceId, currentStepId: currentStep.id });
|
|
110
|
+
}
|
|
111
|
+
const owner = input.nextOwnerSession ?? resolveDefaultOwner(spec, nextStep);
|
|
112
|
+
if (!owner) {
|
|
113
|
+
throw new WorkflowProjectorError("next_owner_unresolved", `cannot resolve next owner for step "${nextStep.id}" (role "${nextStep.actor_role}"); supply nextOwnerSession explicitly or add preferred_targets to the role in the spec`, { instanceId: instance.instanceId, nextStepId: nextStep.id, nextRole: nextStep.actor_role });
|
|
114
|
+
}
|
|
115
|
+
resolvedNextOwner = owner;
|
|
116
|
+
}
|
|
117
|
+
// 2. R1 fix (guard blocker 1): close the current packet via Phase A's
|
|
118
|
+
// QueueRepository.updateWithinTransaction. This validates closure
|
|
119
|
+
// (Phase A hot-potato strict-rejection invariants), persists closure
|
|
120
|
+
// metadata (closure_reason, closure_target, handed_off_to / blocked_on),
|
|
121
|
+
// appends queue_transitions, and emits queue.updated — all inside this
|
|
122
|
+
// outer transaction. The Phase A closure authority is preserved.
|
|
123
|
+
const closure = workflowExitToQueueClosure(input, resolvedNextOwner);
|
|
124
|
+
const queueUpdate = this.queueRepo.updateWithinTransaction({
|
|
125
|
+
qitemId: input.currentPacketId,
|
|
126
|
+
actorSession: input.actorSession,
|
|
127
|
+
state: closure.state,
|
|
128
|
+
closureReason: closure.closureReason,
|
|
129
|
+
closureTarget: closure.closureTarget ?? undefined,
|
|
130
|
+
handedOffTo: closure.handedOffTo,
|
|
131
|
+
blockedOn: closure.blockedOn,
|
|
132
|
+
transitionNote: closure.transitionNote,
|
|
133
|
+
});
|
|
134
|
+
persistedEvents.push(queueUpdate.persistedEvent);
|
|
135
|
+
// 3. If exit is handoff: create next-step qitem in same txn.
|
|
136
|
+
let createdNext = null;
|
|
137
|
+
if (input.exit === "handoff" && nextStep && resolvedNextOwner) {
|
|
138
|
+
nextOwnerSession = resolvedNextOwner;
|
|
139
|
+
nextStepId = nextStep.id;
|
|
140
|
+
createdNext = this.queueRepo.createWithinTransaction({
|
|
141
|
+
sourceSession: input.actorSession,
|
|
142
|
+
destinationSession: resolvedNextOwner,
|
|
143
|
+
body: workflowHandoffBody({
|
|
144
|
+
spec,
|
|
145
|
+
instance,
|
|
146
|
+
currentStep,
|
|
147
|
+
nextStep,
|
|
148
|
+
actorSession: input.actorSession,
|
|
149
|
+
resultNote: input.resultNote,
|
|
150
|
+
}),
|
|
151
|
+
priority: "routine",
|
|
152
|
+
tier: "mode2",
|
|
153
|
+
tags: ["workflow", "handoff", `workflow:${spec.id}`, `instance:${instance.instanceId}`],
|
|
154
|
+
chainOfRecord: [input.currentPacketId],
|
|
155
|
+
});
|
|
156
|
+
nextQitemId = createdNext.qitemId;
|
|
157
|
+
nextQitemCreatePostCommit = {
|
|
158
|
+
destinationSession: createdNext.destinationSession,
|
|
159
|
+
nudge: createdNext.nudge,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// 4. Append step trail entry (prior + next ids).
|
|
163
|
+
this.trailLog.record({
|
|
164
|
+
instanceId: instance.instanceId,
|
|
165
|
+
stepId: currentStep.id,
|
|
166
|
+
stepRole: currentStep.actor_role,
|
|
167
|
+
closedAt: evaluatedAt,
|
|
168
|
+
closureReason: input.exit,
|
|
169
|
+
closureEvidence: input.closureEvidence ?? null,
|
|
170
|
+
actorSession: input.actorSession,
|
|
171
|
+
nextQitemId,
|
|
172
|
+
priorQitemId: input.currentPacketId,
|
|
173
|
+
});
|
|
174
|
+
// 5. Update instance frontier + status.
|
|
175
|
+
// R1 fix (guard blocker 2b): on exit=waiting, PRESERVE the closed
|
|
176
|
+
// packet on the frontier. workflow-keepalive treats waiting as
|
|
177
|
+
// eligible and resolves owners from current_frontier_json; removing
|
|
178
|
+
// the packet would leave a single-packet waiting workflow with no
|
|
179
|
+
// owner to wake.
|
|
180
|
+
const remainingFrontier = instance.currentFrontier.filter((id) => id !== input.currentPacketId);
|
|
181
|
+
let nextFrontier;
|
|
182
|
+
if (input.exit === "waiting") {
|
|
183
|
+
// Keep the closed packet on frontier; the watchdog uses it to wake the owner.
|
|
184
|
+
nextFrontier = [...remainingFrontier, input.currentPacketId];
|
|
185
|
+
}
|
|
186
|
+
else if (nextQitemId) {
|
|
187
|
+
nextFrontier = [...remainingFrontier, nextQitemId];
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
nextFrontier = remainingFrontier;
|
|
191
|
+
}
|
|
192
|
+
// R1 fix (guard blocker 2a): exit=failed sets status=failed, NOT
|
|
193
|
+
// completed. Emits workflow.failed instead of workflow.completed.
|
|
194
|
+
let nextStatus;
|
|
195
|
+
let completedAt = null;
|
|
196
|
+
if (input.exit === "waiting") {
|
|
197
|
+
nextStatus = "waiting";
|
|
198
|
+
}
|
|
199
|
+
else if (input.exit === "failed") {
|
|
200
|
+
nextStatus = "failed";
|
|
201
|
+
completedAt = evaluatedAt;
|
|
202
|
+
}
|
|
203
|
+
else if (nextFrontier.length === 0) {
|
|
204
|
+
nextStatus = "completed";
|
|
205
|
+
completedAt = evaluatedAt;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
nextStatus = "active";
|
|
209
|
+
}
|
|
210
|
+
// R2 fix: set durable current_step_id transition.
|
|
211
|
+
// handoff → next step
|
|
212
|
+
// waiting → preserve (resume on same packet still on same step)
|
|
213
|
+
// done / failed → clear (terminal)
|
|
214
|
+
let currentStepIdUpdate;
|
|
215
|
+
if (input.exit === "handoff" && nextStep) {
|
|
216
|
+
currentStepIdUpdate = nextStep.id;
|
|
217
|
+
}
|
|
218
|
+
else if (input.exit === "waiting") {
|
|
219
|
+
currentStepIdUpdate = "preserve";
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
// done or failed
|
|
223
|
+
currentStepIdUpdate = "clear";
|
|
224
|
+
}
|
|
225
|
+
this.instanceStore.updateFrontier(instance.instanceId, nextFrontier, nextStatus, {
|
|
226
|
+
bumpHopCount: input.exit === "handoff",
|
|
227
|
+
lastContinuationDecision: {
|
|
228
|
+
exit: input.exit,
|
|
229
|
+
actorSession: input.actorSession,
|
|
230
|
+
closedPacket: input.currentPacketId,
|
|
231
|
+
nextPacket: nextQitemId,
|
|
232
|
+
resultNote: input.resultNote ?? null,
|
|
233
|
+
blockedOn: input.blockedOn ?? null,
|
|
234
|
+
currentStep: currentStep.id,
|
|
235
|
+
},
|
|
236
|
+
completedAt,
|
|
237
|
+
currentStepId: currentStepIdUpdate,
|
|
238
|
+
});
|
|
239
|
+
// 6. Persist workflow events within the same txn.
|
|
240
|
+
persistedEvents.push(this.eventBus.persistWithinTransaction({
|
|
241
|
+
type: "workflow.step_closed",
|
|
242
|
+
instanceId: instance.instanceId,
|
|
243
|
+
stepId: currentStep.id,
|
|
244
|
+
closureReason: input.exit,
|
|
245
|
+
actorSession: input.actorSession,
|
|
246
|
+
priorQitemId: input.currentPacketId,
|
|
247
|
+
}));
|
|
248
|
+
if (createdNext && nextStep && resolvedNextOwner) {
|
|
249
|
+
persistedEvents.push(createdNext.persistedEvent);
|
|
250
|
+
persistedEvents.push(this.eventBus.persistWithinTransaction({
|
|
251
|
+
type: "workflow.next_qitem_projected",
|
|
252
|
+
instanceId: instance.instanceId,
|
|
253
|
+
nextQitemId: createdNext.qitemId,
|
|
254
|
+
nextOwner: createdNext.destinationSession,
|
|
255
|
+
nextStepId: nextStep.id,
|
|
256
|
+
}));
|
|
257
|
+
}
|
|
258
|
+
if (nextStatus === "completed") {
|
|
259
|
+
persistedEvents.push(this.eventBus.persistWithinTransaction({
|
|
260
|
+
type: "workflow.completed",
|
|
261
|
+
instanceId: instance.instanceId,
|
|
262
|
+
workflowName: instance.workflowName,
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
else if (nextStatus === "failed") {
|
|
266
|
+
persistedEvents.push(this.eventBus.persistWithinTransaction({
|
|
267
|
+
type: "workflow.failed",
|
|
268
|
+
instanceId: instance.instanceId,
|
|
269
|
+
workflowName: instance.workflowName,
|
|
270
|
+
reason: input.resultNote ?? "workflow_step_failed",
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
txn();
|
|
275
|
+
// Post-commit fan-out: notify subscribers + nudge next owner.
|
|
276
|
+
for (const e of persistedEvents) {
|
|
277
|
+
this.eventBus.notifySubscribers(e);
|
|
278
|
+
}
|
|
279
|
+
const postCommit = nextQitemCreatePostCommit;
|
|
280
|
+
if (nextQitemId && postCommit) {
|
|
281
|
+
await this.queueRepo.maybeNudge(nextQitemId, postCommit.destinationSession, postCommit.nudge);
|
|
282
|
+
}
|
|
283
|
+
const updatedInstance = this.instanceStore.getByIdOrThrow(instance.instanceId);
|
|
284
|
+
return {
|
|
285
|
+
instance: updatedInstance,
|
|
286
|
+
closurePriorPacketId: input.currentPacketId,
|
|
287
|
+
closureReason: input.exit,
|
|
288
|
+
nextQitemId,
|
|
289
|
+
nextOwnerSession,
|
|
290
|
+
nextStepId,
|
|
291
|
+
emittedEventTypes: persistedEvents.map((e) => e.type),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* R2 fix (guard blocker 1): resolve the current step from durable
|
|
297
|
+
* instance.currentStepId, NOT from trail order. The previous trail-based
|
|
298
|
+
* inference produced wrong results for reused-frontier packets:
|
|
299
|
+
* waiting → resume on same packet would skip a step, because the
|
|
300
|
+
* waiting close wrote a trail row that the next inference treated as
|
|
301
|
+
* "last step + 1".
|
|
302
|
+
*
|
|
303
|
+
* Falls back to the entry step ONLY when current_step_id is null
|
|
304
|
+
* (instantiate didn't set it; defense-in-depth, not the production
|
|
305
|
+
* path).
|
|
306
|
+
*
|
|
307
|
+
* Multi-active-frontier instances (parallel steps) remain a graduation;
|
|
308
|
+
* v1 supports a single active frontier packet, so a single
|
|
309
|
+
* current_step_id column suffices.
|
|
310
|
+
*/
|
|
311
|
+
function resolveCurrentStep(spec, instance) {
|
|
312
|
+
if (instance.currentStepId) {
|
|
313
|
+
return spec.steps.find((s) => s.id === instance.currentStepId) ?? null;
|
|
314
|
+
}
|
|
315
|
+
// Defense-in-depth: instance lacks current_step_id. Fall back to
|
|
316
|
+
// entry step (matches behavior of pre-R2 instances if any survive).
|
|
317
|
+
const entryRole = spec.entry?.role;
|
|
318
|
+
return (spec.steps[0] ??
|
|
319
|
+
(entryRole ? spec.steps.find((s) => s.actor_role === entryRole) ?? null : null) ??
|
|
320
|
+
null);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Resolve the next step. v1 = one-hop continuity (the next step in
|
|
324
|
+
* declaration order). Multi-hop chaining via `next_hop.suggested_roles`
|
|
325
|
+
* is a graduation feature per PRD § Risks "Workflow runtime over-engineered".
|
|
326
|
+
*/
|
|
327
|
+
function resolveNextStep(spec, currentStep) {
|
|
328
|
+
const idx = spec.steps.findIndex((s) => s.id === currentStep.id);
|
|
329
|
+
if (idx === -1)
|
|
330
|
+
return null;
|
|
331
|
+
return spec.steps[idx + 1] ?? null;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Resolve a default owner for a step. v1 picks the first declared
|
|
335
|
+
* preferred_target. Returns null if none declared (caller must supply
|
|
336
|
+
* nextOwnerSession explicitly).
|
|
337
|
+
*/
|
|
338
|
+
function resolveDefaultOwner(spec, step) {
|
|
339
|
+
const role = spec.roles?.[step.actor_role];
|
|
340
|
+
const targets = role?.preferred_targets ?? [];
|
|
341
|
+
return targets[0] ?? null;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* R1 fix (guard blocker 1): translate a workflow exit into the Phase A
|
|
345
|
+
* queue closure shape (state + closure_reason + closure_target +
|
|
346
|
+
* handed_off_to / blocked_on metadata). Phase A's hot-potato closure
|
|
347
|
+
* validation enforces the rules:
|
|
348
|
+
* - state=done requires closure_reason from CLOSURE_REASONS
|
|
349
|
+
* - handed_off_to / blocked_on / escalation also require closure_target
|
|
350
|
+
*
|
|
351
|
+
* Mappings:
|
|
352
|
+
* handoff → state=handed-off, closure_reason=handed_off_to,
|
|
353
|
+
* closure_target+handed_off_to=<next-owner>
|
|
354
|
+
* waiting → state=blocked, closure_reason=blocked_on,
|
|
355
|
+
* closure_target+blocked_on=<blocker>
|
|
356
|
+
* done → state=done, closure_reason=no-follow-on
|
|
357
|
+
* failed → state=done, closure_reason=denied (workflow status=failed
|
|
358
|
+
* is set separately on the instance row)
|
|
359
|
+
*/
|
|
360
|
+
function workflowExitToQueueClosure(input, resolvedNextOwner) {
|
|
361
|
+
switch (input.exit) {
|
|
362
|
+
case "handoff": {
|
|
363
|
+
if (!resolvedNextOwner) {
|
|
364
|
+
// Defense-in-depth — projector validates this earlier and throws
|
|
365
|
+
// next_owner_unresolved, so this branch is unreachable in practice.
|
|
366
|
+
throw new WorkflowProjectorError("next_owner_unresolved", "handoff exit requires a resolved next owner before queue closure");
|
|
367
|
+
}
|
|
368
|
+
return {
|
|
369
|
+
state: "handed-off",
|
|
370
|
+
closureReason: "handed_off_to",
|
|
371
|
+
closureTarget: resolvedNextOwner,
|
|
372
|
+
handedOffTo: resolvedNextOwner,
|
|
373
|
+
transitionNote: `workflow handoff to ${resolvedNextOwner}`,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
case "waiting": {
|
|
377
|
+
const blocker = input.blockedOn ?? "external-gate";
|
|
378
|
+
return {
|
|
379
|
+
state: "blocked",
|
|
380
|
+
closureReason: "blocked_on",
|
|
381
|
+
closureTarget: blocker,
|
|
382
|
+
blockedOn: blocker,
|
|
383
|
+
transitionNote: `workflow waiting on ${blocker}`,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
case "done": {
|
|
387
|
+
return {
|
|
388
|
+
state: "done",
|
|
389
|
+
closureReason: "no-follow-on",
|
|
390
|
+
closureTarget: null,
|
|
391
|
+
transitionNote: input.resultNote
|
|
392
|
+
? `workflow done: ${input.resultNote}`
|
|
393
|
+
: "workflow done",
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
case "failed": {
|
|
397
|
+
return {
|
|
398
|
+
state: "done",
|
|
399
|
+
closureReason: "denied",
|
|
400
|
+
closureTarget: input.resultNote ?? "workflow_step_failed",
|
|
401
|
+
transitionNote: input.resultNote
|
|
402
|
+
? `workflow failed: ${input.resultNote}`
|
|
403
|
+
: "workflow failed",
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function workflowHandoffBody(input) {
|
|
409
|
+
const lines = [
|
|
410
|
+
`### Workflow handoff: ${input.spec.id}@${input.spec.version} step ${input.nextStep.id}`,
|
|
411
|
+
"",
|
|
412
|
+
`Workflow instance: ${input.instance.instanceId}`,
|
|
413
|
+
`Prior step: ${input.currentStep.id} (${input.currentStep.actor_role}) closed by ${input.actorSession}`,
|
|
414
|
+
`This step: ${input.nextStep.id} (${input.nextStep.actor_role})`,
|
|
415
|
+
];
|
|
416
|
+
if (input.nextStep.objective) {
|
|
417
|
+
lines.push(`Objective: ${input.nextStep.objective}`);
|
|
418
|
+
}
|
|
419
|
+
if (input.resultNote) {
|
|
420
|
+
lines.push("", `Prior step note: ${input.resultNote}`);
|
|
421
|
+
}
|
|
422
|
+
return lines.join("\n");
|
|
423
|
+
}
|
|
424
|
+
//# sourceMappingURL=workflow-projector.js.map
|