Safety And Tools
The core tools are deterministic helpers exposed to Explorer and Coder through ProtoLink tool registration. Optional Scout uses ProtoLink's first-party network tools rather than a local duplicate.
Workspace Boundary
workspace_root(workspace) resolves the active project. safe_path(path, workspace) then:
- Expands user paths.
- Resolves relative paths against the workspace root.
- Resolves symlinks and absolute paths.
- Rejects any path outside the workspace.
Every read, search, diff, create, and write helper goes through this boundary.
Read-Only Tools
Explorer uses these:
| Tool | Limit or behavior |
|---|---|
read_file(path, with_line_numbers=True) | UTF-8 only, max 240000 bytes, optional line numbers. |
list_directory(path=".") | Skips ignored names and returns type/size metadata. |
search_regex(pattern, path=".", file_filter=".*") | Regex search, max 120 matches, skips binary/large files. |
get_git_status() | Runs git status --short with a short timeout. |
build_context_pack(query) | Source-cited Context Loom evidence for a focused task. |
Ignored directories:
.git .hg .svn .venv __pycache__ node_modules target dist build
Common binary suffixes are skipped by search and indexing.
Network-Read Tools
Scout is the only agent with network tools:
| Tool | Boundary |
|---|---|
web_search | Bounded normalized sources; Brave, keyless best-effort DuckDuckGo, or English Wikipedia. |
fetch_url | Public HTTP(S) URLs on standard ports only, with DNS and redirect checks plus text/size bounds. |
Both tools declare network.read, return untrusted content, and have no
workspace access. Scout is disabled by default, so the default deck neither
registers these tools nor performs web requests. Enabling Scout registers the
factories but still makes no request until Architect invokes a tool.
Write Tools
Coder uses these through approval-gated tools:
| Tool | Purpose |
|---|---|
generate_unified_diff(path, updated_content, original_content=None) | Preview a file replacement. |
create_new_file(path, content) | Preview a new file. |
write_file(path, content, overwrite=True) | Execute only after authorization. |
The tool exposed to the model is not a raw filesystem write. The Coder factory
wraps it in an action builder that first creates a RunAction with a diff
artifact. ProtoLink policy pauses before write_file() runs.
Approval Artifact
The preview artifact is:
| Field | Value |
|---|---|
kind | preview |
media_type | text/x-diff |
metadata.path | Project-relative target path |
parts[0].content | Unified diff |
Rust extracts this artifact in progress.rs and renders it in either a
one-shot terminal diff or fullscreen modal.
Deny By Default
Agent policies use deny-by-default behavior:
| Agent | Default effect | Important allows |
|---|---|---|
| Architect | deny | delegation and state/history operations |
| Explorer | deny | workspace reads only |
| Coder | deny | workspace writes with approval only |
| Scout | deny | network reads only, when enabled |
| Guide | deny | no tools, no state, no delegation |
This means adding a new tool requires both tool registration and policy review.
Maintenance Checklist
When adding a tool:
- Prefer the first-party ProtoLink tool when it provides the required
capability; put ProtoAgent-specific deterministic filesystem logic in
tools.py. - Register the tool only on the agent that needs it.
- Assign the narrowest capability string.
- Update that agent's
CapabilityPolicy. - Add or update tests for policy behavior.
- Update
agent_manifest()if users should see it. - Update this page and
Core / Agent Deck.