fx agents)fx agents is a Fuchsia developer tool that manages tool configurations, permissions, and local state for AI coding assistants (such as Gemini CLI, Claude, and IDE plugins) operating within the Fuchsia source tree.
Its primary command is fx agents setup, which handles:
~/.local/share/Fuchsia/agents/setup/state.json (respecting $XDG_STATE_HOME / $XDG_DATA_HOME) so custom rules you manually add aren't lost when switching profiles.--status), roll back previous changes (--rollback [N]), or reset to a clean baseline (--reset).// and //vendor/*..git/hooks/<hook_name>.d/ hooks across all checkout repositories (//, //vendor/*) to format staged code and check commit message formatting.Run fx agents setup to configure the default local-changes profile:
fx agents setup
fx agents setup --profile read-only
Preview calculated grant modifications, Git hook actions, and daemon restarts without touching config.json or installing hooks:
fx agents setup --profile full-access --dry-run
fx agents setup provides four tiered permission profiles:
| Profile | Purpose | Allowed (allow) | Denied (deny) | Prompt on Exec (ask) |
|---|---|---|---|---|
read-only | Safe workspace inspection and build/test verification. | read_only.txt | never_allow.txt | external_changes.txt, device_ops.txt, cache_destruction.txt, batch_execution.txt |
local-changes (Default) | Workspace editing, formatting, local commits, emulators, and device management. | read_only.txt, local_changes.txt, device_ops.txt | never_allow.txt | batch_execution.txt, external_changes.txt, cache_destruction.txt |
external-changes | Local changes plus upstream code reviews, pushes, and remote infra. | read_only.txt, local_changes.txt, external_changes.txt, device_ops.txt | never_allow.txt | batch_execution.txt, cache_destruction.txt |
full-access | Unrestricted developer operations across all local, external, device, and cache tools. | read_only.txt, local_changes.txt, external_changes.txt, device_ops.txt, cache_destruction.txt, batch_execution.txt | never_allow.txt | (none) |
Rules are stored in plain text files under .agents/config/permissions/:
read_only.txt: Safe inspection (git status, git diff, fx build, fx test, cat, grep, rg, fd).local_changes.txt: In-tree editing and local VCS (git add, git commit, git checkout, git branch, git stash, git rebase, fx format-code).external_changes.txt: Upstream publishing and review (git push, jiri upload, fx gh pr ...).device_ops.txt: Target device controls (ffx target ..., fx ota, fx reboot).cache_destruction.txt: Build directory cleans and cache wipes (fx clean, fx clean-build).batch_execution.txt: Batch traversal and pipeline tools (find, xargs).never_allow.txt: Prohibited dangerous commands (git reset --hard, git clean -fdx, rm -rf /).never_allow.txt Enforcement: Dangerous commands (like rm -rf / or git reset --hard) are denied across every profile.--force, -f, +<ref>) anywhere in git push arguments, preventing accidental remote history overwrites.config.json outside of fx agents are preserved when switching profiles..config.json.tmp and renamed into place atomically to prevent corrupted files if interrupted.~/.local/share/Fuchsia/agents/setup/backups/ before modifying existing configuration.pre-commit hook isolates staged changes before formatting so unstaged edits are never modified or accidentally committed.fx agents setup automatically manages Git hooks across all checkout repositories discovered in the Fuchsia source tree (including // and //vendor/*).
Hooks are installed into .git/hooks/<hook_name>.d/10-fuchsia-agent.sh, integrating cleanly with the Jiri universal hook dispatcher without overwriting custom developer or team hooks.
pre-commit (Safe Formatting & Staging Isolation):fx format-code and re-staged (git add).fx format-code entirely if no formattable files are staged.commit-msg (Commit Message Standards):Bug:, Test:, Change-Id:) via scripts/shac/commit_msg_checker.py.The hooks check whether a commit is run by a human or an AI agent (via environment variables):
| Commit Invocation | Commit Message Style | Formatting Behavior |
|---|---|---|
| Human Developer (Interactive) | Advisory Warnings: Non-blocking warnings for style/length; commits succeed. | Fully staged files auto-formatted and re-staged. |
AI Coding Agent (GEMINI_CLI, etc.) | Strict Rejection: Non-compliant commit messages fail (--strict). | Auto-formatting strictly enforced. |
# Configure permissions without installing Git hooks: fx agents setup --no-git-hooks # Reset permissions while leaving Git hooks installed: fx agents setup --reset --no-git-hooks
# Standard Git flag (skips pre-commit and commit-msg natively): git commit -n # or git commit --no-verify
FUCHSIA_SKIP_HOOKS=1 git commit ...
--status)Inspect active configuration, rule counts, Git hook status, and history:
fx agents setup --status
Example output:
=== AI Coding Agent Configuration Status === Active Profile : local-changes Last Updated : 2026-08-26 21:00:00 Fuchsia Root : /usr/local/google/home/username/fuchsia Config File : /home/username/.gemini/config/config.json [exists] State File : /home/username/.local/share/Fuchsia/agents/setup/state.json [exists] Rule Breakdown: [ALLOW] : 58 total ( 55 managed, 3 custom) [DENY ] : 8 total ( 8 managed, 0 custom) [ASK ] : 12 total ( 12 managed, 0 custom) Recent History (2 transactions): 1. [2026-08-26 21:00:00] Profile: local-changes | Backup: config.20260826_210000.bak 2. [2026-08-26 20:30:00] Profile: read-only | Backup: config.20260826_203000.bak Git hooks: Configured across 12/12 repositories.
--rollback [N])Revert config.json to the state prior to N setup operations:
# Roll back to previous configuration (N=1) fx agents setup --rollback # Roll back 3 setups prior fx agents setup --rollback 3
--reset)Remove all permissions configured by fx agents setup, reverting to a clean baseline while preserving any custom developer-authored rules in config.json:
fx agents setup --reset
Note: Unlike
--rollback(which steps backward through previous profile changes using backup snapshots),--resetremoves all Fuchsia-managed grants and clears the local state file (state.json) without modifying custom permissions or non-permission IDE settings you manually configured. To reset permissions while preserving Git hooks, pass--no-git-hooks(fx agents setup --reset --no-git-hooks).
You can customize any profile by passing ad-hoc commands (--allow, --deny, --ask) or custom list files (--allow-list, --deny-list, --ask-list):
fx agents setup \ --profile local-changes \ --allow "fx test //custom:target" \ --deny "git push upstream main" \ --deny-list ~/my_denylist.txt \ --allow-list path/to/extra_allowed.txt
When an AI coding assistant attempts to execute a command, rules are evaluated in strict priority order:
Incoming Agent Command │ ▼ ┌─────────────────────┐ │ Matches DENY rule? │ ───► YES ───► [BLOCKED] └──────────┬──────────┘ │ NO ▼ ┌─────────────────────┐ │ Matches ASK rule? │ ───► YES ───► [PROMPT USER] └──────────┬──────────┘ │ NO ▼ ┌─────────────────────┐ │ Matches ALLOW rule? │ ───► YES ───► [AUTO-RUN] └──────────┬──────────┘ │ NO ▼ [DEFAULT PROMPT]
DENY Always Wins: If a command matches both an allow and a deny rule, the command is blocked immediately.--deny or --deny-list for a command that is already in the selected profile's allow list (e.g. denying git commit under local-changes), both rules will appear in config.json. Because DENY has highest priority, the command is safely blocked at runtime.setup run. Running fx agents setup later without those flags reverts to the profile defaults. Keep your custom list files (e.g. my_denylist.txt) so you can pass them when re-running setup.In multi-repo setups (e.g. // with //vendor/*), fx agents automatically discovers and merges configuration:
.agents/config/permissions/ (Public Fuchsia tree)vendor/*/.agents/config/permissions/ (Internal & vendor overlays)services.txt daemon declarations across all repository roots.For in-depth documentation on the architecture and implementation of fx agents:
StashGuard ($S^2 \to S$) algorithm, modular .d/ hook dispatchers, and troubleshooting.tools/agents, including directory structure, building, testing, and adding new subcommands.