fix(missions): a bootable rootfs is not a runnable one
Found by looking at what the fleet actually reports, not by reasoning about it: tank's `capabilities.rootfs` is `["agent-terminal", "claude", "default"]`. Slice 5 offered that list to the planner as the menu of backends and validated proposals against it — so a roster naming `agent-terminal` would have been proposed, validated, approved and launched, and then failed at the agent turn, because `microvm_credential_for` has no contract for it and refuses rather than forward an Anthropic subscription token to an unknown endpoint. Refusing at boot is correct and is exactly the wrong PLACE: it is three steps and one human approval after the point where the answer was already knowable. The menu is now the intersection of "a node can boot it" and "a mission agent can authenticate in it", which is what the question meant all along. `backend_can_run_a_mission` derives from the credential contract rather than restating it, so a backend gaining one (GLM and Kimi, when B4.6's base-URL contract is settled) becomes proposable in the same commit that makes it runnable — instead of in a second list someone has to remember. 528 tests pass, clippy clean. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1797669296
commit
aa470091aa
@@ -203,6 +203,13 @@ pub async fn available_backends(
|
||||
.filter_map(|(v,)| v.as_array().cloned())
|
||||
.flatten()
|
||||
.filter_map(|v| v.as_str().map(str::to_string))
|
||||
// A node reports every rootfs it has BUILT, which is not the same as
|
||||
// every rootfs a mission can run in. `agent-terminal` is on tank right
|
||||
// now: bootable, and with no credential contract, so an agent inside it
|
||||
// has nothing to authenticate with. Offering it to the planner would
|
||||
// produce a roster that validates, approves, launches, and then fails at
|
||||
// the agent turn — the expensive kind of late.
|
||||
.filter(|b| crate::mission_runtime::backend_can_run_a_mission(b))
|
||||
.collect();
|
||||
out.sort();
|
||||
out.dedup();
|
||||
@@ -270,6 +277,23 @@ mod tests {
|
||||
assert!(r.validate(&["claude".to_string()]).is_ok());
|
||||
}
|
||||
|
||||
/// A bootable image is not necessarily a runnable one. tank reports
|
||||
/// `agent-terminal` in its rootfs list today: a real image, with no
|
||||
/// credential contract, so an agent booted into it has nothing to
|
||||
/// authenticate with. Offering it to the planner would produce a roster that
|
||||
/// validates, approves, launches and then fails at the agent turn.
|
||||
#[test]
|
||||
fn only_backends_that_can_authenticate_are_offered() {
|
||||
assert!(crate::mission_runtime::backend_can_run_a_mission("claude"));
|
||||
assert!(crate::mission_runtime::backend_can_run_a_mission("default"));
|
||||
for unrunnable in ["agent-terminal", "agent-browser", "rootfs-opus"] {
|
||||
assert!(
|
||||
!crate::mission_runtime::backend_can_run_a_mission(unrunnable),
|
||||
"{unrunnable} has no credential contract and must not be proposable"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The ceiling. Each member is a VM boot, an inject, a full agent session
|
||||
/// and a collect — a model asked to size a team proposes twelve happily.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user