Hmbown/CodeWhale · error
read-only roles may revise their private working notes
Error message
read-only roles may revise their private working notes
What it means
This panic comes from `.expect("read-only roles may revise their private working notes")` on `registry.execute("agent_read_only", "todo_write", ...)` in crates/tui/src/tools/subagent/tests.rs:8528. It asserts the contract that read-only Fleet roles can still write to their own private todo list even though other write tools are denied. If the registry's read-only deny list incorrectly blocks `todo_write`, the tool returns an error and the expect panics.
Solutions
- Check the read-only role's tool catalog/deny list construction and ensure `todo_write` is explicitly permitted for read-only roles.
- Confirm the tool name string "todo_write" matches the registered tool identifier (grep the registry catalog).
- Verify the registry was built with the intended `ToolContext` and auto-approve settings so the write isn't rejected for approval reasons.
- Run the test with the registry construction logged (tool list) to see whether todo_write is present in the child's catalog.
Example fix
// before: blanket deny of all write-suffixed tools for read-only roles
let denied = tools.iter().filter(|t| t.name().ends_with("write"));
// after: exempt the private working notes surface
let denied = tools.iter()
.filter(|t| t.name().ends_with("write") && t.name() != "todo_write"); Defensive patterns
Strategy: validation
Validate before calling
// before relying on a role's catalog, assert the surface:
fn expects_tool(registry: &SubAgentToolRegistry, tool: &str) -> bool {
registry.catalog_names().any(|n| n == tool)
}
assert!(expects_tool(®istry, "todo_write"), "read-only roles must keep todo_write"); Type guard
fn is_private_notes_tool(tool: &str) -> bool {
matches!(tool, "todo_write" | "todo_read")
} Try / catch
match registry.execute("agent_read_only", "todo_write", payload).await {
Ok(out) => assert_eq!(out, expected),
Err(e) => panic!("todo_write denied for read-only role: {e:?} — check the deny-list exemption"),
} Prevention
- When tightening read-only deny lists, always exempt the private working-notes tools explicitly.
- Keep a contract test per role that enumerates its catalog and pins todo_write presence.
- Centralize the read-only exemption list so per-role edits cannot silently drop it.
- Grep for tool-name string literals when renaming tools to update all policy references.
When it happens
Trigger: Executing `todo_write` against an `agent_read_only` SubAgentToolRegistry whose deny-list/allow-list construction no longer exempts the private todo tool — e.g. after tightening role permissions, changing the tool name, or seeding a deny list that includes todo_write.
Common situations: Refactoring the permission allowlist for read-only roles, renaming the todo tool, or adding a new write-protection layer that sweeps in the private notes surface; also seen when tests forget to enable the agent tool surface options.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Refusing from agent ' ' to ' '; a child may control only…
- Refusing on self (agent_id ' '); child coordination…
- [role.posture.denied] Tool
- [shell.readonly.command] Tool
- Absolute path should not warn
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/83af6868276b79b2.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/tests.rs:8528
assert!(
registry.is_tool_allowed("image_ocr"),
"{role:?} must allow image_ocr"
);
assert!(
!registry.role_blocks_unhardened_process_tool("image_ocr"),
"{role:?} must not hide proven read-only tool image_ocr"
);
}
// Private working notes are writable; workspace writes are not.
registry
.execute(
"agent_read_only",
"todo_write",
json!({"todos": [{"content": "inspect issue evidence", "status": "in_progress"}]}),
)
.await
.expect("read-only roles may revise their private working notes");
assert_eq!(
todo_contents(&todo_list).await,
vec!["inspect issue evidence"],
"the bounded notes write lands only in this child's todo list"
);
assert!(
registry
.envelope_refusal(
"File",
&json!({"action": "write", "path": "src/lib.rs", "content": "nope"})
)
.is_some(),
"agent-owned notes must not widen workspace writes"
);
}
}
#[tokio::test]View on GitHub (pinned to 433685b202)