DOCSBooley user guide Tracks the main branch

Setup

This guide connects an installed Booley CLI to a specific RTL project. It assumes you have completed the README installation and that booley --version works. Project Setup also requires a Claude Code or Codex CLI on the host on PATH: Claude Code (claude) or Codex (codex), signed in with your chosen credentials. booley bootstrap checks for this host prerequisite.

The lifecycle has three parts: Host Bootstrap prepares reusable machine resources, Project Initialization makes this codebase a Booley Project, and the booley-setup skill performs design-aware Project Setup. Host Bootstrap deploys that skill, and this guide hands off to it (see The booley-setup skill below).

Two paths, sharing everything up to that handoff:

  • A new IP, from scratch. The easy path. Every flow is green by construction with the built-in Booley Flows, so you skip the feasibility triage entirely: booley init --scaffold writes a working, wired-together starter project, and the skill drives it to a green booley doctor (Booley's built-in health check, explained at Step 4).
  • An existing RTL project (a port). The harder path: a per-flow feasibility triage and hand-authored config (a .core is usually a mechanical restatement of the filelists you already have). Six open-source IPs have gone through this path, from a single-file RV32 CPU to a 415 K-LOC out-of-order core with a vendor toolchain; see Ports.

Both paths begin with a host-side bootstrap, then use their own skill mode. For what each configuration field means, see CONFIG.md for booley.toml and enabled, TARGETS.md for .core and tests.toml, FLOW-SIM.md for sentinels (the log-pattern strings that decide a simulation's pass/fail verdict), and SANDBOX.md for EDA provisioning.

This guide is written for a person setting up a project. A Claude Code or Codex session can follow it too: point it at this file. After the bootstrap it hands off to the booley-setup skill. It assumes you've skimmed the README; the context map locates the canonical definition of any Booley-specific term you hit here.

Ports

Booley has been driven end to end on picorv32, Ibex, biRISC-V, OpenC910 (415 K LOC, out-of-order RV64GC), verilog-pcie, and the taxi 10G Ethernet MAC: upstream RTL, upstream testbenches, no source restructuring, essentially zero testbench edits.

Their build systems have nothing in common (FuseSoC, bare Makefiles, a vendor test runner, cocotb under pytest), which is the useful part: the real requirement is just RTL that some EDA tool can already build. If your project clears that bar, the booley-setup skill can adapt it.

Host Bootstrap · host

Run Host Bootstrap after installation:

booley bootstrap

After upgrading Booley, run booley bootstrap --update instead.

It validates Git, Docker, and VS Code; installs or verifies VS Code's Dev Containers extension; deploys packaged skills; verifies the shared Nangate45 cache; reconciles the base Sandbox Image; and converges the single global egress network, proxy, and reaper. It neither discovers a Project nor selects an agent provider. booley bootstrap --check-only performs no writes and returns 1 when required work is pending; warnings from optional extensions remain non-blocking. --force refreshes Booley-managed host resources while preserving caches and user-owned files.

Bootstrap treats stable release tags in the official ghcr.io/boldaxolotl/booley-sandbox repository as temporary acquisition names. After the verified image is available under the canonical booley-sandbox name, Bootstrap removes every such version tag—including the tag for the current release—without forced deletion or parent pruning. The verified image remains available through its canonical local name. Retag an official image under your own repository name if you need to keep a separately named pinned copy.

Artifact selection follows the running Booley installation. A source checkout or development wheel builds every missing or stale Booley-managed Sandbox Image from its recipes. It never substitutes a registry image merely because the semantic version matches a release. An official release wheel pulls its matching published image; Booley validates the exact payload, recipe, and parent provenance before adopting the canonical local name. --check-only reports which action would occur without pulling or building.

Run Host Bootstrap before Project Initialization. booley init observes its prerequisites without mutating shared images. A current runtime base can support a Project-only wheel refresh even when the host wheel overlay is stale.

Reserve about 4 GB of Docker storage for the standard sandbox or 6 GB for the complete RISC-V demo stack, plus Project artifacts and temporary upgrade/build data. On the measured containerd store, the current Linux/AMD64 images occupy 1.58/2.02 GB and expose 2.82/4.48 GB filesystems; shared layers are not additive.

Local image builds need temporary Docker headroom. Before the first build, Booley checks the complete known sequence on Docker's reported storage filesystem. Required space is the largest retained-output-plus-current-peak point, plus one 5 GiB reserve: Host Bootstrap and maintenance need 40 GiB for the cold standard three-build sequence or 47 GiB for RISC-V; an overlay-only refresh needs 10 GiB. Project initialization excludes the runtime-base build and charges only uncached substrates and descendants, reusing compatible artifacts by immutable identity. Heavyweight builds use a 30 GiB cold peak, reduced to 10 GiB only when a managed image's expected role, recipe, input or contract labels and non-empty build cache prove reuse. Fixed wheel overlays and Booley sidecars use 5 GiB; arbitrary Project recipes remain heavyweight.

Before each build, Booley rechecks that build and the remaining tail without charging completed work. Pull downloads are outside the estimate, so local work is rechecked after a pull. Errors list each image estimate, one reserve, and total and reclaimable build cache. Booley never deletes cache, images, volumes, Project artifacts, or user data; pruning may evict reusable layers. To explicitly accept disk-exhaustion risk, or bypass a misreported Docker storage filesystem, set BOOLEY_SKIP_IMAGE_DISK_PREFLIGHT=1 for that one command; every other value keeps the check enabled.

Initialize the Project · host

Host Bootstrap owns the local runtime base. If it is absent or stale, run booley bootstrap --update before retrying local-source Project initialization.

Run Project Initialization on the host before the skill takes over. The host versus Sandbox split is described in ARCHITECTURE.md.

booley init is the host command; the workflow CLI is container-only. Bare booley prints help and a getting-started hint on the host; inside the Sandbox it opens the Project’s configured Developer Agent. Explicit booley chat, booley goal, booley dashboard, and bwave refuse to run on the host (Reopen in Container); booley init refuses inside the container, where there is no Docker. Either side fails fast with a message naming the fix.

For an existing project, start from a fresh clone when practical and run booley init before making local edits. A clean tracked tree gives the initialization an unambiguous baseline for line-ending repair and other Git checks, minimizing avoidable setup conflicts. If you must use an existing checkout, commit or stash tracked changes first.

The command depends on your path:

cd your-rtl-project            # porting an existing project
booley init

On a terminal, init asks which provider (claude or codex) and auth policy (subscription, api-key, or auto) this project uses. Press Enter to accept the claude and auto defaults. CI and other unattended bootstraps apply the same defaults; pass flags only when the project needs a different selection:

booley init --provider codex --auth subscription

The choice is recorded in .booley/booley.toml before credentials are checked or the devcontainer is generated. Re-running init preserves an existing [agent] selection; change that table directly when deliberately migrating a project. booley init --seed follows the same contract, so an older project without a provider records the default (or supplied flag) on its first reseed.

For CI, release validation, or another environment that must configure a project without access to a user's secrets, pass --skip-credentials. Init still records and validates the provider/auth selection, but does not inspect the environment or warn that credentials are absent:

booley init --provider codex --auth subscription --skip-credentials
mkdir my_ip && cd my_ip && git init      # a new IP, from scratch
booley init --scaffold my_ip

booley init is idempotent (safe to re-run): it never overwrites a .booley/docker/{Dockerfile,requirements.txt} you've hand-edited (it detects the loss of its # AUTO-GENERATED header, or a # booley:keep directive you add, and leaves your files and image untouched). Host Bootstrap owns external dependency validation, system skill links, the Nangate45 cache, the base Sandbox Image, and global sidecars. Project Initialization walks through:

  1. Creating .booley/ with placeholder configs
  2. Recording the selected agent provider and authentication policy
  3. The four create-only Goalsets and selected-provider credential checks
  4. Reconciling the Project-selected or Project-derived Sandbox Image while verifying its immutable base ancestry
  5. Installing Git hooks (repo-level plus the managed Project Git-policy bundle)
  6. Writing and issuing the Interactive Mode devcontainer specification
  7. Post-setup advisories

Machine-global integrations are owned by the one canonical host-installed Booley wheel. The first eligible wheel to run Host Bootstrap becomes canonical, including pipx, uv tool, or an ordinary persistent venv. A source checkout, worktree, QA runtime, or editable development install cannot deploy or retarget the global skills under ~/.agents or ~/.claude; temporary and ephemeral installed-wheel locations are also refused. A wheel in a persistent venv next to a checkout remains eligible: the guard checks the resolved package path, not the purpose of every environment or comprehensive wheel provenance.

The recorded executable, interpreter, distribution root, version, revision, and payload fingerprint must match for later host commands. An intentional upgrade or switch requires booley bootstrap --update from the intended installed launcher. The recorded identity is machine-maintained state in ~/.config/booley/host-installation.json; it is intentionally separate from the user-authored host policy in config.toml.

The commit-msg hook installed in step 5 has one behavior worth knowing about later; it doesn't affect the happy-path install, so it's spelled out under Notes at the end.

What --scaffold adds

On top of everything above, --scaffold writes a starter project. On a terminal it asks the choices below (synthesis mode only when ASIC is enabled); each answer is also a flag, for non-interactive runs that otherwise take the defaults:

Choice Options Flag
Simulator EDA tool Verilator / Icarus --sim-eda-tool
Testbench style SystemVerilog / cocotb --tb-style
Lint EDA tool Verilator / Verible --lint-eda-tool
Flows to enable ASIC synthesis, FPGA (and the part) --asic / --no-asic, --fpga-part
ASIC synthesis mode physical (default) / logical --synth-mode

Two combinations to know about: cocotb requires an image-provisioned simulator, and the currently supported choices are Verilator and Icarus. Commercial simulators are future work.

Physical synthesis uses Yosys and OpenROAD with a generated 10 ns SDC. Logical synthesis uses Yosys mapped-area evidence and emits/references no ASIC SDC; FPGA XDC remains independent. An explicit --synth-mode together with --no-asic is rejected before scaffold files are written. Omitting the mode with --no-asic is supported.

What lands, wired together and ready to run:

  • rtl/my_ip.sv: a small parameterized counter standing in for your design
  • tb/tb_my_ip.sv (or tb/test_my_ip.py for cocotb): a self-checking testbench with two tests, following the shipped TB style guides
  • my_ip.core: one Target per enabled flow (sim, lint, and optionally synth (plus SDC in physical mode), fpga + XDC)
  • .booley/booley.toml and tests.toml, populated rather than skeletons. The scaffolded config also turns stealth mode off, since this repo exists to exercise Booley and commit messages should stay verbatim (set [stealth] enabled = true to opt in)

The scaffold refuses to run in a repo that already contains .core or RTL files. That's a porting job, so use a plain booley init there. Once the scaffold is written, the booley-setup skill takes it from here — see greenfield mode.

When the bootstrap finishes, the booley-setup skill is deployed into your Claude Code or Codex installation by Host Bootstrap. Stay on the host: invoke it in your Claude Code or Codex chat at the Project Root.


The booley-setup skill

Setup proper is driven by the skill. You invoke it on the host first; it tells you when to Reopen in Container, and you re-invoke it in the Developer Agent's chat to finish.

Use the most capable model Claude Code or Codex offers. Setup is one of the heaviest reasoning tasks Booley asks of the setup session — feasibility triage, a decision grill, and a config-authoring + doctor fix-loop that spans the host/container boundary. Run the skill on the smartest model Claude Code or Codex offers (in Claude Code, select it with /model before invoking). A weaker model is more likely to skip a decision or mis-author config and cost you a round-trip.

/booley-setup           # port: phase-detects, plans if no approved plan yet, else executes
/booley-setup new       # a new IP: greenfield mode
/booley-setup <N>       # runs just step N (0-7), to re-run or resume one

Porting an existing project: plan, then execute

Steps 0–7 comprise the gated 0 → 4 sequence followed by post-gate Steps 5–7:

  • 0 · Plan · host. The feasibility triage (per-flow green/yellow/red across sim, lint, synth, fpga) plus a decision grill over everything the later steps need. It asks only a few questions and shows the rest as defaults you can accept in one go. Writes .booley/SETUP-PLAN.md and stops for your approval. The only approval gate.
  • 1 · Environment · host. Applies the plan's sandbox-image decision if it made one (booley init re-run), then hands you into Reopen in Container.
  • 2 · Project config. The .core Target(s), tests.toml, and booley.toml.
  • 3 · AGENTS.md. A concise Project-level guidance file for Developer Agents.
  • 4 · Doctor. booley doctor is Booley's built-in health check: it audits your config, .core Targets, toolchain, and sandbox and prints a PASS/FAIL line per check, each FAIL carrying a fix: hint. --deep goes further and runs live sim/lint/synthesis smoke tests against the real EDA tools. Fix every FAIL, then run --deep and fix those too. The gate.
  • 5 · Parity · optional. Cross-check Booley against the native build system when the approved plan selects one.
  • 6 · Findings. Report and triage findings from the setup run.
  • 7 · Cleanup. Remove the setup run's scratch root (minimal), or keep it (diagnostic).

Steps 2-4 run in-container without further approval gates, consuming the approved plan. A test that needs a non-RTL build step (per-case firmware, vector staging) is declared as [flows.sim].pre_run_commands during project config. Each step is also a standalone how-to file in the skill's steps/ directory if you'd rather write it by hand.

Once booley doctor (and --deep) is green, you're set up. Head to GOAL-MODE.md to enter your first Goal Mode with /booley-goal, or start an Interactive Mode session.

A new IP: greenfield mode

You already ran the scaffold on the host: booley init --scaffold my_ip (in the bootstrap above) asked the scaffold choices and wrote a working, green-by-construction project. So there's no feasibility triage and no config to author — the skill only has to finish the job.

Reopen in Container, then run /booley-setup new from the Project Root. It detects the scaffolded repo, reads the choices the scaffold recorded into the config, and confirms them in one message rather than re-asking. Because the scaffold already wrote the config (Step 2) and the project adopts the built-in Booley Flows, it skips config authoring and runs:

  • The doctor gate (Step 4). booley doctor, resolve every failure and warning, then booley doctor --deep, fix, and re-run until both exit 0 with zero active warnings; the skill does not declare the project ready before that. A deliberate project constraint can be recorded in a reviewed doctor-waivers.toml entry; warnings are never merely ignored. For a scaffolded project the sim, lint, and synthesis smoke checks should pass before you've written a line. Logical synthesis qualifies with completed mapped-area evidence; physical synthesis also requires constrained timing. That proves the wiring. By hand it's the same two commands in a container terminal: read every FAIL, WARN, and fix: hint, and don't stop at a green plain doctor. The deep smokes are the point.
  • AGENTS.md (Step 3), optional. The Project-level guidance file from the sequence above. A scaffolded project typically wants only this beyond the gate.
  • Setup report (Step 6). The report and final summary compare each Flow's delivered facts (from its numbered report.json) with the request and mark missing evidence unverified, per the skill's Delivered Flow results contract. Existing scaffold choices are confirmed as pre-set; a missing synthesis mode means physical. A changed request follows the approved Target-edit plan.

Then replace the counter in rtl/my_ip.sv with your design and grow the testbench, keeping the generated wiring as the pattern. Refresh .booley/selftest/sim/bad-overlay/<top>.sv under your selected Booley Directory to match the current interface, keeping it buildable and behaviorally failing the selected smoke Test. Re-run the doctor gate whenever the shape of the project changes (new Target, new flow, new constraints). From there, drive development the normal way: see GOAL-MODE.md to enter your first Goal Mode with /booley-goal, or start an Interactive Mode session.

Notes

Setup asks whether to keep Booley out of your git history. Yes keeps .booley/ hidden and enables stealth mode, including its commit-message scrub and hidden-core projection when Booley authors cores; No uses open config and native cores with stealth off. Unattended setup leaves stealth off unless hidden authored cores require it. Existing hand-set values are preserved. A missing enabled key retains the on-by-default runtime fallback for compatibility with existing projects. When enabled, stealth mode keeps project-identifying details out of commit messages so private IP names don't leak into git history. The project commit-msg hook installed by booley init rejects recognized attribution footers and sanitizes other protected terms; it does not force a type(scope): summary subject, so human and upstream-style commits on code you don't own land as-is. A team that wants that convention across its own history turns it on with [stealth] enforce_convention = true (see STEALTH.md). Once enabled, BOOLEY_SKIP_COMMIT_VALIDATION=1 lands one non-conforming commit anyway: it skips validation but not attribution rejection or sanitization (unlike git commit --no-verify, which disables the hook entirely and lets project details leak into history). Stealth mode itself is covered in STEALTH.md.

With Stealth enabled, init stores the RTL repository's line-ending default in Git's common info/attributes, shared by linked worktrees and local to this repository; it does not travel through commits. Init repairs a missing local default even when core.autocrlf is already false. Any upstream attributes policy suppresses this default so its higher precedence cannot override user rules. Versioned Booley Directories retain their root .gitattributes policy. The enabled choice is read from the resolved Booley Directory, including relocated data.

See also

Source: docs/user/SETUP.md on GitHub