@openrig/cli 0.3.1 → 0.3.3-rc.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/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +1 -1
- package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +8 -8
- package/daemon/dist/adapters/cmux-transport.d.ts.map +1 -1
- package/daemon/dist/adapters/cmux-transport.js +51 -9
- package/daemon/dist/adapters/cmux-transport.js.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +34 -5
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/tmux.d.ts +68 -1
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +141 -2
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/db/migrations/037_mission_control_actions.d.ts +5 -1
- package/daemon/dist/db/migrations/037_mission_control_actions.d.ts.map +1 -1
- package/daemon/dist/db/migrations/037_mission_control_actions.js +5 -1
- package/daemon/dist/db/migrations/037_mission_control_actions.js.map +1 -1
- package/daemon/dist/db/migrations/041_rig_policy.d.ts +32 -0
- package/daemon/dist/db/migrations/041_rig_policy.d.ts.map +1 -0
- package/daemon/dist/db/migrations/041_rig_policy.js +47 -0
- package/daemon/dist/db/migrations/041_rig_policy.js.map +1 -0
- package/daemon/dist/db/migrations/042_rig_archive.d.ts +16 -0
- package/daemon/dist/db/migrations/042_rig_archive.d.ts.map +1 -0
- package/daemon/dist/db/migrations/042_rig_archive.js +21 -0
- package/daemon/dist/db/migrations/042_rig_archive.js.map +1 -0
- package/daemon/dist/domain/agent-images/resume-token-discovery.js +1 -1
- package/daemon/dist/domain/agent-images/resume-token-discovery.js.map +1 -1
- package/daemon/dist/domain/agent-images/snapshot-capturer.d.ts.map +1 -1
- package/daemon/dist/domain/agent-images/snapshot-capturer.js +2 -1
- package/daemon/dist/domain/agent-images/snapshot-capturer.js.map +1 -1
- package/daemon/dist/domain/agent-manifest.js +27 -0
- package/daemon/dist/domain/agent-manifest.js.map +1 -1
- package/daemon/dist/domain/bootstrap-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/bootstrap-orchestrator.js +86 -6
- package/daemon/dist/domain/bootstrap-orchestrator.js.map +1 -1
- package/daemon/dist/domain/bundle-agent-images-router.d.ts +95 -0
- package/daemon/dist/domain/bundle-agent-images-router.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-agent-images-router.js +140 -0
- package/daemon/dist/domain/bundle-agent-images-router.js.map +1 -0
- package/daemon/dist/domain/bundle-assembler.d.ts +18 -1
- package/daemon/dist/domain/bundle-assembler.d.ts.map +1 -1
- package/daemon/dist/domain/bundle-assembler.js +11 -1
- package/daemon/dist/domain/bundle-assembler.js.map +1 -1
- package/daemon/dist/domain/bundle-audit.d.ts +89 -0
- package/daemon/dist/domain/bundle-audit.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-audit.js +87 -0
- package/daemon/dist/domain/bundle-audit.js.map +1 -0
- package/daemon/dist/domain/bundle-conflict-detector.d.ts +57 -0
- package/daemon/dist/domain/bundle-conflict-detector.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-conflict-detector.js +49 -0
- package/daemon/dist/domain/bundle-conflict-detector.js.map +1 -0
- package/daemon/dist/domain/bundle-context-packs-router.d.ts +100 -0
- package/daemon/dist/domain/bundle-context-packs-router.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-context-packs-router.js +158 -0
- package/daemon/dist/domain/bundle-context-packs-router.js.map +1 -0
- package/daemon/dist/domain/bundle-plugins-router.d.ts +69 -0
- package/daemon/dist/domain/bundle-plugins-router.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-plugins-router.js +87 -0
- package/daemon/dist/domain/bundle-plugins-router.js.map +1 -0
- package/daemon/dist/domain/bundle-skills-router.d.ts +62 -0
- package/daemon/dist/domain/bundle-skills-router.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-skills-router.js +90 -0
- package/daemon/dist/domain/bundle-skills-router.js.map +1 -0
- package/daemon/dist/domain/bundle-types.d.ts +106 -0
- package/daemon/dist/domain/bundle-types.d.ts.map +1 -1
- package/daemon/dist/domain/bundle-types.js +375 -0
- package/daemon/dist/domain/bundle-types.js.map +1 -1
- package/daemon/dist/domain/bundle-workflow-specs-router.d.ts +94 -0
- package/daemon/dist/domain/bundle-workflow-specs-router.d.ts.map +1 -0
- package/daemon/dist/domain/bundle-workflow-specs-router.js +144 -0
- package/daemon/dist/domain/bundle-workflow-specs-router.js.map +1 -0
- package/daemon/dist/domain/context-monitor.d.ts +5 -1
- package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
- package/daemon/dist/domain/context-monitor.js +28 -15
- package/daemon/dist/domain/context-monitor.js.map +1 -1
- package/daemon/dist/domain/graph-projection.d.ts +6 -0
- package/daemon/dist/domain/graph-projection.d.ts.map +1 -1
- package/daemon/dist/domain/graph-projection.js +6 -0
- package/daemon/dist/domain/graph-projection.js.map +1 -1
- package/daemon/dist/domain/native-resume-probe.js +7 -7
- package/daemon/dist/domain/native-resume-probe.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 +98 -0
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/node-launcher.d.ts +12 -0
- package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/node-launcher.js +25 -1
- package/daemon/dist/domain/node-launcher.js.map +1 -1
- package/daemon/dist/domain/pod-bundle-assembler.d.ts +16 -1
- package/daemon/dist/domain/pod-bundle-assembler.d.ts.map +1 -1
- package/daemon/dist/domain/pod-bundle-assembler.js +11 -1
- package/daemon/dist/domain/pod-bundle-assembler.js.map +1 -1
- package/daemon/dist/domain/profile-resolver.d.ts +10 -0
- package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
- package/daemon/dist/domain/profile-resolver.js +4 -0
- package/daemon/dist/domain/profile-resolver.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 +67 -1
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +37 -1
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
- package/daemon/dist/domain/queue-repository.js +99 -2
- package/daemon/dist/domain/queue-repository.js.map +1 -1
- package/daemon/dist/domain/restore-check-service.d.ts +4 -0
- package/daemon/dist/domain/restore-check-service.d.ts.map +1 -1
- package/daemon/dist/domain/restore-check-service.js +16 -7
- package/daemon/dist/domain/restore-check-service.js.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.d.ts +1 -1
- package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.js +12 -10
- package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
- package/daemon/dist/domain/rig-policy/rig-policy-defaults.d.ts +48 -0
- package/daemon/dist/domain/rig-policy/rig-policy-defaults.d.ts.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-defaults.js +96 -0
- package/daemon/dist/domain/rig-policy/rig-policy-defaults.js.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-store.d.ts +46 -0
- package/daemon/dist/domain/rig-policy/rig-policy-store.d.ts.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-store.js +171 -0
- package/daemon/dist/domain/rig-policy/rig-policy-store.js.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-types.d.ts +145 -0
- package/daemon/dist/domain/rig-policy/rig-policy-types.d.ts.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-types.js +52 -0
- package/daemon/dist/domain/rig-policy/rig-policy-types.js.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-validator.d.ts +58 -0
- package/daemon/dist/domain/rig-policy/rig-policy-validator.d.ts.map +1 -0
- package/daemon/dist/domain/rig-policy/rig-policy-validator.js +211 -0
- package/daemon/dist/domain/rig-policy/rig-policy-validator.js.map +1 -0
- package/daemon/dist/domain/rig-repository.d.ts +28 -2
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +40 -3
- package/daemon/dist/domain/rig-repository.js.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts +177 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.js +414 -55
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.d.ts +19 -1
- package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-preflight.js +30 -12
- package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
- package/daemon/dist/domain/rigspec-schema.d.ts +1 -0
- package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-schema.js +4 -1
- package/daemon/dist/domain/rigspec-schema.js.map +1 -1
- package/daemon/dist/domain/seat-activity-service.d.ts +79 -0
- package/daemon/dist/domain/seat-activity-service.d.ts.map +1 -0
- package/daemon/dist/domain/seat-activity-service.js +123 -0
- package/daemon/dist/domain/seat-activity-service.js.map +1 -0
- package/daemon/dist/domain/session-transport.d.ts +15 -0
- package/daemon/dist/domain/session-transport.d.ts.map +1 -1
- package/daemon/dist/domain/session-transport.js +8 -3
- package/daemon/dist/domain/session-transport.js.map +1 -1
- package/daemon/dist/domain/slices/slice-indexer.d.ts +12 -0
- package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
- package/daemon/dist/domain/slices/slice-indexer.js +23 -0
- package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
- package/daemon/dist/domain/spec-library-service.d.ts.map +1 -1
- package/daemon/dist/domain/spec-library-service.js +19 -0
- package/daemon/dist/domain/spec-library-service.js.map +1 -1
- package/daemon/dist/domain/topology-converge.d.ts +97 -0
- package/daemon/dist/domain/topology-converge.d.ts.map +1 -0
- package/daemon/dist/domain/topology-converge.js +70 -0
- package/daemon/dist/domain/topology-converge.js.map +1 -0
- package/daemon/dist/domain/types.d.ts +85 -3
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.js.map +1 -1
- package/daemon/dist/domain/whoami-service.d.ts +8 -0
- package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
- package/daemon/dist/domain/whoami-service.js +1 -0
- package/daemon/dist/domain/whoami-service.js.map +1 -1
- package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-runtime.js +9 -1
- package/daemon/dist/domain/workflow-runtime.js.map +1 -1
- package/daemon/dist/domain/workflow-spec-cache.d.ts +41 -0
- package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
- package/daemon/dist/domain/workflow-spec-cache.js +63 -0
- package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +7 -0
- package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js +156 -3
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
- package/daemon/dist/domain/workspace/workspace-doctor.d.ts +197 -0
- package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -0
- package/daemon/dist/domain/workspace/workspace-doctor.js +448 -0
- package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -0
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +11 -0
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/bundles.d.ts.map +1 -1
- package/daemon/dist/routes/bundles.js +966 -7
- package/daemon/dist/routes/bundles.js.map +1 -1
- package/daemon/dist/routes/config.d.ts.map +1 -1
- package/daemon/dist/routes/config.js +19 -2
- package/daemon/dist/routes/config.js.map +1 -1
- package/daemon/dist/routes/info.d.ts +3 -0
- package/daemon/dist/routes/info.d.ts.map +1 -0
- package/daemon/dist/routes/info.js +20 -0
- package/daemon/dist/routes/info.js.map +1 -0
- package/daemon/dist/routes/ps.js +4 -1
- package/daemon/dist/routes/ps.js.map +1 -1
- package/daemon/dist/routes/queue.d.ts +18 -0
- package/daemon/dist/routes/queue.d.ts.map +1 -1
- package/daemon/dist/routes/queue.js +97 -5
- package/daemon/dist/routes/queue.js.map +1 -1
- package/daemon/dist/routes/rig-policy.d.ts +9 -0
- package/daemon/dist/routes/rig-policy.d.ts.map +1 -0
- package/daemon/dist/routes/rig-policy.js +174 -0
- package/daemon/dist/routes/rig-policy.js.map +1 -0
- package/daemon/dist/routes/rigs.d.ts.map +1 -1
- package/daemon/dist/routes/rigs.js +134 -4
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/sessions.d.ts.map +1 -1
- package/daemon/dist/routes/sessions.js +26 -3
- package/daemon/dist/routes/sessions.js.map +1 -1
- package/daemon/dist/routes/up.d.ts +25 -0
- package/daemon/dist/routes/up.d.ts.map +1 -1
- package/daemon/dist/routes/up.js +70 -3
- package/daemon/dist/routes/up.js.map +1 -1
- package/daemon/dist/routes/workspace.d.ts.map +1 -1
- package/daemon/dist/routes/workspace.js +80 -1
- package/daemon/dist/routes/workspace.js.map +1 -1
- package/daemon/dist/server.d.ts +10 -0
- package/daemon/dist/server.d.ts.map +1 -1
- package/daemon/dist/server.js +11 -0
- package/daemon/dist/server.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +46 -4
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/getting-started.md +69 -0
- package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +28 -4
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +361 -15
- package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +2 -2
- package/daemon/specs/rigs/launch/conveyor/rig.yaml +1 -1
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +13 -1
- package/dist/client.js.map +1 -1
- package/dist/commands/add.d.ts +4 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +115 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/archive.d.ts +10 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +68 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/bootstrap.js +2 -2
- package/dist/commands/bootstrap.js.map +1 -1
- package/dist/commands/bundle.d.ts.map +1 -1
- package/dist/commands/bundle.js +123 -2
- package/dist/commands/bundle.js.map +1 -1
- package/dist/commands/config-init-workspace.d.ts.map +1 -1
- package/dist/commands/config-init-workspace.js +40 -5
- package/dist/commands/config-init-workspace.js.map +1 -1
- package/dist/commands/discover.js +2 -2
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/down.d.ts +1 -1
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +91 -3
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +72 -10
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +6 -0
- package/dist/commands/queue.d.ts.map +1 -1
- package/dist/commands/queue.js +103 -5
- package/dist/commands/queue.js.map +1 -1
- package/dist/commands/rig-policy.d.ts +48 -0
- package/dist/commands/rig-policy.d.ts.map +1 -0
- package/dist/commands/rig-policy.js +429 -0
- package/dist/commands/rig-policy.js.map +1 -0
- package/dist/commands/scope.d.ts +6 -0
- package/dist/commands/scope.d.ts.map +1 -0
- package/dist/commands/scope.js +659 -0
- package/dist/commands/scope.js.map +1 -0
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +11 -0
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/setup.d.ts +7 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +28 -1
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +35 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/unarchive.d.ts +10 -0
- package/dist/commands/unarchive.d.ts.map +1 -0
- package/dist/commands/unarchive.js +53 -0
- package/dist/commands/unarchive.js.map +1 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +97 -0
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +4 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workflow.d.ts +9 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +141 -4
- package/dist/commands/workflow.js.map +1 -1
- package/dist/commands/workspace.d.ts +20 -0
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js +140 -10
- package/dist/commands/workspace.js.map +1 -1
- package/dist/daemon-lifecycle.d.ts +48 -1
- package/dist/daemon-lifecycle.d.ts.map +1 -1
- package/dist/daemon-lifecycle.js +57 -2
- package/dist/daemon-lifecycle.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/scope/dot-id.d.ts +43 -0
- package/dist/lib/scope/dot-id.d.ts.map +1 -0
- package/dist/lib/scope/dot-id.js +165 -0
- package/dist/lib/scope/dot-id.js.map +1 -0
- package/dist/lib/scope/scope-fs.d.ts +79 -0
- package/dist/lib/scope/scope-fs.d.ts.map +1 -0
- package/dist/lib/scope/scope-fs.js +468 -0
- package/dist/lib/scope/scope-fs.js.map +1 -0
- package/dist/lib/scope/templates.d.ts +38 -0
- package/dist/lib/scope/templates.d.ts.map +1 -0
- package/dist/lib/scope/templates.js +109 -0
- package/dist/lib/scope/templates.js.map +1 -0
- package/dist/lib/scope/types.d.ts +61 -0
- package/dist/lib/scope/types.d.ts.map +1 -0
- package/dist/lib/scope/types.js +38 -0
- package/dist/lib/scope/types.js.map +1 -0
- package/dist/lib/scope-templates/backlog-deprecation.md +26 -0
- package/dist/lib/scope-templates/backlog-tech-debt.md +22 -0
- package/dist/lib/scope-templates/bug-fix.md +30 -0
- package/dist/lib/scope-templates/mission-notes.md +97 -0
- package/dist/lib/scope-templates/mission-placeholder.md +20 -0
- package/dist/lib/scope-templates/mission-release.md +25 -0
- package/dist/lib/scope-templates/placeholder.md +30 -0
- package/dist/lib/scope-templates/release-feature.md +26 -0
- package/dist/lib/scope-templates/research.md +22 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +29 -0
- package/dist/mcp-server.js.map +1 -1
- package/dist/release-surface/affected-skills.d.ts +49 -0
- package/dist/release-surface/affected-skills.d.ts.map +1 -0
- package/dist/release-surface/affected-skills.js +153 -0
- package/dist/release-surface/affected-skills.js.map +1 -0
- package/dist/release-surface/extract-surface.d.ts +23 -0
- package/dist/release-surface/extract-surface.d.ts.map +1 -0
- package/dist/release-surface/extract-surface.js +193 -0
- package/dist/release-surface/extract-surface.js.map +1 -0
- package/dist/release-surface/generate.d.ts +2 -0
- package/dist/release-surface/generate.d.ts.map +1 -0
- package/dist/release-surface/generate.js +51 -0
- package/dist/release-surface/generate.js.map +1 -0
- package/dist/release-surface/surface-diff.d.ts +40 -0
- package/dist/release-surface/surface-diff.d.ts.map +1 -0
- package/dist/release-surface/surface-diff.js +212 -0
- package/dist/release-surface/surface-diff.js.map +1 -0
- package/package.json +2 -2
- package/ui/dist/assets/index-CrJgCmkX.js +552 -0
- package/ui/dist/index.html +1 -1
- package/ui/dist/assets/index-Rl3ZBrUg.js +0 -547
|
@@ -240,8 +240,8 @@ export class RigInstantiator {
|
|
|
240
240
|
}
|
|
241
241
|
// -- Pod-aware instantiator (AgentSpec reboot) --
|
|
242
242
|
import { RigSpecCodec as PodRigSpecCodec } from "./rigspec-codec.js";
|
|
243
|
-
import { RigSpecSchema as PodRigSpecSchema } from "./rigspec-schema.js";
|
|
244
|
-
import { rigPreflight } from "./rigspec-preflight.js";
|
|
243
|
+
import { RigSpecSchema as PodRigSpecSchema, VALID_EDGE_KINDS } from "./rigspec-schema.js";
|
|
244
|
+
import { rigPreflight, preflightValidatedSpec } from "./rigspec-preflight.js";
|
|
245
245
|
import { resolveAgentRef } from "./agent-resolver.js";
|
|
246
246
|
import { resolveNodeConfig } from "./profile-resolver.js";
|
|
247
247
|
import { resolveStartup } from "./startup-resolver.js";
|
|
@@ -296,6 +296,57 @@ export class PodRigInstantiator {
|
|
|
296
296
|
if (!preflight.ready) {
|
|
297
297
|
return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
|
|
298
298
|
}
|
|
299
|
+
// OPR.0.3.3.24: parse/validate/preflight is the separable FRONT-END; the
|
|
300
|
+
// persistence CORE (createPod + create-node + edges + events, in one tx)
|
|
301
|
+
// takes the already-parsed+validated spec so `expand` and the `add_member`
|
|
302
|
+
// converge op compose it WITHOUT fabricating a synthetic rig spec.
|
|
303
|
+
return this.materializeValidatedSpec(rigSpec, rigRoot, opts);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* materialize with a STRUCTURED front (OPR.0.3.3.24): the YAML-free sibling of
|
|
307
|
+
* materialize(). Runs the SAME front-end (validate + preflight, via the
|
|
308
|
+
* preflight CORE using this adapter's fsOps) on an already-built raw spec
|
|
309
|
+
* OBJECT, then the persistence core - so `expand` (and the add_member op) drop
|
|
310
|
+
* the synthetic-spec YAML round-trip. Byte-identical to materialize(yaml): same
|
|
311
|
+
* validate(externalQualifiedIds), same preflight checks, same MaterializeOutcome
|
|
312
|
+
* error codes (validation_failed / preflight_failed / target_rig_not_found /
|
|
313
|
+
* materialize_conflict). fsOps stays encapsulated here (the expansion service
|
|
314
|
+
* has none) - this wrapper is mechanics only, no behaviour/layering change.
|
|
315
|
+
*/
|
|
316
|
+
async materializeStructured(raw, rigRoot, opts) {
|
|
317
|
+
const targetRig = opts?.targetRigId ? this.deps.rigRepo.getRig(opts.targetRigId) : null;
|
|
318
|
+
if (opts?.targetRigId && !targetRig) {
|
|
319
|
+
return { ok: false, code: "target_rig_not_found", message: `Rig "${opts.targetRigId}" not found` };
|
|
320
|
+
}
|
|
321
|
+
const validation = PodRigSpecSchema.validate(raw, {
|
|
322
|
+
externalQualifiedIds: targetRig?.nodes.map((node) => node.logicalId),
|
|
323
|
+
});
|
|
324
|
+
if (!validation.valid) {
|
|
325
|
+
return { ok: false, code: "validation_failed", errors: validation.errors };
|
|
326
|
+
}
|
|
327
|
+
const rigSpec = PodRigSpecSchema.normalize(raw);
|
|
328
|
+
const preflight = preflightValidatedSpec(rigSpec, {
|
|
329
|
+
rigRoot,
|
|
330
|
+
cwdOverride: opts?.cwdOverride,
|
|
331
|
+
fsOps: this.deps.fsOps,
|
|
332
|
+
rigNameOverride: targetRig?.rig.name,
|
|
333
|
+
});
|
|
334
|
+
if (!preflight.ready) {
|
|
335
|
+
return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
|
|
336
|
+
}
|
|
337
|
+
return this.materializeValidatedSpec(rigSpec, rigRoot, opts);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* materialize CORE (OPR.0.3.3.24): the persistence body of materialize, taking
|
|
341
|
+
* an already-parsed + validated + preflighted PodRigSpec. Creates pods +
|
|
342
|
+
* member nodes (via the create-node primitive) + edges + events in one
|
|
343
|
+
* transaction. Parse/validate/preflight is the caller's separable front-end
|
|
344
|
+
* (materialize() for YAML; expand/add_member build + validate a structured
|
|
345
|
+
* spec). This is the cut that lets `expand` drop its synthetic-spec hack and
|
|
346
|
+
* `add_member` reuse the exact create path — create+launch only, no identity
|
|
347
|
+
* migration.
|
|
348
|
+
*/
|
|
349
|
+
async materializeValidatedSpec(rigSpec, rigRoot, opts) {
|
|
299
350
|
const persistedEvents = [];
|
|
300
351
|
const nodeResults = [];
|
|
301
352
|
try {
|
|
@@ -342,26 +393,17 @@ export class PodRigInstantiator {
|
|
|
342
393
|
}));
|
|
343
394
|
for (const member of pod.members) {
|
|
344
395
|
const qualifiedId = `${pod.id}.${member.id}`;
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
codexConfigProfile: member.codexConfigProfile,
|
|
350
|
-
cwd: effectiveCwd,
|
|
351
|
-
restorePolicy: member.restorePolicy,
|
|
396
|
+
const { node, event } = this.createMemberNode({
|
|
397
|
+
rigId: materializedRigId,
|
|
398
|
+
qualifiedId,
|
|
399
|
+
member,
|
|
352
400
|
podId: podRecord.id,
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
label: member.label,
|
|
401
|
+
rigRoot,
|
|
402
|
+
cwdOverride: opts?.cwdOverride,
|
|
356
403
|
});
|
|
357
404
|
logicalIdToNodeId.set(qualifiedId, node.id);
|
|
358
405
|
nodeResults.push({ logicalId: qualifiedId, status: "materialized" });
|
|
359
|
-
persistedEvents.push(
|
|
360
|
-
type: "node.added",
|
|
361
|
-
rigId: materializedRigId,
|
|
362
|
-
nodeId: node.id,
|
|
363
|
-
logicalId: qualifiedId,
|
|
364
|
-
}));
|
|
406
|
+
persistedEvents.push(event);
|
|
365
407
|
}
|
|
366
408
|
}
|
|
367
409
|
for (const pod of rigSpec.pods) {
|
|
@@ -434,6 +476,17 @@ export class PodRigInstantiator {
|
|
|
434
476
|
return { ok: false, code: "validation_failed", errors: validation.errors };
|
|
435
477
|
}
|
|
436
478
|
const rigSpec = PodRigSpecSchema.normalize(raw);
|
|
479
|
+
return this.launchValidatedSpec(rigSpec, rigRoot, targetRigId);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* launch CORE (OPR.0.3.3.24): given an already-parsed+validated spec whose
|
|
483
|
+
* nodes are already materialized, compute launch order and bring each node
|
|
484
|
+
* live via the launch-binding primitive. Extracted from launchMaterialized so
|
|
485
|
+
* `expand` (and the add_member op) launch a structured spec WITHOUT a YAML
|
|
486
|
+
* round-trip; launchMaterialized(yaml) is the parse/validate/normalize front
|
|
487
|
+
* over it. Behaviour identical (loop body relocated verbatim).
|
|
488
|
+
*/
|
|
489
|
+
async launchValidatedSpec(rigSpec, rigRoot, targetRigId) {
|
|
437
490
|
const launchOrder = this.computePodLaunchOrder(rigSpec);
|
|
438
491
|
const podWarnings = [];
|
|
439
492
|
const nodeResults = [];
|
|
@@ -458,25 +511,15 @@ export class PodRigInstantiator {
|
|
|
458
511
|
});
|
|
459
512
|
continue;
|
|
460
513
|
}
|
|
461
|
-
const launched =
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
})
|
|
471
|
-
: await this.launchExistingAgentMember({
|
|
472
|
-
rigId: targetRigId,
|
|
473
|
-
rigSpec,
|
|
474
|
-
rigRoot,
|
|
475
|
-
pod: memberContext.pod,
|
|
476
|
-
member: memberContext.member,
|
|
477
|
-
qualifiedId: logicalId,
|
|
478
|
-
nodeId: node.id,
|
|
479
|
-
});
|
|
514
|
+
const launched = await this.launchBinding({
|
|
515
|
+
rigId: targetRigId,
|
|
516
|
+
rigSpec,
|
|
517
|
+
rigRoot,
|
|
518
|
+
pod: memberContext.pod,
|
|
519
|
+
member: memberContext.member,
|
|
520
|
+
qualifiedId: logicalId,
|
|
521
|
+
nodeId: node.id,
|
|
522
|
+
});
|
|
480
523
|
if (launched.warnings?.length) {
|
|
481
524
|
podWarnings.push(...launched.warnings);
|
|
482
525
|
}
|
|
@@ -496,6 +539,187 @@ export class PodRigInstantiator {
|
|
|
496
539
|
},
|
|
497
540
|
};
|
|
498
541
|
}
|
|
542
|
+
/**
|
|
543
|
+
* add_member converge op (OPR.0.3.3.24): add a single MEMBER to an EXISTING
|
|
544
|
+
* pod in a live rig, composing the two extracted primitives — createMemberNode
|
|
545
|
+
* (create-node) + launchBinding (launch-binding) — WITHOUT createPod and
|
|
546
|
+
* WITHOUT fabricating a synthetic rig spec.
|
|
547
|
+
*
|
|
548
|
+
* Identity-migration-FREE: the new node mints a fresh node id + fresh logical
|
|
549
|
+
* id + fresh `@rigged_*` at launch; no existing seat's logical id,
|
|
550
|
+
* continuity_state, queue routing, or session is re-keyed. This is the
|
|
551
|
+
* source-visible fault line that lets add_member ship while move/fork wait for
|
|
552
|
+
* the 0.4.0 identity stack.
|
|
553
|
+
*
|
|
554
|
+
* Versus materialize: this does NOT call materializeValidatedSpec (which always
|
|
555
|
+
* createPods and carries the pod-exists conflict guard). It resolves the
|
|
556
|
+
* EXISTING pod's DB id via `podRepo.getPodByNamespace` and creates the one node
|
|
557
|
+
* directly under it. The pod-exists guard is lifted (adding to a live pod is
|
|
558
|
+
* not a conflict); the per-member duplicate-logical-id guard is KEPT (AC-3).
|
|
559
|
+
*/
|
|
560
|
+
async addMemberToPod(rigId, podNamespace, memberFragment, rigRoot, opts) {
|
|
561
|
+
// 1. Resolve the rig.
|
|
562
|
+
const rig = this.deps.rigRepo.getRig(rigId);
|
|
563
|
+
if (!rig) {
|
|
564
|
+
return { ok: false, code: "rig_not_found", message: `Rig "${rigId}" not found.` };
|
|
565
|
+
}
|
|
566
|
+
// 2. Resolve the EXISTING pod's DB id via getPodByNamespace (the corrected
|
|
567
|
+
// pod-id source — NOT a pre-computed namespace->podId map). Honest not-found
|
|
568
|
+
// with the available namespaces so the caller can correct the handle.
|
|
569
|
+
const pod = this.deps.podRepo.getPodByNamespace(rigId, podNamespace);
|
|
570
|
+
if (!pod) {
|
|
571
|
+
const available = this.deps.podRepo.getPodsForRig(rigId).map((p) => p.namespace);
|
|
572
|
+
const hint = available.length > 0 ? available.join(", ") : "(none)";
|
|
573
|
+
return {
|
|
574
|
+
ok: false,
|
|
575
|
+
code: "pod_not_found",
|
|
576
|
+
message: `Pod "${podNamespace}" not found in rig "${rig.rig.name}". Existing pods: ${hint}. Check the namespace, or add a new pod with \`rig expand\`.`,
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
// 3. Build a minimal one-pod-one-member raw spec around the EXISTING pod so
|
|
580
|
+
// the new member runs the SAME validate + preflight the materialize front
|
|
581
|
+
// does — without a whole-rig spec or a YAML round-trip. The member fragment
|
|
582
|
+
// is embedded raw (spec snake_case shape, as expand's structured path emits);
|
|
583
|
+
// validate/normalize is the type gate.
|
|
584
|
+
const rawSpec = {
|
|
585
|
+
version: "0.2",
|
|
586
|
+
name: rig.rig.name,
|
|
587
|
+
pods: [{ id: podNamespace, label: pod.label, members: [memberFragment], edges: [] }],
|
|
588
|
+
edges: [],
|
|
589
|
+
};
|
|
590
|
+
// 4. Validate + normalize. externalQualifiedIds is the existing rig's node
|
|
591
|
+
// set (matches the materialize front; used for cross-pod edge resolution).
|
|
592
|
+
const validation = PodRigSpecSchema.validate(rawSpec, {
|
|
593
|
+
externalQualifiedIds: rig.nodes.map((node) => node.logicalId),
|
|
594
|
+
});
|
|
595
|
+
if (!validation.valid) {
|
|
596
|
+
return { ok: false, code: "validation_failed", errors: validation.errors };
|
|
597
|
+
}
|
|
598
|
+
const rigSpec = PodRigSpecSchema.normalize(rawSpec);
|
|
599
|
+
const member = rigSpec.pods[0].members[0];
|
|
600
|
+
const qualifiedId = `${podNamespace}.${member.id}`;
|
|
601
|
+
// 5. KEEP the per-member duplicate-logical-id guard (AC-3). The pod-exists
|
|
602
|
+
// guard is lifted (we are adding to a live pod on purpose), but minting a
|
|
603
|
+
// colliding logical id would be a real seat collision — reject it honestly.
|
|
604
|
+
// (validate's externalQualifiedIds only resolves edge targets; it does NOT
|
|
605
|
+
// reject a member colliding with an existing node, so this guard is load-bearing.)
|
|
606
|
+
if (rig.nodes.some((node) => node.logicalId === qualifiedId)) {
|
|
607
|
+
return {
|
|
608
|
+
ok: false,
|
|
609
|
+
code: "member_conflict",
|
|
610
|
+
message: `Member "${qualifiedId}" already exists in rig "${rig.rig.name}". Pick a different member id, or remove the existing seat first.`,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
// 6. Preflight the new member on the normalized spec (same checks the
|
|
614
|
+
// materialize front runs, via the core, using this adapter's fsOps).
|
|
615
|
+
// rigNameOverride suppresses the rig-name-collision check (we are appending
|
|
616
|
+
// to an existing rig, exactly like expand's structured path).
|
|
617
|
+
const preflight = preflightValidatedSpec(rigSpec, {
|
|
618
|
+
rigRoot,
|
|
619
|
+
cwdOverride: opts?.cwdOverride,
|
|
620
|
+
fsOps: this.deps.fsOps,
|
|
621
|
+
rigNameOverride: rig.rig.name,
|
|
622
|
+
});
|
|
623
|
+
if (!preflight.ready) {
|
|
624
|
+
return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
|
|
625
|
+
}
|
|
626
|
+
// 7. Validate + resolve any declared pod-local edges BEFORE creating the
|
|
627
|
+
// node, so a bad edge fails fast with no orphan seat. Two honest failure
|
|
628
|
+
// classes: (a) DECLARATION validity (non-array / empty fields / a kind
|
|
629
|
+
// outside the canonical VALID_EDGE_KINDS - mirrors the rigspec pod-local
|
|
630
|
+
// edge contract, NOT a second looser path) -> validation_failed; (b) live
|
|
631
|
+
// ENDPOINT resolution against the new member + existing pod-mates ->
|
|
632
|
+
// edge_unresolved. Edges carry NO runtime behavior yet (the edge-runtime
|
|
633
|
+
// fence); we persist the declared graph so it is NOT silently dropped (FM2).
|
|
634
|
+
const rawEdges = opts?.edges;
|
|
635
|
+
if (rawEdges !== undefined && rawEdges !== null && !Array.isArray(rawEdges)) {
|
|
636
|
+
return { ok: false, code: "validation_failed", errors: ["edges: must be an array of { from, to, kind }"] };
|
|
637
|
+
}
|
|
638
|
+
const declaredEdges = Array.isArray(rawEdges) ? rawEdges : [];
|
|
639
|
+
const edgeErrors = [];
|
|
640
|
+
declaredEdges.forEach((edge, i) => {
|
|
641
|
+
if (typeof edge?.from !== "string" || typeof edge?.to !== "string" || typeof edge?.kind !== "string"
|
|
642
|
+
|| edge.from.trim() === "" || edge.to.trim() === "" || edge.kind.trim() === "") {
|
|
643
|
+
edgeErrors.push(`edges[${i}]: from, to, and kind are required non-empty strings`);
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
if (!VALID_EDGE_KINDS.has(edge.kind)) {
|
|
647
|
+
edgeErrors.push(`edges[${i}].kind: must be one of ${[...VALID_EDGE_KINDS].join(", ")} (got "${edge.kind}")`);
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
if (edgeErrors.length > 0) {
|
|
651
|
+
return { ok: false, code: "validation_failed", errors: edgeErrors };
|
|
652
|
+
}
|
|
653
|
+
const knownLogicalIds = new Set([...rig.nodes.map((node) => node.logicalId), qualifiedId]);
|
|
654
|
+
const resolvedEdges = [];
|
|
655
|
+
for (const edge of declaredEdges) {
|
|
656
|
+
const from = `${podNamespace}.${edge.from}`;
|
|
657
|
+
const to = `${podNamespace}.${edge.to}`;
|
|
658
|
+
if (!knownLogicalIds.has(from) || !knownLogicalIds.has(to)) {
|
|
659
|
+
const missing = !knownLogicalIds.has(from) ? from : to;
|
|
660
|
+
return { ok: false, code: "edge_unresolved", message: `Pod-local edge references "${missing}", which is neither the new member "${qualifiedId}" nor an existing seat in rig "${rig.rig.name}". Use member ids within pod "${podNamespace}".` };
|
|
661
|
+
}
|
|
662
|
+
resolvedEdges.push({ from, to, kind: edge.kind });
|
|
663
|
+
}
|
|
664
|
+
// 8. create-node into the EXISTING pod (pod_id = resolved pod.id) + persist
|
|
665
|
+
// the resolved pod-local edges, all in one tx so the node row, the
|
|
666
|
+
// node.added event, and the edges commit atomically (mirroring the
|
|
667
|
+
// materialize core); subscribers notified after commit.
|
|
668
|
+
let createdNodeId = "";
|
|
669
|
+
let createdEvent;
|
|
670
|
+
const tx = this.db.transaction(() => {
|
|
671
|
+
const { node, event } = this.createMemberNode({
|
|
672
|
+
rigId,
|
|
673
|
+
qualifiedId,
|
|
674
|
+
member,
|
|
675
|
+
podId: pod.id,
|
|
676
|
+
rigRoot,
|
|
677
|
+
cwdOverride: opts?.cwdOverride,
|
|
678
|
+
});
|
|
679
|
+
createdNodeId = node.id;
|
|
680
|
+
createdEvent = event;
|
|
681
|
+
if (resolvedEdges.length > 0) {
|
|
682
|
+
const logicalIdToNodeId = new Map(rig.nodes.map((n) => [n.logicalId, n.id]));
|
|
683
|
+
logicalIdToNodeId.set(qualifiedId, node.id);
|
|
684
|
+
for (const edge of resolvedEdges) {
|
|
685
|
+
this.deps.rigRepo.addEdge(rigId, logicalIdToNodeId.get(edge.from), logicalIdToNodeId.get(edge.to), edge.kind);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
tx();
|
|
690
|
+
if (createdEvent)
|
|
691
|
+
this.deps.eventBus.notifySubscribers(createdEvent);
|
|
692
|
+
// 9. launch-binding for the one new node (startup projection + delivery +
|
|
693
|
+
// readiness + `@rigged_*`). The minimal spec supplies the member/pod/rig
|
|
694
|
+
// context launchBinding needs; the derived session name is
|
|
695
|
+
// `${podNamespace}-${member.id}@${rig.name}` — queue-addressable immediately.
|
|
696
|
+
const launched = await this.launchBinding({
|
|
697
|
+
rigId,
|
|
698
|
+
rigSpec,
|
|
699
|
+
rigRoot,
|
|
700
|
+
pod: rigSpec.pods[0],
|
|
701
|
+
member,
|
|
702
|
+
qualifiedId,
|
|
703
|
+
nodeId: createdNodeId,
|
|
704
|
+
cwdOverride: opts?.cwdOverride,
|
|
705
|
+
});
|
|
706
|
+
return {
|
|
707
|
+
ok: true,
|
|
708
|
+
result: {
|
|
709
|
+
podId: pod.id,
|
|
710
|
+
podNamespace,
|
|
711
|
+
node: {
|
|
712
|
+
logicalId: qualifiedId,
|
|
713
|
+
nodeId: createdNodeId,
|
|
714
|
+
status: launched.status,
|
|
715
|
+
error: launched.error,
|
|
716
|
+
sessionName: launched.sessionName,
|
|
717
|
+
},
|
|
718
|
+
edges: resolvedEdges,
|
|
719
|
+
warnings: launched.warnings,
|
|
720
|
+
},
|
|
721
|
+
};
|
|
722
|
+
}
|
|
499
723
|
async instantiate(rigSpecYaml, rigRoot, opts) {
|
|
500
724
|
// 1. Parse + validate
|
|
501
725
|
let rigSpec;
|
|
@@ -515,7 +739,21 @@ export class PodRigInstantiator {
|
|
|
515
739
|
if (!preflight.ready) {
|
|
516
740
|
return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
|
|
517
741
|
}
|
|
518
|
-
// 3.
|
|
742
|
+
// 3. Compute launch order from edges (rejects cycles)
|
|
743
|
+
//
|
|
744
|
+
// OPR.0.3.2.22 Bug 2: this MUST run BEFORE createRig. Pre-fix, a
|
|
745
|
+
// cycle in the spec left an orphan stopped-state rig record because
|
|
746
|
+
// createRig had already committed before the cycle check ran. The
|
|
747
|
+
// operator-facing consequence was the "ambiguous library-spec vs
|
|
748
|
+
// restore-target" UX trap on the very next `rig up <builtin>` retry.
|
|
749
|
+
let launchOrder;
|
|
750
|
+
try {
|
|
751
|
+
launchOrder = this.computePodLaunchOrder(rigSpec);
|
|
752
|
+
}
|
|
753
|
+
catch (err) {
|
|
754
|
+
return { ok: false, code: "cycle_error", message: err.message };
|
|
755
|
+
}
|
|
756
|
+
// 4. Create rig (after cycle check passes)
|
|
519
757
|
let rigId;
|
|
520
758
|
try {
|
|
521
759
|
const rig = this.deps.rigRepo.createRig(rigSpec.name);
|
|
@@ -529,14 +767,6 @@ export class PodRigInstantiator {
|
|
|
529
767
|
catch (err) {
|
|
530
768
|
return { ok: false, code: "instantiate_error", message: err.message };
|
|
531
769
|
}
|
|
532
|
-
// 4. Compute launch order from edges (rejects cycles)
|
|
533
|
-
let launchOrder;
|
|
534
|
-
try {
|
|
535
|
-
launchOrder = this.computePodLaunchOrder(rigSpec);
|
|
536
|
-
}
|
|
537
|
-
catch (err) {
|
|
538
|
-
return { ok: false, code: "cycle_error", message: err.message };
|
|
539
|
-
}
|
|
540
770
|
// 5. Create pods + nodes + edges, then launch in topological order
|
|
541
771
|
const nodeResults = [];
|
|
542
772
|
const nodeIdMap = {}; // "pod.member" -> node DB id
|
|
@@ -568,10 +798,15 @@ export class PodRigInstantiator {
|
|
|
568
798
|
// Sort members by topological launch order
|
|
569
799
|
const orderMap = new Map(launchOrder.map((id, i) => [id, i]));
|
|
570
800
|
memberEntries.sort((a, b) => (orderMap.get(a.qualifiedId) ?? 999) - (orderMap.get(b.qualifiedId) ?? 999));
|
|
571
|
-
// Prelaunch hook: service gate runs after topology setup, before any node launch
|
|
801
|
+
// Prelaunch hook: service gate runs after topology setup, before any node launch.
|
|
802
|
+
//
|
|
803
|
+
// OPR.0.3.2.22 Bug 2: if the hook fails, roll back the rig record so
|
|
804
|
+
// the spec name is left free for a clean retry. Pods rely on rigs
|
|
805
|
+
// via ON DELETE CASCADE so deleting the rig is sufficient.
|
|
572
806
|
if (opts?.prelaunchHook) {
|
|
573
807
|
const hookResult = await opts.prelaunchHook(rigId);
|
|
574
808
|
if (!hookResult.ok) {
|
|
809
|
+
this.deps.rigRepo.deleteRig(rigId);
|
|
575
810
|
return { ok: false, code: "service_boot_failed", message: hookResult.message };
|
|
576
811
|
}
|
|
577
812
|
}
|
|
@@ -654,6 +889,8 @@ export class PodRigInstantiator {
|
|
|
654
889
|
logicalId: qualifiedId,
|
|
655
890
|
status: launched.status,
|
|
656
891
|
error: launched.error,
|
|
892
|
+
evidence: launched.evidence,
|
|
893
|
+
sessionName: launched.sessionName,
|
|
657
894
|
});
|
|
658
895
|
}
|
|
659
896
|
// Create pod-local edges (after all members created)
|
|
@@ -680,9 +917,23 @@ export class PodRigInstantiator {
|
|
|
680
917
|
catch { /* best-effort */ }
|
|
681
918
|
}
|
|
682
919
|
}
|
|
683
|
-
//
|
|
684
|
-
|
|
685
|
-
|
|
920
|
+
// OPR.0.3.2.CT (conveyor-trust-minimal-fix):
|
|
921
|
+
// Distinguish recoverable attention_required (e.g., workspace trust
|
|
922
|
+
// gate) from terminal failure. ANY attention_required node means
|
|
923
|
+
// the rig is operator-recoverable — do NOT tear down. Only when
|
|
924
|
+
// every node is TERMINALLY failed (status === "failed") does the
|
|
925
|
+
// tear-down run, preserving the existing failure-cleanup behavior.
|
|
926
|
+
//
|
|
927
|
+
// For all-attention_required (no successful launch, no terminal
|
|
928
|
+
// failure), surface an attention_required outcome that carries
|
|
929
|
+
// the actionable per-node detail. The route returns a 3-part
|
|
930
|
+
// error pointing the operator at the approve→resume path. Sessions
|
|
931
|
+
// remain in startup_status='attention_required' so `rig ps` lists
|
|
932
|
+
// them and tmux panes are NOT killed.
|
|
933
|
+
const hasAttention = nodeResults.some((n) => n.status === "attention_required");
|
|
934
|
+
const hasLaunched = nodeResults.some((n) => n.status === "launched");
|
|
935
|
+
const allTerminal = nodeResults.length > 0 && nodeResults.every((n) => n.status === "failed");
|
|
936
|
+
if (allTerminal) {
|
|
686
937
|
// Kill orphan tmux sessions
|
|
687
938
|
if (this.deps.tmuxAdapter) {
|
|
688
939
|
for (const sessionName of launchedSessionNames) {
|
|
@@ -699,14 +950,55 @@ export class PodRigInstantiator {
|
|
|
699
950
|
const details = nodeResults.map((n) => `${n.logicalId}: ${n.error ?? "unknown"}`).join("; ");
|
|
700
951
|
return { ok: false, code: "instantiate_error", message: `all node launches/startups failed — ${details}` };
|
|
701
952
|
}
|
|
953
|
+
if (hasAttention && !hasLaunched) {
|
|
954
|
+
// All-attention_required path — rig + sessions PRESERVED; no
|
|
955
|
+
// tear-down. The operator's path: attach to a session via
|
|
956
|
+
// `tmux attach -t <session>` and answer the runtime prompt. NO
|
|
957
|
+
// new trust primitive
|
|
958
|
+
// introduced (HG-5); reuses the runtime's shipped in-pane
|
|
959
|
+
// trust-grant prompt.
|
|
960
|
+
const attentionNodes = nodeResults
|
|
961
|
+
.filter((n) => n.status === "attention_required")
|
|
962
|
+
.map((n) => ({
|
|
963
|
+
logicalId: n.logicalId,
|
|
964
|
+
sessionName: n.sessionName ?? "",
|
|
965
|
+
evidence: n.evidence,
|
|
966
|
+
reason: n.error ?? "node awaiting attention",
|
|
967
|
+
}));
|
|
968
|
+
// Emit rig.imported so callers see the rig exists; nodes are
|
|
969
|
+
// attention_required, not "launched", so `rig ps` shows the
|
|
970
|
+
// correct lifecycle state.
|
|
971
|
+
try {
|
|
972
|
+
this.deps.eventBus.emit({ type: "rig.imported", rigId, specName: rigSpec.name, specVersion: rigSpec.version });
|
|
973
|
+
}
|
|
974
|
+
catch { /* best-effort */ }
|
|
975
|
+
return {
|
|
976
|
+
ok: false,
|
|
977
|
+
code: "attention_required",
|
|
978
|
+
message: `${attentionNodes.length} node${attentionNodes.length === 1 ? "" : "s"} require attention before becoming interactive (rig parked, NOT failed; approve and resume to proceed).`,
|
|
979
|
+
rigId,
|
|
980
|
+
attentionNodes,
|
|
981
|
+
};
|
|
982
|
+
}
|
|
702
983
|
// Emit rig.imported
|
|
703
984
|
try {
|
|
704
985
|
this.deps.eventBus.emit({ type: "rig.imported", rigId, specName: rigSpec.name, specVersion: rigSpec.version });
|
|
705
986
|
}
|
|
706
987
|
catch { /* best-effort */ }
|
|
988
|
+
// Carry sessionName + evidence through to InstantiateResult.nodes
|
|
989
|
+
// so BootstrapOrchestrator can build AttentionNode[] in the mixed
|
|
990
|
+
// launched+attention_required path (guard verdict
|
|
991
|
+
// qitem-20260518082933 BLOCKER 1).
|
|
992
|
+
const resultNodes = nodeResults.map((n) => ({
|
|
993
|
+
logicalId: n.logicalId,
|
|
994
|
+
status: n.status,
|
|
995
|
+
error: n.error,
|
|
996
|
+
sessionName: n.sessionName,
|
|
997
|
+
evidence: n.evidence,
|
|
998
|
+
}));
|
|
707
999
|
return {
|
|
708
1000
|
ok: true,
|
|
709
|
-
result: { rigId, specName: rigSpec.name, specVersion: rigSpec.version, nodes:
|
|
1001
|
+
result: { rigId, specName: rigSpec.name, specVersion: rigSpec.version, nodes: resultNodes, warnings: podInstantiateWarnings.length > 0 ? podInstantiateWarnings : undefined },
|
|
710
1002
|
};
|
|
711
1003
|
}
|
|
712
1004
|
computePodLaunchOrder(rigSpec) {
|
|
@@ -826,6 +1118,50 @@ export class PodRigInstantiator {
|
|
|
826
1118
|
const member = pod?.members.find((entry) => entry.id === memberId);
|
|
827
1119
|
return pod && member ? { pod, member } : null;
|
|
828
1120
|
}
|
|
1121
|
+
/**
|
|
1122
|
+
* create-node primitive (OPR.0.3.3.24): mint a fresh node row for one member
|
|
1123
|
+
* (fresh stable id + fresh qualified logical id, `pod_id` = the given pod) plus
|
|
1124
|
+
* the matching `node.added` event. Extracted from materialize's loop so the
|
|
1125
|
+
* `add_member` converge op and a de-YAML'd `expand` create a member node
|
|
1126
|
+
* WITHOUT fabricating a synthetic rig spec. Identity-migration-FREE: addNode
|
|
1127
|
+
* mints a brand-new identity; nothing existing re-keys. The caller pushes the
|
|
1128
|
+
* returned `event` into its transaction's persisted-events list.
|
|
1129
|
+
*/
|
|
1130
|
+
createMemberNode(input) {
|
|
1131
|
+
const effectiveCwd = resolveLaunchCwd(input.member.cwd, input.rigRoot, input.cwdOverride);
|
|
1132
|
+
const node = this.deps.rigRepo.addNode(input.rigId, input.qualifiedId, {
|
|
1133
|
+
runtime: input.member.runtime,
|
|
1134
|
+
model: input.member.model,
|
|
1135
|
+
codexConfigProfile: input.member.codexConfigProfile,
|
|
1136
|
+
cwd: effectiveCwd,
|
|
1137
|
+
restorePolicy: input.member.restorePolicy,
|
|
1138
|
+
podId: input.podId,
|
|
1139
|
+
agentRef: input.member.agentRef,
|
|
1140
|
+
profile: input.member.profile,
|
|
1141
|
+
label: input.member.label,
|
|
1142
|
+
});
|
|
1143
|
+
const event = this.deps.eventBus.persistWithinTransaction({
|
|
1144
|
+
type: "node.added",
|
|
1145
|
+
rigId: input.rigId,
|
|
1146
|
+
nodeId: node.id,
|
|
1147
|
+
logicalId: input.qualifiedId,
|
|
1148
|
+
});
|
|
1149
|
+
return { node, event };
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* launch-binding primitive (OPR.0.3.3.24): given an already-created node and
|
|
1153
|
+
* its member context, bring it fully live — harness launch + startup
|
|
1154
|
+
* projection + delivery + readiness + `@rigged_*` metadata. Dispatches the
|
|
1155
|
+
* terminal vs agent launch path. Extracted as an independently-callable
|
|
1156
|
+
* primitive so launchMaterialized's loop, `expand`, and the `add_member`
|
|
1157
|
+
* converge op all launch a node WITHOUT fabricating a synthetic rig spec.
|
|
1158
|
+
* Behaviour is identical to the prior inline dispatch.
|
|
1159
|
+
*/
|
|
1160
|
+
async launchBinding(input) {
|
|
1161
|
+
return input.member.agentRef === "builtin:terminal"
|
|
1162
|
+
? this.launchExistingTerminalMember(input)
|
|
1163
|
+
: this.launchExistingAgentMember(input);
|
|
1164
|
+
}
|
|
829
1165
|
async launchExistingAgentMember(input) {
|
|
830
1166
|
const resolveResult = input.resolveResult ?? resolveAgentRef(input.member.agentRef, input.rigRoot, this.deps.fsOps);
|
|
831
1167
|
if (!resolveResult.ok) {
|
|
@@ -854,7 +1190,16 @@ export class PodRigInstantiator {
|
|
|
854
1190
|
return { status: "failed", error: sessionNameErrors.join("; ") };
|
|
855
1191
|
}
|
|
856
1192
|
const canonicalSessionName = deriveCanonicalSessionName(input.pod.id, input.member.id, input.rigSpec.name);
|
|
857
|
-
|
|
1193
|
+
// Slice 15 — forward per-seat silenceWindowSeconds from the resolved
|
|
1194
|
+
// profile.activity block. NodeLauncher applies the launcher default
|
|
1195
|
+
// (3s) when this is undefined. The seat's tmux monitor-silence is
|
|
1196
|
+
// configured immediately after createSession; SeatActivityService
|
|
1197
|
+
// then reads window_activity to compute terminalActive against this
|
|
1198
|
+
// threshold per poll.
|
|
1199
|
+
const launchResult = await this.deps.nodeLauncher.launchNode(input.rigId, input.qualifiedId, {
|
|
1200
|
+
sessionName: canonicalSessionName,
|
|
1201
|
+
silenceWindowSeconds: configResult.config.activity?.silenceWindowSeconds,
|
|
1202
|
+
});
|
|
858
1203
|
if (!launchResult.ok) {
|
|
859
1204
|
return { status: "failed", error: launchResult.message };
|
|
860
1205
|
}
|
|
@@ -920,7 +1265,8 @@ export class PodRigInstantiator {
|
|
|
920
1265
|
else if (input.member.sessionSource?.mode === "agent_image") {
|
|
921
1266
|
// PL-016 Item 4: agent_image → resolve via library + dispatch
|
|
922
1267
|
// through the native-fork code path so nativeResumeProbe
|
|
923
|
-
// semantics are preserved
|
|
1268
|
+
// semantics are preserved
|
|
1269
|
+
// (docs/as-built/architecture/adapters-and-runtimes.md § Resume honesty).
|
|
924
1270
|
const library = this.deps.agentImageLibrary;
|
|
925
1271
|
if (!library) {
|
|
926
1272
|
return {
|
|
@@ -1028,9 +1374,22 @@ export class PodRigInstantiator {
|
|
|
1028
1374
|
console.warn(`[openrig] agent-image fork_count bump failed for ${consumedAgentImageId}: ${err.message}`);
|
|
1029
1375
|
}
|
|
1030
1376
|
}
|
|
1377
|
+
// OPR.0.3.2.CT — preserve the attention_required distinction so
|
|
1378
|
+
// the instantiator can leave a recoverable rig + sessions instead
|
|
1379
|
+
// of zero-collapsing. The session row's startup_status was already
|
|
1380
|
+
// persisted by startupOrchestrator.fail() (see startup-orchestrator.ts
|
|
1381
|
+
// lines 223-225, 241-243).
|
|
1382
|
+
if (startupResult.ok) {
|
|
1383
|
+
return {
|
|
1384
|
+
status: "launched",
|
|
1385
|
+
sessionName: canonicalSessionName,
|
|
1386
|
+
warnings: launchResult.warnings,
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1031
1389
|
return {
|
|
1032
|
-
status: startupResult.
|
|
1033
|
-
error: startupResult.
|
|
1390
|
+
status: startupResult.startupStatus === "attention_required" ? "attention_required" : "failed",
|
|
1391
|
+
error: startupResult.errors.join("; "),
|
|
1392
|
+
evidence: startupResult.evidence,
|
|
1034
1393
|
sessionName: canonicalSessionName,
|
|
1035
1394
|
warnings: launchResult.warnings,
|
|
1036
1395
|
};
|