GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing chatcli.edilsonfreitas.com — Coder Mode Security (Governance) - ChatCLI ChatCLI was designed to be a powerful tool, but power requires control. In Coder Mode ( /coder), the AI has the ability to read, write, create, and execute commands on your system. To ensure you are always in control, we implemented a governance system inspired by ClaudeCode.
How Does It Work?Every time the AI suggests an action (such as creating a file or running a script), ChatCLI checks your local security rules before executing.The 3 Permission StatesAllow (Permitted)The action is executed automatically, without interruption. Ideal for read commands ( read, tree, search) and read-only Git operations (git-status, git-diff, git-log, git-changed, git-branch).Deny (Blocked)The action is silently blocked (or with an error for the AI). Ideal for protecting sensitive files or destructive commands. Ask (Prompt)ChatCLI pauses and displays an interactive menu for you to decide. This is the default for unconfigured actions. policy_manager priority orderWhen the agent requests an action,policy_manager evaluates rules in the order below (first match wins):
@read, @search, @tree, @websearch, @webfetch (GET), @scheduler query/list, @coder read/search/tree, @recall (reads back output this session compressed) and @memory recall/timeline/map/neighbors/list — all pass without a prompt while write/exec stay gated (@memory link/unlink change memory and stay gated like remember).
Deny rules always beat the capability gate. You can block @websearch in a corporate environment via a @websearch → Deny rule even if the plugin advertises read-only.Typeahead protection (input guard)When the LLM is streaming and the security box appears, any character you typed before the prompt rendered is discarded automatically. Three layers:
also update the changelog) never answers the prompt, but it is no longer thrown away: the drain re-queues it and it reaches the model at the next turn boundary. From the drain, only lines shaped like a prompt answer (y, n, yes, no, sim, a, always, d, deny, or a bare Enter) stay discarded.
Interactive Approval MenuWhen an action falls into the “Ask” state, you will see a security box with contextual information about the action:Recognized Action Types
Prompt with Context in Parallel ModeWhen the action is requested by a multi-agent mode worker, the prompt includes additional information about which agent is making the request:This allows you to know exactly which agent is requesting the action and why, facilitating informed security decisions. Options1 y (Yes) Executes only this time. Next time, it will ask again. 2 a (Always) Creates a permanent ALLOW rule for this command (e.g., allows all writes with @coder write).3 n (No) Skips execution. The AI receives an error informing that the user denied. 4 d (Deny) Creates a permanent DENY rule. The action will be automatically blocked in the future. For exec commands, the “Always” and “Deny Forever” options are not available, as each execution is unique and requires individual approval.Rule ManagementRules are saved locally in~/.chatcli/coder_policy.json. You can edit this file manually if desired, but the interactive menu is the easiest way to configure.
The matching uses the effective @coder subcommand even when args is JSON (e.g., {"cmd":"read"} becomes @coder read).
Local Policy (Per Project)You can add a local policy in the project directory:
A local coder_policy.json loads only from a trusted workspace, and it can only tighten the global policy — it can never widen it. This changed in the security release; the older merge/replace behaviour is gone.
./coder_policy.json @coder write back to ask and denies a destructive rm -rf even if the global policy was more permissive. Any allow it contained would be dropped.
For evals, the per-case policy no longer comes from a coder_policy.json placed in the sandbox. It comes from CHATCLI_CODER_POLICY_OVERLAY, a path read only from the process environment; that overlay is a full merge and is never persisted.Policy Example (coder_policy.json)Word Boundary MatchingThe policy system uses word boundary matching, ensuring that rules do not partially match different subcommands:
This means @coder read will never allow @coder readlink or @coder readwrite accidentally.Command Validation (50+ Patterns)Beyond policy governance,@coder exec validates each command against 50+ regex patterns that detect:
Data destructionrm -rf, dd if=, mkfs, drop databaseRemote executioncurl | bash, base64 | shCode injectionpython -c, eval, $(curl ...)Process substitution<(cmd), >(cmd)Kernel manipulationinsmod, modprobe, rmmodEvasion${IFS;cmd}, VAR=x; bashCHATCLI_AGENT_DENYLIST:
For the complete list of ChatCLI security protections, see the Security and Hardening documentation. Exec Sandbox (OS-level confinement)The command validator and the permission policy gate what a command is allowed to run. The exec sandbox is a second, complementary layer that confines what a permitted command can touch — file writes and network — using the operating system’s own sandboxing. It is opt-in and default OFF, selected withCHATCLI_CODER_SANDBOX:
workspace and strict, writes are allowed to the workspace plus a generous allowlist of toolchain caches — Go module cache / GOCACHE, .npm, .cargo, .rustup, .gradle, .m2, ~/.chatcli, and the temp dir — so ordinary builds keep working while stray writes elsewhere are blocked.
Backends — confinement on any OSChatCLI picks the strongest available backend for the host, and the container backend makes confinement work on any operating system, Windows included:
CHATCLI_CODER_SANDBOX=docker, podman, or container) wins; otherwise the native backend is used; if none is present, the portable container backend takes over; only when no backend at all is installed does it degrade to unconfined — printing a one-line note, never failing the command.
The container image is configurable with CHATCLI_CODER_SANDBOX_IMAGE (default alpine:3).
The sandbox is opt-in on purpose: a silently confined build that can’t reach its module cache is worse than no sandbox at all. Turn it on deliberately.With the container backend, the command runs inside the image — so host toolchains ( go, node, …) are only available if the image ships them. Point CHATCLI_CODER_SANDBOX_IMAGE at an image that carries your toolchain, or use the native macOS/Linux backends when you need the host tools.Tool Call DeduplicationChatCLI includes a deduplication mechanism that ensures each tool call is verified and executed exactly once.The ProblemWhen the AI responds with XML-format tool calls (e.g.,<tool_call name="@coder" args='{"cmd":"read",...}' />), ChatCLI’s parser uses two extraction methods:
args attribute (e.g., {"cmd":"read",...}) could be incorrectly recognized by the JSON parser as a second tool call. Without deduplication, this would cause:
The SolutionParseToolCalls applies automatic deduplication: tool calls extracted by the JSON parser that already exist as part of an XML tool call are discarded. The comparison uses the tool name, arguments, and raw text to detect duplicates.
This mechanism is transparent — you don’t need to do anything. The security check appears exactly once per action. Best Practices1 Start with Caution Keep write commands ( write, patch, exec) as ask until you feel confident in the agent.2 Allow Reads Generally, it is safe to give “Always” for coder read, coder tree, coder search, and read-only Git (git-status, git-diff, git-log).3 Be Specific Matching uses word boundary for subcommand prefixes and path-prefix for arguments. You can allow coder exec --cmd 'ls but block coder exec --cmd 'rm.4 Safe Exec @coder exec blocks dangerous patterns by default (50+ rules). A --allow-unsafe or --allow-sudo flag coming from the model is ignored — only the human operator can lift these guards, via CHATCLI_CODER_ALLOW_UNSAFE=true and CHATCLI_AGENT_ALLOW_SUDO=true in the environment. Set them deliberately and only when necessary.Governance in Multi-Agent Mode (Parallel)Security policies are fully respected by multi-agent mode workers. When/coder or /agent operates in parallel mode, each worker checks the coder_policy.json rules before executing any action.
Behavior
Security prompts from multiple workers are serialized — only one prompt at a time is displayed, avoiding visual overlap. Rules created during the session (via “Always” or “Deny”) are immediately visible to all subsequent workers. Ask Rules on Unattended Surfaces (ACP, MCP, Gateway, headless one-shot)In the interactive terminal anask rule shows the security prompt. On unattended surfaces — where stdin carries a protocol or nobody is watching — the rule is resolved per surface.
When no human can answer, an ask now DENIES, fail-safe. This is the release default across the gateway, the server pipeline, ACP/MCP without a dialog, chatcli tool, and chatcli eval. To let an unattended surface auto-approve its ask verdicts, the operator opts in with CHATCLI_POLICY_AUTOMODE=true (process-wide) or /policy mode auto (per session). deny rules and the safety-immune list keep blocking regardless. See the security hardening upgrade guide.
exec commands never receive the always choices on any surface — the same restriction the interactive prompt applies, since any shell command could be destructive.deny rules block on every surface, and the dangerous-command validation applies everywhere regardless of policy. A client that doesn’t implement the permission round-trip (answers method not found) falls back to the auto-approve contract instead of having every gated action denied.
Session Policy Mode (
Sometimes you want a session to just flow — a long refactor you already trust, a scripted run — without approving every |
| Command | Effect |
|---|---|
/policy or /policy status | Show the current mode, rule count and policy file |
/policy mode auto | Automode: every policy ask verdict auto-approves for this session |
/policy mode interactive | Back to the default: ask prompts for approval |
ask instead of denying it fail-safe — set it process-wide with CHATCLI_POLICY_AUTOMODE=true, or per session with /policy mode auto. See Ask Rules on Unattended Surfaces.
What automode does not change:
deny rules still block — they resolve before ask in the policy check.rm -rf, sudo, force push, …) still prompt — automode widens convenience, never the blast radius the safety-immune tier protects against./policy status and /config security.
Available on all three surfaces: the terminal REPL, the ACP slash-command menu in the IDE, and MCP via the manage_session tool’s policy_mode action (name: auto | interactive | status).
/coder via environment variables:
| Variable | Values | Description |
|---|---|---|
CHATCLI_CODER_UI | full (default), minimal | Interface style |
CHATCLI_CODER_BANNER | true (default), false | Show/hide the cheat sheet |
/status and /config.