Skip to content

fix(agents): unify permission safe-list + surface real failure cause (v0.1.14)#12

Merged
ste-bah merged 1 commit into
mainfrom
fix/permission-gate-and-real-error-v0.1.14
Apr 27, 2026
Merged

fix(agents): unify permission safe-list + surface real failure cause (v0.1.14)#12
ste-bah merged 1 commit into
mainfrom
fix/permission-gate-and-real-error-v0.1.14

Conversation

@ste-bah

@ste-bah ste-bah commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

Two bugs fixed together. Both have been blocking agent dispatch in the TUI since v0.1.10 — every prior fix addressed real issues but did not actually make the Agent tool work.

Bug #1 — duplicate permission gate, never synced

v0.1.10 added `Agent` to `archon_permissions::DEFAULT_SAFE_TOOLS` (`crates/archon-permissions/src/checker.rs:19`). But the agent loop has its OWN inline match arm at `crates/archon-core/src/agent.rs:881-883` that hardcoded a separate safe-list never including Agent. Two systems, one updated, the other not. Every Agent dispatch in default mode prompted for permission despite the "Agent in safe list" claim being technically true at the permissions layer.

Fixed: removed the duplicate. Added `pub fn is_default_safe_tool()`, `default_safe_tools()`, `is_accept_edits_safe_tool()`, `accept_edits_whitelist()` to archon-permissions; both inline match arms in agent.rs (default/ask AND auto) now query the helper. Re-exported at crate root for shorter call sites.

Lockstep regression test at `crates/archon-core/tests/permission_gate_consistency.rs` asserts every entry in `DEFAULT_SAFE_TOOLS` is auto-allowed by agent.rs's gate. Prevents this exact class of drift recurring.

Bug #2 — Agent tool failures returned vague errors, LLM misinterpreted as rate limits

Symptom: Steven typed "use the coder agent to create a file..." and saw `[tool] Agent failed` followed by "Rate limited. Retrying in 30s." That latter wasn't a real rate limit — it was the parent LLM's interpretation of whatever error string the failed subagent returned through `tool_result.content`. The TUI's failure renderer only printed the tool name, dropping the error message. The LLM saw the raw error string but the user never did, so we couldn't diagnose.

Fixed:

  • TUI surfacing: `archon-tui/src/app.rs:260` now includes 200-char truncated error message in the failure line.
  • Forensic logging: `tracing::error!` at every failure arm in `agent_tool.rs` with subagent_id, subagent_type, full err chain → `~/.archon/logs/`.
  • Conservative classification: `tool_result.content` prefixed with explicit category — `[subagent_rate_limited]` / `[subagent_auth_failed]` / `[subagent_panic]` / `[subagent_timeout]` / `[subagent_failure]`. Per ChatGPT review, the heuristic is conservative — only matches HTTP status codes with word boundaries, exact phrases (`"panicked at"`, `"authentication failed"`, `"timed out"`); ambiguous strings default to neutral `[subagent_failure]`. Original error preserved verbatim — prefix is additive, not replacing.
  • 12 classifier tests cover positive + adversarial cases (e.g., `"author"` must NOT classify as auth-failed, `"context limit"` must NOT classify as rate-limited).

Test plan

  • cargo check --workspace --tests -j1: exit 0
  • cargo test --workspace -j1 -- --test-threads=2: ALL PASS (incl. 2 new lockstep + 12 classifier)
  • cargo fmt --check: exit 0
  • cargo build --release --bin archon -j1: PASS
  • Real binary smoke (Steven): `target/release/archon`, type `use the coder agent to create a file called testing.txt with the words "hello world" inside it`. Verify:

…(v0.1.14)

Two bugs fixed together. Both have been blocking agent dispatch in the
TUI since v0.1.10.

Bug #1 — duplicate permission gate, never synced:

v0.1.10 added "Agent" to archon_permissions::DEFAULT_SAFE_TOOLS at
crates/archon-permissions/src/checker.rs:19. But the agent loop has its
own inline match arm at crates/archon-core/src/agent.rs:881-883 that
hardcoded a separate safe-list never including Agent. Two systems, one
updated, the other not. Every Agent dispatch in default mode prompted
for permission despite the "Agent in safe list" claim.

Fixed: removed the duplicate. Added pub fn is_default_safe_tool(name),
default_safe_tools(), is_accept_edits_safe_tool(), accept_edits_whitelist()
to archon-permissions; both inline match arms in agent.rs (default/ask
and auto) now query that helper. Single source of truth via
archon_permissions::is_default_safe_tool. Also re-exported at crate
root for shorter call sites.

Lockstep regression test added at
crates/archon-core/tests/permission_gate_consistency.rs — asserts every
entry in DEFAULT_SAFE_TOOLS is auto-allowed by agent.rs's gate. Prevents
this exact class of drift recurring.

Bug #2 — Agent tool failures returned vague errors, LLM misinterpreted
as rate limits:

Symptom: Steven typed "use the coder agent to create a file..." and
saw [tool] Agent failed followed by "Rate limited. Retrying in 30s."
The latter wasn't a real rate limit — it was the parent LLM's
interpretation of whatever error string the failed subagent returned
through tool_result.content.

Root cause: the TUI's failure renderer at archon-tui/src/app.rs:260
only printed the tool name, dropping the error message. The LLM saw
the raw error string but the user never did, so we couldn't diagnose.
Worse, when the error string contained generic words like "rate" or
"limit" (e.g. "context limit"), the LLM concluded "rate limited" and
retried.

Fixed:
- archon-tui/src/app.rs: failure line now includes a 200-char truncated
  error message — user sees the actual cause for the first time.
- crates/archon-tools/src/agent_tool.rs: tracing::error! at every
  failure arm with subagent_id, subagent_type, full err. Logs to
  ~/.archon/logs/ for forensic pasting.
- crates/archon-tools/src/agent_tool.rs: tool_result.content now
  prefixed with an explicit category — [subagent_rate_limited],
  [subagent_auth_failed], [subagent_panic], [subagent_timeout], or
  [subagent_failure] — so the LLM cannot guess the wrong cause.
  Classification is conservative (HTTP status codes with word
  boundaries, exact phrases like "panicked at" / "authentication
  failed" / "timed out" only); ambiguous strings default to neutral
  [subagent_failure]. Original error preserved verbatim — prefix is
  additive, not replacing. 12 classifier tests cover positive +
  adversarial cases (e.g., "author" must NOT classify as auth-failed,
  "context limit" must NOT classify as rate-limited).

Verified end-to-end:
- cargo check --workspace --tests -j1: exit 0
- cargo test --workspace -j1 -- --test-threads=2: ALL PASS, includes
  2 new lockstep tests + 12 classifier tests
- cargo fmt --check: exit 0
- cargo build --release --bin archon -j1: PASS

Pending: real-binary TUI smoke test (Steven runs interactively).

Version: 0.1.13 -> 0.1.14.
@ste-bah
ste-bah merged commit ddcd47b into main Apr 27, 2026
1 of 22 checks passed
@ste-bah
ste-bah deleted the fix/permission-gate-and-real-error-v0.1.14 branch May 8, 2026 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant