missions: wire per-mission runtime container into launch + retry (C3 slice 2)
ci / gates (push) Successful in 6s
ci / rust (push) Failing after 10s
ci / frontend (push) Successful in 32s
ci / e2e (push) Skipped
ci / publish (push) Skipped

- mission_orchestrator::on_launch now calls ensure_container after
  the repo checkout, persists the container_name + endpoint on the
  missions row. Non-fatal — logs and continues on docker errors so
  dev-mode + tests keep working.
- phase_runner::launch_phase does the same as a fallback for any
  mission whose runtime_endpoint is null (pre-C3 or torn down).

Nothing reads the endpoint yet; slice 3 swaps topology_worker over.
This commit is contained in:
Omar Sobh
2026-07-21 22:30:22 -07:00
parent f648bcd26e
commit 7649b213ad
2 changed files with 75 additions and 0 deletions
+37
View File
@@ -65,6 +65,43 @@ pub async fn on_launch(
),
}
// Provision the per-mission ZeroClaw runtime container (C3).
// Idempotent: returns the endpoint if the container is already
// running. Falls back silently when docker is unreachable so
// dev-mode + tests still work — the topology_worker will use the
// shared runtime endpoint in that case.
if let Some(prov) = crate::mission_runtime::MissionRuntimeProvisioner::from_env() {
match prov.ensure_container(mission_id).await {
Ok(endpoint) => {
let container_name = crate::mission_runtime::container_name(mission_id);
if let Err(e) = cm_db::repo::missions::set_runtime_binding(
pool,
mission_id,
workspace_id.as_uuid(),
Some(&container_name),
Some(&endpoint),
)
.await
{
eprintln!(
"mission_orchestrator: bind runtime container for {mission_id} failed: {e}"
);
} else {
eprintln!(
"mission_orchestrator: runtime container {container_name}{endpoint} for mission {mission_id}"
);
}
}
Err(e) => eprintln!(
"mission_orchestrator: provision runtime container for {mission_id} failed (continuing with shared runtime): {e}"
),
}
} else {
eprintln!(
"mission_orchestrator: docker unreachable, mission {mission_id} will use shared runtime"
);
}
// Skip team materialization if already bound.
if mission.team_id.is_some() {
eprintln!(