@openrig/cli 0.4.3 → 0.4.6
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/guidance/openrig-start.md +6 -0
- package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +47 -21
- package/daemon/assets/plugins/openrig-core/skills/openrig-cmux/SKILL.md +86 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-herdr/SKILL.md +158 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +742 -94
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +12 -8
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/pi-resume.d.ts +32 -0
- package/daemon/dist/adapters/pi-resume.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-resume.js +125 -0
- package/daemon/dist/adapters/pi-resume.js.map +1 -0
- package/daemon/dist/adapters/pi-runner-protocol.d.ts +88 -0
- package/daemon/dist/adapters/pi-runner-protocol.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-runner-protocol.js +153 -0
- package/daemon/dist/adapters/pi-runner-protocol.js.map +1 -0
- package/daemon/dist/adapters/pi-runner.d.ts +99 -0
- package/daemon/dist/adapters/pi-runner.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-runner.js +519 -0
- package/daemon/dist/adapters/pi-runner.js.map +1 -0
- package/daemon/dist/adapters/pi-runtime-adapter.d.ts +61 -0
- package/daemon/dist/adapters/pi-runtime-adapter.d.ts.map +1 -0
- package/daemon/dist/adapters/pi-runtime-adapter.js +356 -0
- package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -0
- package/daemon/dist/adapters/tmux.d.ts +22 -1
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +40 -1
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/build-info.d.ts +12 -0
- package/daemon/dist/build-info.d.ts.map +1 -0
- package/daemon/dist/build-info.js +11 -0
- package/daemon/dist/build-info.js.map +1 -0
- package/daemon/dist/builtins/workflow-specs/branched-remediation.yaml +31 -0
- package/daemon/dist/builtins/workflow-specs/factory-rsi.yaml +152 -0
- package/daemon/dist/builtins/workflow-specs/gated-release.yaml +26 -0
- package/daemon/dist/builtins/workflow-specs/linear-build.yaml +21 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.d.ts +18 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.d.ts.map +1 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.js +22 -0
- package/daemon/dist/db/migrations/048_queue_item_evidence_ref.js.map +1 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.d.ts +20 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.d.ts.map +1 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.js +24 -0
- package/daemon/dist/db/migrations/049_workflow_instance_version.js.map +1 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.d.ts +22 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.d.ts.map +1 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.js +26 -0
- package/daemon/dist/db/migrations/050_workflow_spec_json.js.map +1 -0
- package/daemon/dist/db/migrations/051_workflow_resume.d.ts +22 -0
- package/daemon/dist/db/migrations/051_workflow_resume.d.ts.map +1 -0
- package/daemon/dist/db/migrations/051_workflow_resume.js +27 -0
- package/daemon/dist/db/migrations/051_workflow_resume.js.map +1 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.d.ts +26 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.d.ts.map +1 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.js +30 -0
- package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.js.map +1 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.d.ts +48 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.d.ts.map +1 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.js +53 -0
- package/daemon/dist/db/migrations/053_sessions_node_id_index.js.map +1 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.d.ts +34 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.d.ts.map +1 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.js +49 -0
- package/daemon/dist/db/migrations/054_queue_transitions_archive.js.map +1 -0
- package/daemon/dist/domain/claim-service.d.ts +11 -0
- package/daemon/dist/domain/claim-service.d.ts.map +1 -1
- package/daemon/dist/domain/claim-service.js +3 -1
- package/daemon/dist/domain/claim-service.js.map +1 -1
- package/daemon/dist/domain/discovery-types.d.ts +1 -1
- package/daemon/dist/domain/discovery-types.d.ts.map +1 -1
- package/daemon/dist/domain/feed/attention-aggregator.d.ts +31 -0
- package/daemon/dist/domain/feed/attention-aggregator.d.ts.map +1 -0
- package/daemon/dist/domain/feed/attention-aggregator.js +119 -0
- package/daemon/dist/domain/feed/attention-aggregator.js.map +1 -0
- package/daemon/dist/domain/files/file-write-service.d.ts +11 -2
- package/daemon/dist/domain/files/file-write-service.d.ts.map +1 -1
- package/daemon/dist/domain/files/file-write-service.js +77 -0
- package/daemon/dist/domain/files/file-write-service.js.map +1 -1
- package/daemon/dist/domain/hosts/fanout-contract.d.ts +33 -0
- package/daemon/dist/domain/hosts/fanout-contract.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/fanout-contract.js +23 -0
- package/daemon/dist/domain/hosts/fanout-contract.js.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts +50 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.js +184 -0
- package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts +11 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.js +54 -0
- package/daemon/dist/domain/hosts/hosts-registry-writer.js.map +1 -0
- package/daemon/dist/domain/hosts/read-through.d.ts +28 -0
- package/daemon/dist/domain/hosts/read-through.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/read-through.js +139 -0
- package/daemon/dist/domain/hosts/read-through.js.map +1 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts +56 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.js +154 -0
- package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -0
- package/daemon/dist/domain/human-route-enforcer.d.ts +71 -0
- package/daemon/dist/domain/human-route-enforcer.d.ts.map +1 -0
- package/daemon/dist/domain/human-route-enforcer.js +80 -0
- package/daemon/dist/domain/human-route-enforcer.js.map +1 -0
- package/daemon/dist/domain/mission-control/audit-browse.d.ts +8 -0
- package/daemon/dist/domain/mission-control/audit-browse.d.ts.map +1 -1
- package/daemon/dist/domain/mission-control/audit-browse.js +19 -0
- package/daemon/dist/domain/mission-control/audit-browse.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-action-log.d.ts +1 -1
- package/daemon/dist/domain/mission-control/mission-control-action-log.d.ts.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-action-log.js +4 -0
- package/daemon/dist/domain/mission-control/mission-control-action-log.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-fleet-cli-capability.js +1 -1
- package/daemon/dist/domain/mission-control/mission-control-fleet-cli-capability.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-read-layer.js +1 -1
- package/daemon/dist/domain/mission-control/mission-control-read-layer.js.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts +28 -0
- package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts.map +1 -1
- package/daemon/dist/domain/mission-control/mission-control-write-contract.js +125 -0
- package/daemon/dist/domain/mission-control/mission-control-write-contract.js.map +1 -1
- package/daemon/dist/domain/node-inventory.d.ts +18 -0
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +206 -95
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/node-launcher.d.ts +11 -0
- package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/node-launcher.js +10 -0
- package/daemon/dist/domain/node-launcher.js.map +1 -1
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts +7 -0
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -1
- package/daemon/dist/domain/policies/workflow-keepalive.js +93 -13
- package/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -1
- package/daemon/dist/domain/ps-projection.d.ts +28 -1
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +76 -26
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +130 -1
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
- package/daemon/dist/domain/queue-repository.js +304 -11
- package/daemon/dist/domain/queue-repository.js.map +1 -1
- package/daemon/dist/domain/queue-retention.d.ts +130 -0
- package/daemon/dist/domain/queue-retention.d.ts.map +1 -0
- package/daemon/dist/domain/queue-retention.js +224 -0
- package/daemon/dist/domain/queue-retention.js.map +1 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts +5 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +29 -2
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/resume-token-capture.d.ts +13 -0
- package/daemon/dist/domain/resume-token-capture.d.ts.map +1 -1
- package/daemon/dist/domain/resume-token-capture.js +14 -1
- package/daemon/dist/domain/resume-token-capture.js.map +1 -1
- package/daemon/dist/domain/resume-token-validation.d.ts +1 -1
- package/daemon/dist/domain/resume-token-validation.d.ts.map +1 -1
- package/daemon/dist/domain/resume-token-validation.js +58 -10
- package/daemon/dist/domain/resume-token-validation.js.map +1 -1
- package/daemon/dist/domain/review/brief-spine.d.ts +19 -0
- package/daemon/dist/domain/review/brief-spine.d.ts.map +1 -0
- package/daemon/dist/domain/review/brief-spine.js +86 -0
- package/daemon/dist/domain/review/brief-spine.js.map +1 -0
- package/daemon/dist/domain/review/compose.d.ts +277 -0
- package/daemon/dist/domain/review/compose.d.ts.map +1 -0
- package/daemon/dist/domain/review/compose.js +862 -0
- package/daemon/dist/domain/review/compose.js.map +1 -0
- package/daemon/dist/domain/review/fleet-compose.d.ts +52 -0
- package/daemon/dist/domain/review/fleet-compose.d.ts.map +1 -0
- package/daemon/dist/domain/review/fleet-compose.js +294 -0
- package/daemon/dist/domain/review/fleet-compose.js.map +1 -0
- package/daemon/dist/domain/review/freeze.d.ts +31 -0
- package/daemon/dist/domain/review/freeze.d.ts.map +1 -0
- package/daemon/dist/domain/review/freeze.js +257 -0
- package/daemon/dist/domain/review/freeze.js.map +1 -0
- package/daemon/dist/domain/review/gather.d.ts +115 -0
- package/daemon/dist/domain/review/gather.d.ts.map +1 -0
- package/daemon/dist/domain/review/gather.js +812 -0
- package/daemon/dist/domain/review/gather.js.map +1 -0
- package/daemon/dist/domain/review/types.d.ts +361 -0
- package/daemon/dist/domain/review/types.d.ts.map +1 -0
- package/daemon/dist/domain/review/types.js +35 -0
- package/daemon/dist/domain/review/types.js.map +1 -0
- package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.js +3 -0
- package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
- package/daemon/dist/domain/rig-repository.d.ts +7 -6
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +33 -11
- 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 +3 -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 +4 -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 +11 -0
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.d.ts +6 -0
- package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.js +26 -1
- package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
- package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-schema.js +20 -1
- package/daemon/dist/domain/rigspec-schema.js.map +1 -1
- package/daemon/dist/domain/runtime-verifier.d.ts +7 -1
- package/daemon/dist/domain/runtime-verifier.d.ts.map +1 -1
- package/daemon/dist/domain/runtime-verifier.js +39 -1
- package/daemon/dist/domain/runtime-verifier.js.map +1 -1
- package/daemon/dist/domain/scope/scope-approve.d.ts +64 -0
- package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -0
- package/daemon/dist/domain/scope/scope-approve.js +153 -0
- package/daemon/dist/domain/scope/scope-approve.js.map +1 -0
- package/daemon/dist/domain/scope/scope-audit.d.ts +9 -1
- package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
- package/daemon/dist/domain/scope/scope-audit.js +173 -1
- package/daemon/dist/domain/scope/scope-audit.js.map +1 -1
- package/daemon/dist/domain/seat-handover-service.d.ts +9 -0
- package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-handover-service.js +2 -0
- package/daemon/dist/domain/seat-handover-service.js.map +1 -1
- package/daemon/dist/domain/seat-identity-store.d.ts +7 -0
- package/daemon/dist/domain/seat-identity-store.d.ts.map +1 -1
- package/daemon/dist/domain/seat-identity-store.js +27 -0
- package/daemon/dist/domain/seat-identity-store.js.map +1 -1
- package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
- package/daemon/dist/domain/seat-status-service.js +6 -4
- package/daemon/dist/domain/seat-status-service.js.map +1 -1
- package/daemon/dist/domain/session-name.d.ts +22 -0
- package/daemon/dist/domain/session-name.d.ts.map +1 -1
- package/daemon/dist/domain/session-name.js +29 -0
- package/daemon/dist/domain/session-name.js.map +1 -1
- package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
- package/daemon/dist/domain/slices/slice-detail-projector.js +4 -5
- package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
- package/daemon/dist/domain/spec-library-workflow-scanner.d.ts +18 -2
- package/daemon/dist/domain/spec-library-workflow-scanner.d.ts.map +1 -1
- package/daemon/dist/domain/spec-library-workflow-scanner.js +23 -1
- package/daemon/dist/domain/spec-library-workflow-scanner.js.map +1 -1
- package/daemon/dist/domain/startup-proof.d.ts +10 -6
- package/daemon/dist/domain/startup-proof.d.ts.map +1 -1
- package/daemon/dist/domain/startup-proof.js +35 -7
- package/daemon/dist/domain/startup-proof.js.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.d.ts +16 -0
- package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/successor-session-launcher.js +13 -0
- package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
- package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts +27 -0
- package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/cmux-provider-adapter.js +67 -0
- package/daemon/dist/domain/terminal/cmux-provider-adapter.js.map +1 -0
- package/daemon/dist/domain/terminal/herdr-adapter.d.ts +77 -0
- package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/herdr-adapter.js +266 -0
- package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -0
- package/daemon/dist/domain/terminal/herdr-transport.d.ts +50 -0
- package/daemon/dist/domain/terminal/herdr-transport.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/herdr-transport.js +145 -0
- package/daemon/dist/domain/terminal/herdr-transport.js.map +1 -0
- package/daemon/dist/domain/terminal/terminal-provider.d.ts +88 -0
- package/daemon/dist/domain/terminal/terminal-provider.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/terminal-provider.js +17 -0
- package/daemon/dist/domain/terminal/terminal-provider.js.map +1 -0
- package/daemon/dist/domain/terminal/terminal-service.d.ts +60 -0
- package/daemon/dist/domain/terminal/terminal-service.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/terminal-service.js +174 -0
- package/daemon/dist/domain/terminal/terminal-service.js.map +1 -0
- package/daemon/dist/domain/terminal/terminal-views-store.d.ts +77 -0
- package/daemon/dist/domain/terminal/terminal-views-store.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/terminal-views-store.js +146 -0
- package/daemon/dist/domain/terminal/terminal-views-store.js.map +1 -0
- package/daemon/dist/domain/terminal/view-composer.d.ts +42 -0
- package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -0
- package/daemon/dist/domain/terminal/view-composer.js +137 -0
- package/daemon/dist/domain/terminal/view-composer.js.map +1 -0
- package/daemon/dist/domain/tmux-option-defaults.d.ts +89 -0
- package/daemon/dist/domain/tmux-option-defaults.d.ts.map +1 -0
- package/daemon/dist/domain/tmux-option-defaults.js +132 -0
- package/daemon/dist/domain/tmux-option-defaults.js.map +1 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.d.ts +49 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.d.ts.map +1 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.js +132 -0
- package/daemon/dist/domain/topology/multi-rig-launcher.js.map +1 -0
- package/daemon/dist/domain/topology/remote-up-leaf.d.ts +29 -0
- package/daemon/dist/domain/topology/remote-up-leaf.d.ts.map +1 -0
- package/daemon/dist/domain/topology/remote-up-leaf.js +60 -0
- package/daemon/dist/domain/topology/remote-up-leaf.js.map +1 -0
- package/daemon/dist/domain/topology/topology-manifest.d.ts +34 -0
- package/daemon/dist/domain/topology/topology-manifest.d.ts.map +1 -0
- package/daemon/dist/domain/topology/topology-manifest.js +195 -0
- package/daemon/dist/domain/topology/topology-manifest.js.map +1 -0
- package/daemon/dist/domain/types.d.ts +39 -1
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.js.map +1 -1
- package/daemon/dist/domain/up-command-router.d.ts +1 -1
- package/daemon/dist/domain/up-command-router.d.ts.map +1 -1
- package/daemon/dist/domain/up-command-router.js +34 -2
- package/daemon/dist/domain/up-command-router.js.map +1 -1
- package/daemon/dist/domain/user-settings/settings-store.d.ts +18 -1
- package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
- package/daemon/dist/domain/user-settings/settings-store.js +201 -0
- package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
- package/daemon/dist/domain/workflow/slice-workflow-projection.d.ts.map +1 -1
- package/daemon/dist/domain/workflow/slice-workflow-projection.js +6 -2
- package/daemon/dist/domain/workflow/slice-workflow-projection.js.map +1 -1
- package/daemon/dist/domain/workflow-boot-sweep.d.ts +28 -0
- package/daemon/dist/domain/workflow-boot-sweep.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-boot-sweep.js +102 -0
- package/daemon/dist/domain/workflow-boot-sweep.js.map +1 -0
- package/daemon/dist/domain/workflow-deadline.d.ts +74 -0
- package/daemon/dist/domain/workflow-deadline.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-deadline.js +165 -0
- package/daemon/dist/domain/workflow-deadline.js.map +1 -0
- package/daemon/dist/domain/workflow-exception-escalation.d.ts +33 -0
- package/daemon/dist/domain/workflow-exception-escalation.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-exception-escalation.js +104 -0
- package/daemon/dist/domain/workflow-exception-escalation.js.map +1 -0
- package/daemon/dist/domain/workflow-exception-router.d.ts +33 -0
- package/daemon/dist/domain/workflow-exception-router.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-exception-router.js +96 -0
- package/daemon/dist/domain/workflow-exception-router.js.map +1 -0
- package/daemon/dist/domain/workflow-exception.d.ts +90 -0
- package/daemon/dist/domain/workflow-exception.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-exception.js +122 -0
- package/daemon/dist/domain/workflow-exception.js.map +1 -0
- package/daemon/dist/domain/workflow-frontier-guard.d.ts +24 -0
- package/daemon/dist/domain/workflow-frontier-guard.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-frontier-guard.js +30 -0
- package/daemon/dist/domain/workflow-frontier-guard.js.map +1 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts +28 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-instance-store.js +66 -10
- package/daemon/dist/domain/workflow-instance-store.js.map +1 -1
- package/daemon/dist/domain/workflow-keepalive-arming.d.ts +35 -0
- package/daemon/dist/domain/workflow-keepalive-arming.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-keepalive-arming.js +87 -0
- package/daemon/dist/domain/workflow-keepalive-arming.js.map +1 -0
- package/daemon/dist/domain/workflow-projector.d.ts +117 -2
- package/daemon/dist/domain/workflow-projector.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-projector.js +672 -41
- package/daemon/dist/domain/workflow-projector.js.map +1 -1
- package/daemon/dist/domain/workflow-role-context.d.ts +57 -0
- package/daemon/dist/domain/workflow-role-context.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-role-context.js +120 -0
- package/daemon/dist/domain/workflow-role-context.js.map +1 -0
- package/daemon/dist/domain/workflow-role-resolver.d.ts +65 -0
- package/daemon/dist/domain/workflow-role-resolver.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-role-resolver.js +108 -0
- package/daemon/dist/domain/workflow-role-resolver.js.map +1 -0
- package/daemon/dist/domain/workflow-runtime.d.ts +157 -1
- package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-runtime.js +718 -11
- package/daemon/dist/domain/workflow-runtime.js.map +1 -1
- package/daemon/dist/domain/workflow-spec-cache.d.ts +26 -1
- package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-spec-cache.js +327 -13
- package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
- package/daemon/dist/domain/workflow-types.d.ts +143 -8
- package/daemon/dist/domain/workflow-types.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-types.js +14 -1
- package/daemon/dist/domain/workflow-types.js.map +1 -1
- package/daemon/dist/domain/workflow-validator.d.ts +11 -1
- package/daemon/dist/domain/workflow-validator.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-validator.js +246 -1
- package/daemon/dist/domain/workflow-validator.js.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js +51 -6
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.d.ts +11 -0
- package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.js +82 -0
- package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
- package/daemon/dist/index.d.ts +17 -0
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +44 -0
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/activity.js +22 -0
- package/daemon/dist/routes/activity.js.map +1 -1
- package/daemon/dist/routes/config.d.ts.map +1 -1
- package/daemon/dist/routes/config.js +15 -6
- package/daemon/dist/routes/config.js.map +1 -1
- package/daemon/dist/routes/files.d.ts.map +1 -1
- package/daemon/dist/routes/files.js +45 -1
- package/daemon/dist/routes/files.js.map +1 -1
- package/daemon/dist/routes/hosts.d.ts +5 -0
- package/daemon/dist/routes/hosts.d.ts.map +1 -0
- package/daemon/dist/routes/hosts.js +346 -0
- package/daemon/dist/routes/hosts.js.map +1 -0
- package/daemon/dist/routes/mission-control.d.ts.map +1 -1
- package/daemon/dist/routes/mission-control.js +67 -2
- package/daemon/dist/routes/mission-control.js.map +1 -1
- package/daemon/dist/routes/queue.d.ts +10 -9
- package/daemon/dist/routes/queue.d.ts.map +1 -1
- package/daemon/dist/routes/queue.js +305 -10
- package/daemon/dist/routes/queue.js.map +1 -1
- package/daemon/dist/routes/review.d.ts +3 -0
- package/daemon/dist/routes/review.d.ts.map +1 -0
- package/daemon/dist/routes/review.js +195 -0
- package/daemon/dist/routes/review.js.map +1 -0
- package/daemon/dist/routes/scope-approve.d.ts +3 -0
- package/daemon/dist/routes/scope-approve.d.ts.map +1 -0
- package/daemon/dist/routes/scope-approve.js +55 -0
- package/daemon/dist/routes/scope-approve.js.map +1 -0
- package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
- package/daemon/dist/routes/scope-audit.js +28 -1
- package/daemon/dist/routes/scope-audit.js.map +1 -1
- package/daemon/dist/routes/seat.js +13 -0
- package/daemon/dist/routes/seat.js.map +1 -1
- package/daemon/dist/routes/slices.d.ts.map +1 -1
- package/daemon/dist/routes/slices.js +49 -9
- package/daemon/dist/routes/slices.js.map +1 -1
- package/daemon/dist/routes/terminal-ws.d.ts.map +1 -1
- package/daemon/dist/routes/terminal-ws.js +58 -21
- package/daemon/dist/routes/terminal-ws.js.map +1 -1
- package/daemon/dist/routes/terminal.d.ts +11 -0
- package/daemon/dist/routes/terminal.d.ts.map +1 -0
- package/daemon/dist/routes/terminal.js +104 -0
- package/daemon/dist/routes/terminal.js.map +1 -0
- package/daemon/dist/routes/up.d.ts.map +1 -1
- package/daemon/dist/routes/up.js +84 -0
- package/daemon/dist/routes/up.js.map +1 -1
- package/daemon/dist/routes/workflow.d.ts.map +1 -1
- package/daemon/dist/routes/workflow.js +102 -10
- package/daemon/dist/routes/workflow.js.map +1 -1
- package/daemon/dist/routes/workspace.js +2 -2
- package/daemon/dist/server.d.ts +6 -0
- package/daemon/dist/server.d.ts.map +1 -1
- package/daemon/dist/server.js +36 -1
- package/daemon/dist/server.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +238 -14
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-startup-guide.md +1 -1
- package/daemon/docs/reference/product-factory-vps-runbook.md +132 -0
- package/daemon/docs/reference/sdlc-conventions.md +187 -0
- package/daemon/specs/agents/conveyor/builder/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/builder/guidance/role.md +1 -0
- package/daemon/specs/agents/conveyor/lead/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/lead/guidance/role.md +1 -0
- package/daemon/specs/agents/conveyor/planner/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/planner/guidance/role.md +1 -0
- package/daemon/specs/agents/conveyor/reviewer/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/reviewer/guidance/role.md +1 -0
- package/daemon/specs/agents/design/product-designer/agent.yaml +1 -1
- package/daemon/specs/agents/design/product-designer/guidance/role.md +1 -0
- package/daemon/specs/agents/development/implementer/agent.yaml +1 -1
- package/daemon/specs/agents/development/implementer/guidance/role.md +1 -0
- package/daemon/specs/agents/development/qa/agent.yaml +1 -1
- package/daemon/specs/agents/development/qa/guidance/role.md +1 -0
- package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +29 -0
- package/daemon/specs/agents/factory-rsi/dogfood/guidance/role.md +37 -0
- package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +29 -0
- package/daemon/specs/agents/factory-rsi/release-manager/guidance/role.md +40 -0
- package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +1 -1
- package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +1 -0
- package/daemon/specs/agents/product-management/pm/agent.yaml +1 -0
- package/daemon/specs/agents/product-management/pm/guidance/role.md +13 -0
- package/daemon/specs/agents/review/independent-reviewer/agent.yaml +1 -1
- package/daemon/specs/agents/review/independent-reviewer/guidance/role.md +1 -0
- package/daemon/specs/agents/shared/agent.yaml +2 -0
- package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +113 -0
- package/daemon/specs/agents/shared/skills/core/openrig-cmux/SKILL.md +86 -0
- package/daemon/specs/agents/shared/skills/core/openrig-herdr/SKILL.md +158 -0
- package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +4 -4
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +75 -29
- package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +2 -2
- package/daemon/specs/rigs/focused/pm-team/CULTURE.md +4 -0
- package/daemon/specs/rigs/launch/factory-rsi/CULTURE.md +47 -0
- package/daemon/specs/rigs/launch/factory-rsi/rig.yaml +115 -0
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +1 -1
- package/daemon/specs/rigs/launch/kernel/agents/operator/agent/startup/context.md +1 -1
- package/daemon/specs/rigs/preview/product-team/CULTURE.md +4 -0
- package/dist/build-info.d.ts +8 -0
- package/dist/build-info.d.ts.map +1 -0
- package/dist/build-info.js +11 -0
- package/dist/build-info.js.map +1 -0
- package/dist/commands/broadcast.d.ts +6 -1
- package/dist/commands/broadcast.d.ts.map +1 -1
- package/dist/commands/broadcast.js +101 -15
- package/dist/commands/broadcast.js.map +1 -1
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +99 -8
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/config-init-workspace.d.ts.map +1 -1
- package/dist/commands/config-init-workspace.js +20 -4
- package/dist/commands/config-init-workspace.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +4 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +5 -0
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/expand.js +1 -1
- package/dist/commands/expand.js.map +1 -1
- package/dist/commands/file.d.ts +7 -0
- package/dist/commands/file.d.ts.map +1 -0
- package/dist/commands/file.js +77 -0
- package/dist/commands/file.js.map +1 -0
- package/dist/commands/host.d.ts +48 -0
- package/dist/commands/host.d.ts.map +1 -0
- package/dist/commands/host.js +772 -0
- package/dist/commands/host.js.map +1 -0
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +5 -0
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/proof.d.ts +54 -0
- package/dist/commands/proof.d.ts.map +1 -0
- package/dist/commands/proof.js +311 -0
- package/dist/commands/proof.js.map +1 -0
- package/dist/commands/ps.d.ts +41 -7
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +353 -135
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +36 -0
- package/dist/commands/queue.d.ts.map +1 -1
- package/dist/commands/queue.js +149 -7
- package/dist/commands/queue.js.map +1 -1
- package/dist/commands/restore-packet.d.ts.map +1 -1
- package/dist/commands/restore-packet.js +13 -2
- package/dist/commands/restore-packet.js.map +1 -1
- package/dist/commands/scope.d.ts.map +1 -1
- package/dist/commands/scope.js +140 -3
- package/dist/commands/scope.js.map +1 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +127 -13
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/terminal.d.ts +6 -0
- package/dist/commands/terminal.d.ts.map +1 -0
- package/dist/commands/terminal.js +116 -0
- package/dist/commands/terminal.js.map +1 -0
- package/dist/commands/transcript.d.ts +6 -1
- package/dist/commands/transcript.d.ts.map +1 -1
- package/dist/commands/transcript.js +113 -30
- package/dist/commands/transcript.js.map +1 -1
- package/dist/commands/up.d.ts +2 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +78 -2
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +11 -0
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workflow-errors.d.ts +23 -0
- package/dist/commands/workflow-errors.d.ts.map +1 -0
- package/dist/commands/workflow-errors.js +100 -0
- package/dist/commands/workflow-errors.js.map +1 -0
- package/dist/commands/workflow-follow.d.ts +71 -0
- package/dist/commands/workflow-follow.d.ts.map +1 -0
- package/dist/commands/workflow-follow.js +259 -0
- package/dist/commands/workflow-follow.js.map +1 -0
- package/dist/commands/workflow-render.d.ts +114 -0
- package/dist/commands/workflow-render.d.ts.map +1 -0
- package/dist/commands/workflow-render.js +223 -0
- package/dist/commands/workflow-render.js.map +1 -0
- package/dist/commands/workflow.d.ts +1 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +278 -14
- package/dist/commands/workflow.js.map +1 -1
- package/dist/commands/workspace.js +6 -6
- package/dist/commands/workspace.js.map +1 -1
- package/dist/config-store.d.ts +19 -1
- package/dist/config-store.d.ts.map +1 -1
- package/dist/config-store.js +171 -0
- package/dist/config-store.js.map +1 -1
- package/dist/cross-host-cli-helpers.d.ts +13 -0
- package/dist/cross-host-cli-helpers.d.ts.map +1 -1
- package/dist/cross-host-cli-helpers.js +27 -0
- package/dist/cross-host-cli-helpers.js.map +1 -1
- package/dist/cross-host-executor.d.ts +1 -0
- package/dist/cross-host-executor.d.ts.map +1 -1
- package/dist/cross-host-executor.js +4 -1
- package/dist/cross-host-executor.js.map +1 -1
- package/dist/cross-host-target.d.ts +49 -0
- package/dist/cross-host-target.d.ts.map +1 -0
- package/dist/cross-host-target.js +35 -0
- package/dist/cross-host-target.js.map +1 -0
- package/dist/daemon-lifecycle.d.ts.map +1 -1
- package/dist/daemon-lifecycle.js +4 -1
- package/dist/daemon-lifecycle.js.map +1 -1
- package/dist/host-registry.d.ts +17 -0
- package/dist/host-registry.d.ts.map +1 -1
- package/dist/host-registry.js +64 -2
- package/dist/host-registry.js.map +1 -1
- package/dist/host-selection.d.ts +13 -0
- package/dist/host-selection.d.ts.map +1 -0
- package/dist/host-selection.js +54 -0
- package/dist/host-selection.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/file-transfer.d.ts +89 -0
- package/dist/lib/file-transfer.d.ts.map +1 -0
- package/dist/lib/file-transfer.js +300 -0
- package/dist/lib/file-transfer.js.map +1 -0
- package/dist/lib/hosts/fanout-contract.d.ts +33 -0
- package/dist/lib/hosts/fanout-contract.d.ts.map +1 -0
- package/dist/lib/hosts/fanout-contract.js +23 -0
- package/dist/lib/hosts/fanout-contract.js.map +1 -0
- package/dist/lib/scope/scope-audit.d.ts +9 -1
- package/dist/lib/scope/scope-audit.d.ts.map +1 -1
- package/dist/lib/scope/scope-audit.js +173 -1
- package/dist/lib/scope/scope-audit.js.map +1 -1
- package/dist/lib/scope/templates.d.ts +1 -0
- package/dist/lib/scope/templates.d.ts.map +1 -1
- package/dist/lib/scope/templates.js +9 -0
- package/dist/lib/scope/templates.js.map +1 -1
- package/dist/lib/scope-templates/backlog-deprecation.md +16 -0
- package/dist/lib/scope-templates/backlog-tech-debt.md +16 -0
- package/dist/lib/scope-templates/bug-fix.md +16 -0
- package/dist/lib/scope-templates/implementation-prd.md +33 -0
- package/dist/lib/scope-templates/mission-placeholder.md +1 -1
- package/dist/lib/scope-templates/mission-progress.md +1 -1
- package/dist/lib/scope-templates/mission-release.md +1 -1
- package/dist/lib/scope-templates/placeholder.md +11 -7
- package/dist/lib/scope-templates/proof.md +5 -1
- package/dist/lib/scope-templates/release-feature.md +14 -6
- package/dist/lib/scope-templates/research.md +16 -0
- package/dist/lib/scope-templates/slice-progress.md +1 -1
- package/dist/remote-host-ops.d.ts +1 -0
- package/dist/remote-host-ops.d.ts.map +1 -1
- package/dist/remote-host-ops.js +11 -4
- package/dist/remote-host-ops.js.map +1 -1
- package/dist/session-name.d.ts +23 -0
- package/dist/session-name.d.ts.map +1 -0
- package/dist/session-name.js +61 -0
- package/dist/session-name.js.map +1 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +11 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/ui/dist/assets/index-CFqxa0zW.css +32 -0
- package/ui/dist/assets/index-zrFqS7gL.js +623 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-DYZniQcc.js +0 -597
- package/ui/dist/assets/index-trcb4Yf_.css +0 -32
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fanout-contract.js","sourceRoot":"","sources":["../../../src/domain/hosts/fanout-contract.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,sEAAsE;AACtE,0EAA0E;AAC1E,4EAA4E;AAC5E,uEAAuE;AACvE,0EAA0E;AAC1E,sEAAsE;AACtE,uEAAuE;AAEvE;;kCAEkC;AAClC,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC;AA6BrC;;iDAEiD;AACjD,MAAM,UAAU,YAAY,CAAC,OAAmC,EAAE,eAAyB;IACzF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjF,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,eAAe,CAAC,MAAM,CAAC;AAC9G,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface SshHostEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
transport: "ssh";
|
|
4
|
+
target: string;
|
|
5
|
+
user?: string;
|
|
6
|
+
notes?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface HttpHostEntry {
|
|
9
|
+
id: string;
|
|
10
|
+
transport: "http";
|
|
11
|
+
url: string;
|
|
12
|
+
bearer_env?: string;
|
|
13
|
+
bearer_file?: string;
|
|
14
|
+
notes?: string;
|
|
15
|
+
}
|
|
16
|
+
export type HostEntry = SshHostEntry | HttpHostEntry;
|
|
17
|
+
export interface HostRegistry {
|
|
18
|
+
hosts: HostEntry[];
|
|
19
|
+
}
|
|
20
|
+
export type HostRegistryLoadResult = {
|
|
21
|
+
ok: true;
|
|
22
|
+
registry: HostRegistry;
|
|
23
|
+
} | {
|
|
24
|
+
ok: false;
|
|
25
|
+
error: string;
|
|
26
|
+
};
|
|
27
|
+
export type HostResolution = {
|
|
28
|
+
ok: true;
|
|
29
|
+
host: HostEntry;
|
|
30
|
+
} | {
|
|
31
|
+
ok: false;
|
|
32
|
+
error: string;
|
|
33
|
+
};
|
|
34
|
+
export declare const RESERVED_HOST_IDS: Set<string>;
|
|
35
|
+
export declare function defaultHostRegistryPath(): string;
|
|
36
|
+
/** Load + validate the operator's hosts registry (read-only). Mirrors the CLI
|
|
37
|
+
* loader's error surfaces so operators see one vocabulary everywhere. */
|
|
38
|
+
export declare function loadHostRegistry(path?: string): HostRegistryLoadResult;
|
|
39
|
+
export declare function validateHostRegistry(parsed: unknown, sourcePath: string): HostRegistryLoadResult;
|
|
40
|
+
/** Resolve a host id for placement. Unknown id names the requested id and
|
|
41
|
+
* lists up to 10 known ids — the FR-4 per-entry validation message rides
|
|
42
|
+
* this (what/why/fix, before any launch attempt). */
|
|
43
|
+
export declare function resolveHost(registry: HostRegistry, id: string): HostResolution;
|
|
44
|
+
/** FR-4: placement requires a transport that can carry remote-up. v0 that is
|
|
45
|
+
* the http transport (the shipped remote single-rig leaf is POST /api/up
|
|
46
|
+
* over runRemoteHttpOp); ssh-transport hosts are reachable for send/capture
|
|
47
|
+
* but cannot carry remote-up — a structured per-entry error, not a launch
|
|
48
|
+
* attempt. */
|
|
49
|
+
export declare function resolvePlacementHost(registry: HostRegistry, id: string): HostResolution;
|
|
50
|
+
//# sourceMappingURL=hosts-registry-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts-registry-reader.d.ts","sourceRoot":"","sources":["../../../src/domain/hosts/hosts-registry-reader.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAKjC,eAAO,MAAM,iBAAiB,aAAuC,CAAC;AAItE,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED;0EAC0E;AAC1E,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,MAAkC,GAAG,sBAAsB,CAoBjG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,sBAAsB,CAsGhG;AAED;;sDAEsD;AACtD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,CAW9E;AAED;;;;eAIe;AACf,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,cAAc,CAUvF"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// OPR.0.4.4.11 — the SHARED daemon-side hosts-registry read module (the P3/P4
|
|
2
|
+
// interface cell, pm-lead ruling c): P3 uses it for topology placement
|
|
3
|
+
// resolution + validation messages; P4's fan-out aggregation consumes the
|
|
4
|
+
// SAME module. Land once, here; P4 must not re-implement it.
|
|
5
|
+
//
|
|
6
|
+
// READ-ONLY FOREVER (arch ruling 3): the registry is operator-managed YAML at
|
|
7
|
+
// ~/.openrig/hosts.yaml; nothing in the daemon ever writes it. This module
|
|
8
|
+
// MIRRORS the CLI's packages/cli/src/host-registry.ts schema + validation
|
|
9
|
+
// (incl. the exactly-one-bearer rule) — the CLI copy is deliberately
|
|
10
|
+
// untouched this slice (no-unification boundary); the twin is held in sync by
|
|
11
|
+
// packages/daemon/test/hosts-registry-parity.test.ts, the same discipline as
|
|
12
|
+
// the scope-audit CLI/daemon twins.
|
|
13
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
14
|
+
import { parse as parseYaml } from "yaml";
|
|
15
|
+
import { getDefaultOpenRigPath } from "../../openrig-compat.js";
|
|
16
|
+
// OPR.0.4.6.MH1 FR-7 — reserved host ids, MIRRORED verbatim from the
|
|
17
|
+
// CLI twin (packages/cli/src/host-registry.ts RESERVED_HOST_IDS; the
|
|
18
|
+
// parity test pins both). See the CLI twin for the collision rationale.
|
|
19
|
+
export const RESERVED_HOST_IDS = new Set(["kernel", "host", "local"]);
|
|
20
|
+
const KNOWN_TRANSPORTS = new Set(["ssh", "http"]);
|
|
21
|
+
export function defaultHostRegistryPath() {
|
|
22
|
+
return getDefaultOpenRigPath("hosts.yaml");
|
|
23
|
+
}
|
|
24
|
+
/** Load + validate the operator's hosts registry (read-only). Mirrors the CLI
|
|
25
|
+
* loader's error surfaces so operators see one vocabulary everywhere. */
|
|
26
|
+
export function loadHostRegistry(path = defaultHostRegistryPath()) {
|
|
27
|
+
if (!existsSync(path)) {
|
|
28
|
+
return {
|
|
29
|
+
ok: false,
|
|
30
|
+
error: `host registry not found at ${path}. Create it with a 'hosts:' array; transport: ssh (target + user) or http (url + bearer_env/bearer_file).`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
let raw;
|
|
34
|
+
try {
|
|
35
|
+
raw = readFileSync(path, "utf-8");
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return { ok: false, error: `failed to read host registry at ${path}: ${err.message}` };
|
|
39
|
+
}
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = parseYaml(raw);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return { ok: false, error: `failed to parse host registry YAML at ${path}: ${err.message}` };
|
|
46
|
+
}
|
|
47
|
+
return validateHostRegistry(parsed, path);
|
|
48
|
+
}
|
|
49
|
+
export function validateHostRegistry(parsed, sourcePath) {
|
|
50
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
51
|
+
return { ok: false, error: `host registry at ${sourcePath} must be a YAML object with a 'hosts' array` };
|
|
52
|
+
}
|
|
53
|
+
const obj = parsed;
|
|
54
|
+
const hosts = obj["hosts"];
|
|
55
|
+
if (!Array.isArray(hosts)) {
|
|
56
|
+
return { ok: false, error: `host registry at ${sourcePath}: 'hosts' must be an array` };
|
|
57
|
+
}
|
|
58
|
+
const seenIds = new Set();
|
|
59
|
+
const validated = [];
|
|
60
|
+
for (let i = 0; i < hosts.length; i++) {
|
|
61
|
+
const raw = hosts[i];
|
|
62
|
+
const prefix = `host registry at ${sourcePath}: hosts[${i}]`;
|
|
63
|
+
if (raw === null || typeof raw !== "object") {
|
|
64
|
+
return { ok: false, error: `${prefix}: must be an object with id/transport/target` };
|
|
65
|
+
}
|
|
66
|
+
const entry = raw;
|
|
67
|
+
const id = entry["id"];
|
|
68
|
+
if (typeof id !== "string" || id.trim() === "") {
|
|
69
|
+
return { ok: false, error: `${prefix}.id: required non-empty string` };
|
|
70
|
+
}
|
|
71
|
+
if (seenIds.has(id)) {
|
|
72
|
+
return { ok: false, error: `${prefix}.id: duplicate host id '${id}' (each host id must be unique within the registry)` };
|
|
73
|
+
}
|
|
74
|
+
if (RESERVED_HOST_IDS.has(id)) {
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
error: `${prefix}.id: '${id}' is a reserved host id (reserved set: ${[...RESERVED_HOST_IDS].sort().join(", ")}). 'kernel' and 'host' collide with human-seat session classification (@kernel/@host), and 'local' is the local host itself — pick a different id.`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// OPR.0.4.6.MH1 rev1-r2 B1 — host ids name FILES (the pair verb's
|
|
81
|
+
// bearer_file path embeds the id) and render in tables: path-bearing
|
|
82
|
+
// ids are rejected at the registry door, same home as reserved ids.
|
|
83
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id)) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
error: `${prefix}.id: '${id}' is not a valid host id — allowed: letters, digits, dot, underscore, dash (starting with a letter or digit). Host ids name credential files; path characters are not allowed.`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
seenIds.add(id);
|
|
90
|
+
const transport = entry["transport"];
|
|
91
|
+
if (typeof transport !== "string" || !KNOWN_TRANSPORTS.has(transport)) {
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
error: `${prefix}.transport: must be one of ${[...KNOWN_TRANSPORTS].sort().join(", ")} (got ${JSON.stringify(transport)})`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const notes = entry["notes"];
|
|
98
|
+
if (notes !== undefined && typeof notes !== "string") {
|
|
99
|
+
return { ok: false, error: `${prefix}.notes: optional, but if present must be a string` };
|
|
100
|
+
}
|
|
101
|
+
if (transport === "ssh") {
|
|
102
|
+
const target = entry["target"];
|
|
103
|
+
if (typeof target !== "string" || target.trim() === "") {
|
|
104
|
+
return { ok: false, error: `${prefix}.target: required non-empty string (an ssh target)` };
|
|
105
|
+
}
|
|
106
|
+
const user = entry["user"];
|
|
107
|
+
if (user !== undefined && (typeof user !== "string" || user.trim() === "")) {
|
|
108
|
+
return { ok: false, error: `${prefix}.user: optional, but if present must be a non-empty string` };
|
|
109
|
+
}
|
|
110
|
+
validated.push({
|
|
111
|
+
id,
|
|
112
|
+
transport: "ssh",
|
|
113
|
+
target,
|
|
114
|
+
...(user !== undefined ? { user: user } : {}),
|
|
115
|
+
...(notes !== undefined ? { notes: notes } : {}),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else if (transport === "http") {
|
|
119
|
+
const url = entry["url"];
|
|
120
|
+
if (typeof url !== "string" || url.trim() === "") {
|
|
121
|
+
return { ok: false, error: `${prefix}.url: required non-empty string (the remote daemon's base URL)` };
|
|
122
|
+
}
|
|
123
|
+
const bearerEnv = entry["bearer_env"];
|
|
124
|
+
const bearerFile = entry["bearer_file"];
|
|
125
|
+
const hasEnv = bearerEnv !== undefined;
|
|
126
|
+
const hasFile = bearerFile !== undefined;
|
|
127
|
+
if (!hasEnv && !hasFile) {
|
|
128
|
+
return { ok: false, error: `${prefix}: http transport requires exactly one of bearer_env or bearer_file` };
|
|
129
|
+
}
|
|
130
|
+
if (hasEnv && hasFile) {
|
|
131
|
+
return { ok: false, error: `${prefix}: specify exactly one of bearer_env or bearer_file, not both` };
|
|
132
|
+
}
|
|
133
|
+
if (hasEnv && (typeof bearerEnv !== "string" || bearerEnv.trim() === "")) {
|
|
134
|
+
return { ok: false, error: `${prefix}.bearer_env: must be a non-empty env var name` };
|
|
135
|
+
}
|
|
136
|
+
if (hasFile && (typeof bearerFile !== "string" || bearerFile.trim() === "")) {
|
|
137
|
+
return { ok: false, error: `${prefix}.bearer_file: must be a non-empty file path` };
|
|
138
|
+
}
|
|
139
|
+
validated.push({
|
|
140
|
+
id,
|
|
141
|
+
transport: "http",
|
|
142
|
+
url: url,
|
|
143
|
+
...(hasEnv ? { bearer_env: bearerEnv } : {}),
|
|
144
|
+
...(hasFile ? { bearer_file: bearerFile } : {}),
|
|
145
|
+
...(notes !== undefined ? { notes: notes } : {}),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { ok: true, registry: { hosts: validated } };
|
|
150
|
+
}
|
|
151
|
+
/** Resolve a host id for placement. Unknown id names the requested id and
|
|
152
|
+
* lists up to 10 known ids — the FR-4 per-entry validation message rides
|
|
153
|
+
* this (what/why/fix, before any launch attempt). */
|
|
154
|
+
export function resolveHost(registry, id) {
|
|
155
|
+
const match = registry.hosts.find((h) => h.id === id);
|
|
156
|
+
if (match)
|
|
157
|
+
return { ok: true, host: match };
|
|
158
|
+
const knownIds = registry.hosts.map((h) => h.id).slice(0, 10);
|
|
159
|
+
const idsHint = knownIds.length > 0
|
|
160
|
+
? ` Known host ids: ${knownIds.join(", ")}${registry.hosts.length > knownIds.length ? ` (+${registry.hosts.length - knownIds.length} more)` : ""}.`
|
|
161
|
+
: " (registry is empty)";
|
|
162
|
+
return {
|
|
163
|
+
ok: false,
|
|
164
|
+
error: `unknown host id '${id}'.${idsHint}`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** FR-4: placement requires a transport that can carry remote-up. v0 that is
|
|
168
|
+
* the http transport (the shipped remote single-rig leaf is POST /api/up
|
|
169
|
+
* over runRemoteHttpOp); ssh-transport hosts are reachable for send/capture
|
|
170
|
+
* but cannot carry remote-up — a structured per-entry error, not a launch
|
|
171
|
+
* attempt. */
|
|
172
|
+
export function resolvePlacementHost(registry, id) {
|
|
173
|
+
const res = resolveHost(registry, id);
|
|
174
|
+
if (!res.ok)
|
|
175
|
+
return res;
|
|
176
|
+
if (res.host.transport !== "http") {
|
|
177
|
+
return {
|
|
178
|
+
ok: false,
|
|
179
|
+
error: `host '${id}' uses transport '${res.host.transport}', which cannot carry remote rig-up. Placement requires an http-transport host (url + bearer_env/bearer_file) — update the registry entry or launch that rig locally.`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return res;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=hosts-registry-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts-registry-reader.js","sourceRoot":"","sources":["../../../src/domain/hosts/hosts-registry-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type HostEntry } from "./hosts-registry-reader.js";
|
|
2
|
+
export type AddHostResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
path: string;
|
|
5
|
+
entry: HostEntry;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function addHostEntry(rawEntry: Record<string, unknown>, path?: string): AddHostResult;
|
|
11
|
+
//# sourceMappingURL=hosts-registry-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts-registry-writer.d.ts","sourceRoot":"","sources":["../../../src/domain/hosts/hosts-registry-writer.ts"],"names":[],"mappings":"AAwBA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,GAAE,MAAkC,GAAG,aAAa,CA6BvH"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// OPR.0.4.6.MH1 FR-5/FR-6 — the daemon-side hosts-registry WRITE twin
|
|
2
|
+
// (arch B1 ruling, pins P1–P4).
|
|
3
|
+
//
|
|
4
|
+
// The browser surface cannot reach the CLI's fs code, so the dashboard
|
|
5
|
+
// add/pair path writes through THIS module — a deliberate VERBATIM MIRROR
|
|
6
|
+
// of packages/cli/src/host-registry.ts addHostEntry, byte-parity-pinned
|
|
7
|
+
// by packages/daemon/test/hosts-add-pair-routes.test.ts (same entries in
|
|
8
|
+
// → identical yaml bytes out; P3) and sharing the reader twin's
|
|
9
|
+
// validateHostRegistry (identical validation: exactly-one-bearer,
|
|
10
|
+
// reserved ids, duplicate ids — P3). The reader module stays READ-ONLY
|
|
11
|
+
// FOREVER; writes flow ONLY through the single parity-pinned write
|
|
12
|
+
// contract (CLI addHostEntry + this twin), reachable daemon-side solely
|
|
13
|
+
// via the narrow named add/pair routes (P1 — no generic registry-write
|
|
14
|
+
// route exists).
|
|
15
|
+
//
|
|
16
|
+
// Concurrency (P4): atomic tmp+rename, whole-file LAST-WRITE-WINS on a
|
|
17
|
+
// concurrent add — the ceiling is one operator-scale registry file; NO
|
|
18
|
+
// locking machinery by design. Two simultaneous adds may drop one entry;
|
|
19
|
+
// re-running the add re-converges (add-time validation = load-time
|
|
20
|
+
// validation, verbatim).
|
|
21
|
+
import { existsSync, writeFileSync, renameSync, mkdirSync } from "node:fs";
|
|
22
|
+
import { dirname, join } from "node:path";
|
|
23
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
24
|
+
import { defaultHostRegistryPath, loadHostRegistry, validateHostRegistry, } from "./hosts-registry-reader.js";
|
|
25
|
+
export function addHostEntry(rawEntry, path = defaultHostRegistryPath()) {
|
|
26
|
+
// Load what exists; a MISSING file is a valid starting point for `add`
|
|
27
|
+
// (the verb exists so operators never hand-create the YAML), but a present-
|
|
28
|
+
// but-invalid file is a loud error — never silently clobber operator state.
|
|
29
|
+
let existing = [];
|
|
30
|
+
if (existsSync(path)) {
|
|
31
|
+
const loaded = loadHostRegistry(path);
|
|
32
|
+
if (!loaded.ok) {
|
|
33
|
+
return { ok: false, error: `refusing to modify an invalid registry: ${loaded.error}` };
|
|
34
|
+
}
|
|
35
|
+
existing = loaded.registry.hosts;
|
|
36
|
+
}
|
|
37
|
+
const candidate = { hosts: [...existing, rawEntry] };
|
|
38
|
+
const validated = validateHostRegistry(candidate, path);
|
|
39
|
+
if (!validated.ok) {
|
|
40
|
+
return { ok: false, error: validated.error };
|
|
41
|
+
}
|
|
42
|
+
const entry = validated.registry.hosts[validated.registry.hosts.length - 1];
|
|
43
|
+
try {
|
|
44
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
45
|
+
const tmp = join(dirname(path), `.hosts.yaml.tmp-${process.pid}`);
|
|
46
|
+
writeFileSync(tmp, stringifyYaml({ hosts: validated.registry.hosts }), { mode: 0o600 });
|
|
47
|
+
renameSync(tmp, path);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return { ok: false, error: `failed to write host registry at ${path}: ${err.message}` };
|
|
51
|
+
}
|
|
52
|
+
return { ok: true, path, entry };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=hosts-registry-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts-registry-writer.js","sourceRoot":"","sources":["../../../src/domain/hosts/hosts-registry-writer.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,gCAAgC;AAChC,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,wEAAwE;AACxE,yEAAyE;AACzE,gEAAgE;AAChE,kEAAkE;AAClE,uEAAuE;AACvE,mEAAmE;AACnE,wEAAwE;AACxE,uEAAuE;AACvE,iBAAiB;AACjB,EAAE;AACF,uEAAuE;AACvE,uEAAuE;AACvE,yEAAyE;AACzE,mEAAmE;AACnE,yBAAyB;AAEzB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,4BAA4B,CAAC;AAMpC,MAAM,UAAU,YAAY,CAAC,QAAiC,EAAE,OAAe,uBAAuB,EAAE;IACtG,uEAAuE;IACvE,4EAA4E;IAC5E,4EAA4E;IAC5E,IAAI,QAAQ,GAAgB,EAAE,CAAC;IAC/B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2CAA2C,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;QACzF,CAAC;QACD,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;IACnC,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;IACrD,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC;IAC/C,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IAE7E,IAAI,CAAC;QACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,mBAAmB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAClE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxF,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;IACrG,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Context, Next } from "hono";
|
|
2
|
+
export declare const READ_THROUGH_TIMEOUT_MS = 5000;
|
|
3
|
+
export declare const READ_THROUGH_ALLOWLIST: readonly ["/api/rigs/summary", "/api/rigs/:rigId/graph", "/api/rigs/:rigId/nodes", "/api/rigs/:rigId/nodes/:logicalId", "/api/ps", "/api/slices", "/api/slices/:name", "/api/slices/:name/doc/*", "/api/missions/:missionId", "/api/specs/library", "/api/specs/library/:id/review"];
|
|
4
|
+
export declare function isReadThroughPath(path: string): boolean;
|
|
5
|
+
/** The param-intercept middleware (arch E2 ruling). Mounted on /api/* ahead
|
|
6
|
+
* of the route table; consumes the `?host=` envelope for remote reads and
|
|
7
|
+
* passes everything else through untouched. */
|
|
8
|
+
export declare function hostReadThrough(): (c: Context, next: Next) => Promise<void | (Response & import("hono").TypedResponse<{
|
|
9
|
+
error: string;
|
|
10
|
+
boundary: string;
|
|
11
|
+
hostId: string;
|
|
12
|
+
method: string;
|
|
13
|
+
path: string;
|
|
14
|
+
message: string;
|
|
15
|
+
}, 405, "json">) | (Response & import("hono").TypedResponse<{
|
|
16
|
+
error: string;
|
|
17
|
+
boundary: string;
|
|
18
|
+
hostId: string;
|
|
19
|
+
path: string;
|
|
20
|
+
message: string;
|
|
21
|
+
}, 403, "json">) | (Response & import("hono").TypedResponse<{
|
|
22
|
+
detail: string;
|
|
23
|
+
remoteStatus?: number | undefined;
|
|
24
|
+
error: string;
|
|
25
|
+
hostId: string;
|
|
26
|
+
failureClass: string;
|
|
27
|
+
}, 502, "json">) | (Response & import("hono").TypedResponse<string, never, "body">)>;
|
|
28
|
+
//# sourceMappingURL=read-through.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-through.d.ts","sourceRoot":"","sources":["../../../src/domain/hosts/read-through.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAQ1C,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAmB7C,eAAO,MAAM,sBAAsB,sRAiBzB,CAAC;AAEX,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASvD;AAKD;;gDAEgD;AAChD,wBAAgB,eAAe,KACf,GAAG,OAAO,EAAE,MAAM,IAAI;;;;;;;;;;;;;;;;;;;qFAyErC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// OPR.0.4.6.MH2 FR-2 + FR-7 — the general single-host READ-THROUGH.
|
|
2
|
+
//
|
|
3
|
+
// The read twin of the shipped forward-then-strip write pattern
|
|
4
|
+
// (routes/mission-control.ts remote-forward leg): the browser stays
|
|
5
|
+
// same-origin against the LOCAL daemon; a `?host=<id>` query param is the
|
|
6
|
+
// out-of-band host envelope (MH-1 BR-1 rail — host never rides in a path or
|
|
7
|
+
// session identity). The daemon edge consumes the envelope: resolve the
|
|
8
|
+
// registry, forward the SAME path (envelope stripped) to the origin daemon
|
|
9
|
+
// over the shared bearer transport, and return the origin's response
|
|
10
|
+
// VERBATIM — status + content-type + body untouched (arch P3). Origin
|
|
11
|
+
// shapes stay the law: no AggregatedPayload wrapping on single-host reads.
|
|
12
|
+
//
|
|
13
|
+
// READ-ONLY IS ENFORCED HERE, AT THE EDGE (FR-7, arch R2): a non-GET
|
|
14
|
+
// request carrying a remote host envelope, or a GET outside the named
|
|
15
|
+
// allowlist below, is REFUSED with a structured error naming the MH-3
|
|
16
|
+
// boundary and is NEVER forwarded. The UI hiding mutation affordances is
|
|
17
|
+
// necessary but not the enforcement.
|
|
18
|
+
//
|
|
19
|
+
// local / absent host param short-circuits to the existing handler before
|
|
20
|
+
// any of this logic runs — the local path is unchanged by construction
|
|
21
|
+
// (FR-2 zero-regression negative).
|
|
22
|
+
import { LOCAL_HOST_ID } from "./fanout-contract.js";
|
|
23
|
+
import { loadHostRegistry, resolveHost } from "./hosts-registry-reader.js";
|
|
24
|
+
import { remoteRawRequest } from "./remote-daemon-http.js";
|
|
25
|
+
// The 5s single-host READ deadline class (matches the shipped aggregate
|
|
26
|
+
// read class in attention-aggregator.ts; deadline is a REQUIRED arg on the
|
|
27
|
+
// transport by arch ruling — named here, passed explicitly at the call).
|
|
28
|
+
export const READ_THROUGH_TIMEOUT_MS = 5_000;
|
|
29
|
+
// THE NAMED CLOSED ALLOWLIST (arch P1). One exported constant; additions
|
|
30
|
+
// are deliberate cross-review extensions, never drive-by edits — flag arch.
|
|
31
|
+
// Grammar: `:seg` matches exactly one non-empty path segment; a trailing
|
|
32
|
+
// `/*` matches one-or-more tail segments. v1 = the MVP read screens
|
|
33
|
+
// (topology / project / library / dashboard-ps) exactly.
|
|
34
|
+
//
|
|
35
|
+
// DELIBERATE EXCLUSIONS (recorded, not oversights): /api/queue/* (queue is
|
|
36
|
+
// the MH-3 lane — MH-1's queue-negative boundary, read included for now);
|
|
37
|
+
// /api/files/* (local FS discovery; the twin derives remote missions from
|
|
38
|
+
// the host-keyed slice list instead); /api/slices/:name/proof-asset/*
|
|
39
|
+
// (binary — the raw transport is text-only by design);
|
|
40
|
+
// /api/specs/library/active-lens (a local operator preference with write
|
|
41
|
+
// verbs — its literal segment cannot match `:id/review`'s shape).
|
|
42
|
+
// NUANCE (pinned by test): the slices REFRESH write is excluded by the
|
|
43
|
+
// METHOD tooth, not by path shape — `:name` matches the literal "refresh",
|
|
44
|
+
// so a GET there forwards and the origin resolves it as a slice named
|
|
45
|
+
// "refresh" (its own 404, verbatim); the POST can never cross the edge.
|
|
46
|
+
export const READ_THROUGH_ALLOWLIST = [
|
|
47
|
+
"/api/rigs/summary",
|
|
48
|
+
"/api/rigs/:rigId/graph",
|
|
49
|
+
"/api/rigs/:rigId/nodes",
|
|
50
|
+
// OPR.0.4.6.MH2 rev1-r2 B2 + arch ruling (qitem-…c5402960): seat detail
|
|
51
|
+
// is the LEAF of the FR-2 hierarchy — same read class as its /nodes
|
|
52
|
+
// sibling. STRICT SEGMENT-SHAPE match only (the arch tooth): the deeper
|
|
53
|
+
// ACTION routes under this prefix (…/:logicalId/focus, …/open-cmux)
|
|
54
|
+
// must stay REFUSED — pinned by named negatives.
|
|
55
|
+
"/api/rigs/:rigId/nodes/:logicalId",
|
|
56
|
+
"/api/ps",
|
|
57
|
+
"/api/slices",
|
|
58
|
+
"/api/slices/:name",
|
|
59
|
+
"/api/slices/:name/doc/*",
|
|
60
|
+
"/api/missions/:missionId",
|
|
61
|
+
"/api/specs/library",
|
|
62
|
+
"/api/specs/library/:id/review",
|
|
63
|
+
];
|
|
64
|
+
export function isReadThroughPath(path) {
|
|
65
|
+
const parts = path.split("/").filter((s) => s !== "");
|
|
66
|
+
return READ_THROUGH_ALLOWLIST.some((pattern) => {
|
|
67
|
+
const pat = pattern.split("/").filter((s) => s !== "");
|
|
68
|
+
const tailWild = pat[pat.length - 1] === "*";
|
|
69
|
+
const fixed = tailWild ? pat.slice(0, -1) : pat;
|
|
70
|
+
if (tailWild ? parts.length <= fixed.length : parts.length !== fixed.length)
|
|
71
|
+
return false;
|
|
72
|
+
return fixed.every((seg, i) => (seg.startsWith(":") ? parts[i] !== "" : seg === parts[i]));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const MH3_BOUNDARY_MESSAGE = "acting on a remote host is the MH-3 routing lane; the MH-2 read-through forwards allowlisted GET reads only";
|
|
76
|
+
/** The param-intercept middleware (arch E2 ruling). Mounted on /api/* ahead
|
|
77
|
+
* of the route table; consumes the `?host=` envelope for remote reads and
|
|
78
|
+
* passes everything else through untouched. */
|
|
79
|
+
export function hostReadThrough() {
|
|
80
|
+
return async (c, next) => {
|
|
81
|
+
const hostParam = c.req.query("host");
|
|
82
|
+
if (hostParam === undefined || hostParam === "" || hostParam === LOCAL_HOST_ID) {
|
|
83
|
+
return next();
|
|
84
|
+
}
|
|
85
|
+
const hostId = hostParam;
|
|
86
|
+
const path = c.req.path;
|
|
87
|
+
if (c.req.method !== "GET") {
|
|
88
|
+
// FR-7 tooth 1: a mutating request never crosses the edge.
|
|
89
|
+
return c.json({ error: "cross_host_write_refused", boundary: "MH-3", hostId, method: c.req.method, path, message: MH3_BOUNDARY_MESSAGE }, 405);
|
|
90
|
+
}
|
|
91
|
+
if (!isReadThroughPath(path)) {
|
|
92
|
+
// FR-7 tooth 2: reads outside the named closed set never cross either.
|
|
93
|
+
return c.json({ error: "read_through_path_not_allowed", boundary: "MH-3", hostId, path, message: MH3_BOUNDARY_MESSAGE }, 403);
|
|
94
|
+
}
|
|
95
|
+
// Arch P2 leg 1: registry-validated BEFORE any dial — an unknown id is a
|
|
96
|
+
// structured error, never a blind network attempt. Same injected-loader
|
|
97
|
+
// seam as the write twin (tests swap it; production reads the registry).
|
|
98
|
+
const registryLoader = c.get("hostRegistryLoader") ?? loadHostRegistry;
|
|
99
|
+
const fetchImpl = c.get("remoteFetchImpl");
|
|
100
|
+
const fail = (detail, failureClass, remoteStatus) => c.json({ error: "remote_read_failed", hostId, failureClass, ...(remoteStatus !== undefined ? { remoteStatus } : {}), detail }, 502);
|
|
101
|
+
const reg = registryLoader();
|
|
102
|
+
if (!reg.ok)
|
|
103
|
+
return fail(reg.error, "registry");
|
|
104
|
+
const resolved = resolveHost(reg.registry, hostId);
|
|
105
|
+
if (!resolved.ok)
|
|
106
|
+
return fail(resolved.error, "unknown-host");
|
|
107
|
+
if (resolved.host.transport !== "http") {
|
|
108
|
+
return fail(`host '${hostId}' is SSH-declared; the read-through requires an http-transport registry entry (url + bearer)`, "unsupported-transport");
|
|
109
|
+
}
|
|
110
|
+
// Arch P2 leg 2: STRIP IS TOTAL — the forwarded request carries no host
|
|
111
|
+
// param in any form, so the origin never sees the envelope and a
|
|
112
|
+
// forwarded request structurally cannot re-forward. Every OTHER query
|
|
113
|
+
// param rides through untouched (e.g. the slices filter).
|
|
114
|
+
const url = new URL(c.req.url);
|
|
115
|
+
url.searchParams.delete("host");
|
|
116
|
+
const forwardPath = `${path}${url.searchParams.size > 0 ? `?${url.searchParams.toString()}` : ""}`;
|
|
117
|
+
const res = await remoteRawRequest(resolved.host, forwardPath, {
|
|
118
|
+
timeoutMs: READ_THROUGH_TIMEOUT_MS,
|
|
119
|
+
fetchImpl,
|
|
120
|
+
});
|
|
121
|
+
if (res.ok) {
|
|
122
|
+
// Arch P3: the origin ANSWERED — its status/content-type/body ARE the
|
|
123
|
+
// answer, passed through untouched (its own 404/500 included). Edge
|
|
124
|
+
// taxonomy errors below are only for the forward itself failing.
|
|
125
|
+
return c.body(res.bodyText, res.status, { "Content-Type": res.contentType });
|
|
126
|
+
}
|
|
127
|
+
switch (res.kind) {
|
|
128
|
+
case "bearer":
|
|
129
|
+
return fail(res.detail, "auth-failed");
|
|
130
|
+
case "timeout":
|
|
131
|
+
return fail(res.phase === "body"
|
|
132
|
+
? `remote read timed out: response headers arrived (HTTP ${res.status}) but the body never completed`
|
|
133
|
+
: `remote read timed out after ${READ_THROUGH_TIMEOUT_MS}ms`, "unreachable", res.status);
|
|
134
|
+
case "network":
|
|
135
|
+
return fail(res.detail, "unreachable");
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=read-through.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-through.js","sourceRoot":"","sources":["../../../src/domain/hosts/read-through.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { HttpHostEntry } from "./hosts-registry-reader.js";
|
|
2
|
+
export interface RemoteJsonDeps {
|
|
3
|
+
/** Injected for tests; defaults to global fetch. */
|
|
4
|
+
fetchImpl?: typeof fetch;
|
|
5
|
+
env?: Record<string, string | undefined>;
|
|
6
|
+
readFile?: (path: string) => string;
|
|
7
|
+
}
|
|
8
|
+
export interface RemoteJsonOptions extends RemoteJsonDeps {
|
|
9
|
+
method: "GET" | "POST";
|
|
10
|
+
body?: unknown;
|
|
11
|
+
/** REQUIRED — the caller names its deadline class explicitly. */
|
|
12
|
+
timeoutMs: number;
|
|
13
|
+
}
|
|
14
|
+
export type RemoteJsonFailureKind = "bearer" | "timeout" | "network" | "http";
|
|
15
|
+
export interface RemoteJsonFailure {
|
|
16
|
+
ok: false;
|
|
17
|
+
kind: RemoteJsonFailureKind;
|
|
18
|
+
/** For kind=timeout: whether the deadline fired before headers
|
|
19
|
+
* ("request") or while reading the body ("body"). */
|
|
20
|
+
phase?: "request" | "body";
|
|
21
|
+
/** HTTP status when headers arrived (kind=http, or kind=timeout/phase=body). */
|
|
22
|
+
status?: number;
|
|
23
|
+
/** Bearer message / network error message / remote error text (may be ""). */
|
|
24
|
+
detail: string;
|
|
25
|
+
}
|
|
26
|
+
export type RemoteJsonResult = {
|
|
27
|
+
ok: true;
|
|
28
|
+
status: number;
|
|
29
|
+
payload: unknown;
|
|
30
|
+
} | RemoteJsonFailure;
|
|
31
|
+
export interface RemoteRawOptions extends RemoteJsonDeps {
|
|
32
|
+
/** REQUIRED — the caller names its deadline class explicitly. */
|
|
33
|
+
timeoutMs: number;
|
|
34
|
+
}
|
|
35
|
+
export type RemoteRawResult = {
|
|
36
|
+
ok: true;
|
|
37
|
+
status: number;
|
|
38
|
+
contentType: string;
|
|
39
|
+
bodyText: string;
|
|
40
|
+
} | {
|
|
41
|
+
ok: false;
|
|
42
|
+
kind: Exclude<RemoteJsonFailureKind, "http">;
|
|
43
|
+
phase?: "request" | "body";
|
|
44
|
+
status?: number;
|
|
45
|
+
detail: string;
|
|
46
|
+
};
|
|
47
|
+
/** One bounded daemon→daemon JSON exchange. The single deadline covers
|
|
48
|
+
* request + body; every outcome is structured — this function never hangs
|
|
49
|
+
* and never throws. */
|
|
50
|
+
export declare function remoteJsonRequest(host: HttpHostEntry, path: string, opts: RemoteJsonOptions): Promise<RemoteJsonResult>;
|
|
51
|
+
/** One bounded daemon→daemon GET, body passed through as text for ANY origin
|
|
52
|
+
* status (arch P3 verbatim rule). Same bearer resolution + single-deadline +
|
|
53
|
+
* explicit body race discipline as remoteJsonRequest; never hangs, never
|
|
54
|
+
* throws. */
|
|
55
|
+
export declare function remoteRawRequest(host: HttpHostEntry, path: string, opts: RemoteRawOptions): Promise<RemoteRawResult>;
|
|
56
|
+
//# sourceMappingURL=remote-daemon-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-daemon-http.d.ts","sourceRoot":"","sources":["../../../src/domain/hosts/remote-daemon-http.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,qBAAqB,CAAC;IAC5B;0DACsD;IACtD,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,iBAAiB,CAAC;AAElG,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAwB7H;;wBAEwB;AACxB,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmD7H;AAED;;;cAGc;AACd,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwC1H"}
|