fix(runtime_provision): use team-template risk_profile, not hardcoded toolfree
ci / gates (push) Successful in 6s
ci / frontend (push) Successful in 38s
ci / rust (push) Successful in 3m48s
ci / e2e (push) Skipped
ci / publish (push) Successful in 4m4s

The provisioner was hardcoding risk_profile=toolfree for every claw,
which the ZeroClaw config explicitly configures to EXCLUDE every
usable tool (shell, file_read, file_write, http_request, browser).
Result: coder/tester/committer claws had zero tools and produced text
in the context window with no ability to actually write files or run
tests — exactly what the last mission summary showed.

Fixes:
- provision_claw now takes risk_profile: &str, passed through from
  the team template (development teams already had coding_readwrite,
  which now actually gets applied).
- Research team templates updated from toolfree → research_readonly
  (file_read) and papers_research → research_web_readonly
  (file_read + web_search + web_fetch). Applied to both the on-disk
  TOML files and the live DB rows.
- Added RuntimeProvisioner::default_risk_profile_for_role for
  auto-provision code paths that lack a template context — picks
  coding_readwrite for coder-like roles, research_readonly otherwise.
- Split rebind_model out of provision_claw so the model-change UI
  path doesnt inadvertently clobber the existing risk_profile.

Templates DB fixup for missions launched pre-deploy is already
applied via manual UPDATE.
This commit is contained in:
Omar Sobh
2026-07-23 19:44:27 -07:00
parent 9a23c851e0
commit 84572186e9
9 changed files with 68 additions and 13 deletions
+9 -1
View File
@@ -327,8 +327,16 @@ async fn mint_team_from_template(
.map_err(|e| format!("set_model_binding {claw_id}: {e}"))?;
// Runtime provisioning is opt-in — no-op if unconfigured.
// Pass the team template's risk_profile so the claw actually
// gets the tools its role expects (research_readonly for
// scout/researcher, coding_readwrite for coder/tester/committer,
// etc.). Passing "toolfree" — the old default — left every
// agent with zero tools regardless of what its prompt asked for.
if let Some(p) = provisioner {
if let Err(e) = p.provision_claw(claw_id, default_model).await {
if let Err(e) = p
.provision_claw(claw_id, default_model, &template.template.risk_profile)
.await
{
eprintln!(
"mission_orchestrator: provision claw {claw_id} failed (continuing): {e}"
);