Repository navigation
Description
TL;DR
FastLED's ci/hooks/check_forbidden_commands.py blocks agents from invoking low-level build/debug tools directly (ninja, meson, clang++, gcc, pio, gdb, lldb) and points them at bash test / bash compile / bash debug. After FastLED #3336 / #3339 it also blocks raw powershell ... SerialPort patterns.
fbuild has tool_guard.py for soldr enforcement and worktree_guard.py, but no equivalent ban on agents reaching for pyocd, esptool, dfu-util, or direct subprocess.Command(["pyocd", ...]) calls. That's the exact pattern that burned two sessions on the LPC bring-up — agents typing pyocd flash ad-hoc instead of going through the deploy orchestrator that knows about the board's reset method, DTR/RTS conventions, and post-flash recovery.
This issue requests an fbuild-side check_forbidden_commands.py covering the deploy/debug surface.
What to ban
pyocd(CLI, any subcommand) — agents should go throughfbuild deploy/bash autoresearch.esptool/esptool.py— same; the wrapper knows about ROM-download-mode detection, retry policy, etc.dfu-util(when SAMD/STM32 deploy paths land) — same reasoning.picotool(RP2040) — same.probe-rsCLI — same.- Optional bonus: raw
cargoinvocation (already tracked bytool_guard.py's soldr enforcement, but worth merging the rules into a single hook for discoverability).
Error message shape (mirror FastLED's)
pyocd is forbidden — use `fbuild deploy <board>` or `bash autoresearch <board>` instead.
The deploy orchestrator handles:
- CMSIS-DAP / SWD reset method dispatch (see fbuild#687)
- Post-flash VCOM unwedge timing (see fbuild#565)
- Artifact size validation against board flash region (see fbuild#690)
- Per-board handoff timing (see fbuild#691)
None of those are run when pyocd is invoked directly. The result is a wedged
VCOM on Windows, silent flash failures past the flash region boundary, and
race conditions on monitor open. Override with FL_AGENT_ALLOW_ALL_CMDS=1 only
for legitimate debug-the-hook cases.
Acceptance criteria
-
ci/hooks/check_forbidden_commands.pyexists in fbuild's repo, mirrors FastLED's structure. - Bans
pyocd,esptool,dfu-util,picotool,probe-rsstandalone invocations. - Registered in
.claude/settings.jsonas aPreToolUsehook on the Bash tool. - Override env var:
FL_AGENT_ALLOW_ALL_CMDS=1(same name as FastLED's for muscle memory). - Smoke-tested: each banned tool produces the expected block message; benign mentions in commit bodies / docs are not flagged (lesson from FastLED's first revision tightening, see #3339 review).
Why this matters
The structural lesson from FastLED #3300 / #3325 / #3339 is that "the device looks silent" bugs are almost always agents reaching for a low-level tool that bypasses the project's accumulated knowledge about that board. The fix isn't policy through documentation — agents drift fast — it's policy through hooks.
Refs
- FastLED/FastLED#3336 — agent doc/hook rule for PowerShell SerialPort. The pattern this mirrors.
- FastLED/FastLED#3339 — merged, includes the hook addition that closed #3336.
- FastLED/fbuild#687 —
BoardFamily/ reset dispatch. The orchestrator this hook protects. - FastLED/fbuild#690 — artifact size validation. Skipped when pyocd invoked directly.
- FastLED/fbuild#691 — handoff timing. Skipped when pyocd invoked directly.
Filed from the audit fan-out on FastLED/FastLED#3339.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriage
Activity
dylint: code-quality gotcha sweep (#826) — 5 new lints + websocket ha…