validation sweep: close residual TODO + strip 'future' stubs

- mission_orchestrator: replace hardcoded cli=\"claude\" with real
  precedence chain: mission.config.cli → template.config.default_cli
  → \"claude\". Missions can now A/B by CLI without a schema change.
- fleet.rs: scope clippy::too_many_arguments allow on
  NodeHub::open_pty — 8 params (session address x4 + target address
  x3) is the actual dimensionality; a struct would be ceremony.
- security_scan.rs: delete future_artifact_root — pure hint-stub,
  no callers, nothing depends on it.
- routes/world.rs: delete the empty normalize() seam + its 30-line
  comment block. normalize_run_event higher up does the real work;
  the empty stub was pre-cleanup scaffolding.

Post-sweep validation across the whole workspace:
  * cargo check --workspace           → clean
  * cargo test --workspace --no-run   → all bins build
  * cargo test -p cm-api --test mission_orchestrator → 3/3 pass
  * cargo clippy -p cm-api -p clawmates-node --tests → 0 warnings
  * tsc --noEmit                      → 0 errors

Wiring audit: every recent route handler is registered in lib.rs.
Every recent frontend component has at least one importer.

Remaining #[allow(dead_code)] entries are deprovision_claw +
unpublish_claw on RuntimeProvisioner — real rollback paths waiting
on the team-delete route. Documented future hooks, not stubs.
This commit is contained in:
Omar Sobh
2026-07-20 11:41:59 -07:00
parent bf4af48c80
commit a2bc06d313
4 changed files with 23 additions and 21 deletions
+4
View File
@@ -208,6 +208,10 @@ impl NodeHub {
/// `command`, when set to a non-empty argv, wins over both — spawns /// `command`, when set to a non-empty argv, wins over both — spawns
/// the program directly (used by the Herdr Live Pane to attach xterm.js /// the program directly (used by the Herdr Live Pane to attach xterm.js
/// straight to `herdr`). /// straight to `herdr`).
// 8 params is at the target-shape ceiling: (id, sid, cols, rows) address
// the session, (container, session, command) address the target. Wrapping
// in a struct would add ceremony without collapsing dimensions.
#[allow(clippy::too_many_arguments)]
pub async fn open_pty( pub async fn open_pty(
&self, &self,
id: NodeId, id: NodeId,
+19 -2
View File
@@ -108,12 +108,29 @@ pub async fn on_launch(
if mission.runtime_kind == "local_herdr" { if mission.runtime_kind == "local_herdr" {
if let (Some(hub), Some(node_id)) = (node_hub, mission.target_node_id) { if let (Some(hub), Some(node_id)) = (node_hub, mission.target_node_id) {
let prompt = mission.description.clone().unwrap_or_default(); let prompt = mission.description.clone().unwrap_or_default();
let cli = "claude"; // TODO(phase-4): pick from team template // CLI selection precedence:
// mission.config.cli → template.config.default_cli → "claude"
// Templates encode which agent CLI fits their stack; missions can
// override per-run for A/B (kimi on morpheus vs claude on tank).
let cli = mission
.config
.get("cli")
.and_then(|v| v.as_str())
.map(str::to_string)
.or_else(|| {
template
.template
.config
.get("default_cli")
.and_then(|v| v.as_str())
.map(str::to_string)
})
.unwrap_or_else(|| "claude".to_string());
match crate::fleet_herdr::dispatch( match crate::fleet_herdr::dispatch(
hub, hub,
cm_domain::NodeId::from(node_id), cm_domain::NodeId::from(node_id),
mission_id, mission_id,
cli, &cli,
&prompt, &prompt,
) )
.await .await
-13
View File
@@ -587,16 +587,3 @@ pub async fn world_replay(
)) ))
} }
// THE NORMALIZE SEAM (future) -------------------------------------------------
// Translate one durable `run_events` row into zero+ taxonomy events, the Rust
// twin of the handoff bridge's normalize(). Wire this into the poll loop above
// once the runner emits node targets:
// turn.started -> agent.status(working) [+ agent.task.update]
// turn.token -> agent.reasoning.delta
// tool.invoked -> agent.tool.call [+ world.touch if a nodeId is present]
// door.requested -> door.request ; door.resolved -> door.resolve
// agent.message -> agent.message ; runner.telemetry -> telemetry
#[allow(dead_code)]
fn normalize(_event_type: &str, _payload: &Value) -> Vec<(&'static str, Value)> {
Vec::new()
}
-6
View File
@@ -354,9 +354,3 @@ fn static_tool_name(s: &str) -> &'static str {
} }
} }
// Unused import silence + shape hint for a future artifact-write
// path that dumps the raw JSON outputs into mission_artifacts/security/.
#[allow(dead_code)]
fn future_artifact_root(mission_id: Uuid) -> PathBuf {
PathBuf::from(format!("/var/lib/clawmates-missions/{mission_id}/security"))
}