Never hard fault again

The HAL for AI Agents

Hard Fault is a local embedded-debug agent HAL built on pyOCD. Bring your own model — Codex, Claude, or an OpenAI / Anthropic API key — and it flashes images, reads UART, and drives SWD on your board, behind safety guardrails.

01 — install the v0.1.5 preview
$ curl -fsSL https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5/install.sh | sh -s -- --version 0.1.5 --base-url https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5 --sha256 a1c2507509a93738d966bbb446266d2d9ff1fd85f2e9b7df7a7eb67ad6063b92 --allow-unsigned
$ curl -fsSL https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5/install.sh | sh -s -- --version 0.1.5 --base-url https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5 --sha256 9896706ab6f94fd6254e55016428c8eff6dd71e579b5d91a52398ac7f56e678e --allow-unsigned
$ & ([scriptblock]::Create((irm https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5/install.ps1))) -Version 0.1.5 -BaseUrl https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5 -Sha256 ccbfb0d2f38570cb9417ad80f95e1429dc947ec2aea651a0c65a204ed707908e -AllowUnsigned
$ curl -fsSL https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5/install.sh | sh -s -- --version 0.1.5 --base-url https://github.com/JasonPeng2019/BYO-Installer/releases/download/0.1.5 --sha256 bb96c01d5ad896835cd5db5126c67d172b5cd55393dab3a678613acc750cde00 --allow-unsigned
02 — initialize this project
$ cd /path/to/your/firmware-project$ byo init$ byo codex firmware  # or: byo claude firmware

See the complete installation guide and uninstall guide.

// the difference

Without hardware, an agent guesses.
Hard Fault hands it the probe.

One firmware task, run twice — once against a bare model, once through Hard Fault’s MCP server.

Bare model · no MCP serverno hardware access
Bare model · no MCP server — no hardware access
Asked to debug a real board, even a strong model has to stop: it can’t reach the probe, no debug tooling is installed, and it’s flying blind on the firmware.
With Hard FaultPASS ✓
With Hard Fault — PASS ✓
Same prompt, connected MCP server: it validates the ST-Link, sets a breakpoint after init, mutates boot_count 1→42 through a plan-gated write, and confirms the telemetry changes.

Safe enough to hand a model a debug probe. Every mutating action passes a gate, and watchers stop a runaway before it can brick a board.

Guardrails →

// the loop

A closed loop, not a script.

Every run cycles Connect → Decide → Act → Verify until the board meets its green criteria — or a guardrail stops it.

01

Connect

Resolve the board from its YAML — target, probe, baud, recover policy — and open an SWD session with a tracked run id.

02

Decide

The model plans the next action from compact run memory: structured decisions in, one governed action out.

03

Act

Flash an image, run a build, write to UART, or step the core — every action routed through the brain gate.

04

Verify

Check UART boot text and green criteria, then persist evidence and events to the run log.

↻ the loop repeats until green criteria pass

// capabilities

A firmware engineer's bench, driven by a model.

Session

Open and inspect a debug session against the resolved board.

connectdisconnectget_board_infoget_state

Execution control

Drive the core exactly as you would by hand at the bench.

haltresumestepreset

Registers & memory

Read and write core registers and memory, including block reads.

read_core_registerwrite_core_registerread_memorywrite_memory

Firmware & UART

Flash validated images and capture serial output for verification.

flash_firmwareread_serial

Recovery

Board-policy-aware unlock for supported recover modes.

unlock_recover

Governed by MCP

Every operation is an MCP tool — wire the same governed actions into your own client or agent.

set_breakpointremove_breakpointread_memory_block

// guardrails

Safe to hand a model direct control.

A model can iterate on a fix, but it cannot silently loop on a destructive action or brick a board without an explicit, validated request.

Flash gate

Flashing validates its input before touching the board — a tracked baseline or a valid .elf/.hex succeeds; a missing path or bad suffix refuses.

$flash_firmware notes.txt→refused · invalid suffix

Recover gate

Recovery is board-policy aware: it needs explicit confirmation where a recover_mode exists, and refuses outright where none is tracked.

$unlock_recover (no recover_mode)→refused · unsupported

Mutation watchers

Scoped watchers stop a run thrashing on a broken op — and only that op. Disconnecting and reconnecting clears the block.

$flash_firmware ×3 failed→flash blocked