fix(missions): the door read a field that is not set yet
`install_skills_door` took the container name from `mission.runtime_container_name`, and `on_launch` loads the mission at the top — before `ensure_container` runs and binds that field. So it was always `None`, and the early return had no log, so the door simply never installed and said nothing about it. Verified against a live mission: no log line, no file in the container. That is the same shape as the three hook bugs before it, which is a poor excuse for repeating it. The name is derived from the mission id (`container_name`) instead, guarded on `mission_gateway` being Some — which is exactly the signal that `ensure_container` ran and that this mission has its own container rather than the shared runtime. Every remaining early return now logs. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_018i9Ten1LU4jUr5d7TAWda9
This commit is contained in:
co-authored by
Claude Opus 5
parent
73f5d71c55
commit
3aeee070b8
@@ -346,7 +346,19 @@ pub async fn on_launch(
|
||||
settings ({e}) — this mission's tool calls run unchecked"
|
||||
);
|
||||
}
|
||||
install_skills_door(pool, user_id, &mission, p).await;
|
||||
// Only when this mission got its OWN container — the shared runtime is
|
||||
// not ours to reconfigure, and `mission_gateway` being Some is exactly
|
||||
// the signal that `ensure_container` ran.
|
||||
if mission_gateway.is_some() {
|
||||
install_skills_door(
|
||||
pool,
|
||||
user_id,
|
||||
mission_id,
|
||||
&crate::mission_runtime::container_name(mission_id),
|
||||
p,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
let mut first_team_id: Option<Uuid> = None;
|
||||
let mut provisioned_claws: Vec<cm_domain::AgentId> = Vec::new();
|
||||
@@ -907,17 +919,14 @@ fn default_accent_for(slot: &str) -> &'static str {
|
||||
async fn install_skills_door(
|
||||
pool: &PgPool,
|
||||
user_id: cm_domain::UserId,
|
||||
mission: &cm_db::repo::missions::Mission,
|
||||
mission_id: Uuid,
|
||||
container: &str,
|
||||
prov: &RuntimeProvisioner,
|
||||
) {
|
||||
let Some(container) = mission.runtime_container_name.as_deref() else {
|
||||
return;
|
||||
};
|
||||
let Some(origin) = crate::container_tool_hooks::api_origin() else {
|
||||
eprintln!(
|
||||
"mission_orchestrator: no API origin for the skills door (set \
|
||||
CLAWMATES_API_ORIGIN) — mission {} runs without it",
|
||||
mission.id
|
||||
CLAWMATES_API_ORIGIN) — mission {mission_id} runs without it"
|
||||
);
|
||||
return;
|
||||
};
|
||||
@@ -932,8 +941,7 @@ async fn install_skills_door(
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"mission_orchestrator: could not mint a skills token ({e}) — \
|
||||
mission {} runs without the door",
|
||||
mission.id
|
||||
mission {mission_id} runs without the door"
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -948,6 +956,7 @@ async fn install_skills_door(
|
||||
let doc = crate::container_tool_hooks::mcp_document(&origin, &token);
|
||||
let Some(path) = crate::container_tool_hooks::install_door(&docker, container, &doc).await
|
||||
else {
|
||||
// `install_door` already said why.
|
||||
return;
|
||||
};
|
||||
if let Err(e) = prov.set_claude_cli_mcp_config(&path).await {
|
||||
@@ -958,7 +967,7 @@ async fn install_skills_door(
|
||||
return;
|
||||
}
|
||||
eprintln!(
|
||||
"mission_orchestrator: skills door installed for mission {} ({origin}/mcp/skills)",
|
||||
mission.id
|
||||
"mission_orchestrator: skills door installed for mission {mission_id} \
|
||||
({origin}/mcp/skills)"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user