@brad-frost-web/bfw-process
v0.24.0
Published
The Brad Frost Web Software Creation Process, encoded as portable agent-ready infrastructure. Drop into any BFW project and any AI coding agent will load BFW's rules, phase gates, and Eddie-first discipline automatically.
Readme
@brad-frost-web/bfw-process
The Brad Frost Web Software Creation Process — encoded, portable, and agent-ready.
bfw-process drops BFW's software creation rules, phase gates, and Eddie-first discipline into any project in one command. Any AI coding agent — Claude Code, OpenHands, Cursor, Cline, or anything that reads AGENTS.md — automatically loads BFW's rules on the first turn of every session.
Stop re-explaining the process. Install it instead.
What you get
Running bfw-process init in a project adds:
AGENTS.md— the universal, cross-agent source of truth (core principles, always-on rules, phase structure)CLAUDE.md— a Claude Code-compatible mirror ofAGENTS.md.microagents/— always-on + keyword-triggered microagents (repo.md,eddie.md,eleventy.md,nuxt.md,accessibility.md,testing.md)SPEC.md— a starter spec file (Phase 2 template,status: draft).bfw-process/— phase definitions, checklists, theverify-phasescript, and your project's config (mode, owners, project type)
Everything is markdown. Everything is readable. No runtime, no daemon, no magic.
Two modes
BFW projects happen in two very different contexts, and bfw-process treats both as first-class.
Full mode (default)
The six-phase gauntlet from the BFW Software Creation Process. Spec before build, phase gates enforced, tests written alongside code, ship-readiness checked before deploy.
npx @brad-frost-web/bfw-process initQuick mode
For teaching, podcasting, live-coding, and prototyping — when speed and immediacy matter more than rigor. Phase gates are skipped. SPEC.md is optional. Ship-readiness checks are off. Eddie-first, design-tokens-only, and WCAG AA semantic baseline remain on even in quick mode, because they're muscle memory and cheap.
npx @brad-frost-web/bfw-process init --mode=quickPromoting Quick to Full
After a teaching call or a demo, if the quick-mode code is actually worth shipping:
bfw-process mode full…or simply tell the agent "do it for real now" in a session. The agent will generate a SPEC.md from the existing code, stop at the Phase 2 gate, and walk the project back through the Full-mode flow as refinement rather than a rewrite.
The hard gate
Phase 5 → Phase 6 (ship-readiness → deploy) is the one hard gate. Everything else is soft — checklists the agent reads. Ship-readiness runs real checks and exits non-zero on failure:
- Unit tests pass
- Automated a11y audit clean (axe or equivalent)
- Responsive spot-check
- Each spec user flow verified
- Lighthouse regression check
Projects scaffolded with bfw-process init expose the gate as an npm script:
npm run bfw:shipThat's the canonical invocation — it uses the pinned version in devDependencies, so CI and collaborators hit the same checks. If you need to run the gate directly, use npx --no bfw-process verify-phase ship; without --no, npx re-resolves from the registry each time and you may be gating against a different version than the one you pinned (AGENTS.md §2.8a).
Owner bypass
BFW core members (currently Brad Frost and Ian Frost by default) can bypass the ship gate in emergencies:
BFW_OWNER_OVERRIDE=1 npm run bfw:shipThe bypass requires the current git user.email to match an entry in .bfw-process/config.json's owners array. Non-owners get no bypass path. Every bypass is logged to .bfw-process/overrides.log with timestamp, user, and which checks were skipped.
Add additional owners per-project by editing config.json.
Installing into a project
npm (preferred)
# In an existing project
npm install --save-dev @brad-frost-web/bfw-process
npx bfw-process initinit pins @brad-frost-web/bfw-process in the project's devDependencies at the currently-installed version (exact, no caret) and adds an npm run bfw:ship script that runs the Phase 5 hard gate. Pinning is what makes the process reproducible: CI and every collaborator resolve to the same version, and a project audited today can replay its audit later against the same rules.
You can also one-shot without a prior install:
npx @brad-frost-web/bfw-process init…but still run npm install afterward so the pin in package.json is materialized in node_modules.
Git submodule (for non-Node projects)
git submodule add https://github.com/Brad-Frost-Web/bfw-process.git .bfw-process-src
./.bfw-process-src/scripts/bootstrap.shThe submodule path doesn't touch package.json (non-Node projects typically don't have one). If your project does have a package.json, prefer the npm path so the process version is pinned alongside your other dependencies.
CLI reference
bfw-process init [--mode=full|quick] [--type=content-site|app|recipe|script] [--yes] [--force]
without --yes, prompts interactively for name/type/mode/owners
(+ GitHub labels if a remote is detected) when stdin is a TTY;
non-TTY (CI) falls back to silent defaults
bfw-process rules [--json] print the governing rules: mode, lane, gate status, spec
status, and which guardrails actually fail a command.
The Phase 1 orientation bundle, fetchable on any harness
bfw-process sync update generated files, preserve SPEC.md + config.json
bfw-process mode [full|quick] show or set current mode
bfw-process verify-phase <phase> run checklist; phase = scope|spec|build|ship
(refused on design/* branches — use design promote first)
bfw-process design promote record SPEC.md, archive current design branch, adopt or
file the parent feature issue
[--dry-run] [--yes] [--force] [--no-push] [--parent=<N>]Design branches
BFW projects support a sketch-first branch type for exploratory work — the first half of the double diamond. See AGENTS.md §5.3 for the full contract. The short version:
# Open an exploration issue (use the "Design exploration" template), then:
gh issue develop <N> --checkout --name design/<N>-<slug>
# Sketch freely. Eddie is the default; the agent will ask one confirming question
# when invited to "color outside the lines". a11y baseline stays on always.
# SPEC.md is NOT required while sketching. `npm run bfw:ship` will refuse on a design/* branch.
# When the exploration is ready to become production work:
bfw-process design promotedesign promote validates the branch, generates or amends SPEC.md (status: draft) and commits it on the design branch, creates an archive/design-<N>-<slug> tag at that commit so the archive carries the record, pushes the tag to origin, and links the production work to a parent feature issue — adopting an existing one (--parent=<N>, a Parent: #<N> line in the design-exploration issue, or one a previous promotion filed) and filing a new one only when there is none. The design branch is never merged, so that SPEC.md commit does not reach the integration branch on its own — the recap prints the amendment block to carry across. Fresh feature/* branches off the integration branch (main on trunk repos, develop on gitflow repos — AGENTS.md §9.5) carry the production work.
Updating a consuming project
When BFW publishes a new version of the process:
npm install --save-dev @brad-frost-web/bfw-process@latest
npx --no bfw-process sync--no keeps sync on the version you just pinned: it runs the local copy or fails, never fetching a different one from the registry (AGENTS.md §2.8a).
sync refreshes every generated file — AGENTS.md, microagents, phase docs, checklists, templates, .github/ISSUE_TEMPLATE/, .github/PULL_REQUEST_TEMPLATE.md, the Eddie validation hook (UI projects), the beacon receiver workflow (npm projects) — and bumps the pinned version in package.json to match the running bfw-process version. Your SPEC.md and CLAUDE.md are left untouched, and so is every hand-owned key in config.json — the markers sync owns are written on every run (version, lastSyncedVersion, an empty eddieRoot it backfills on UI projects, and syncOnUpgrade when you opt in).
The list is held to one rule: anything bfw-process doctor reports as missing with "run bfw-process sync" is something sync writes (#117). A remediation hint that doesn't remediate is worse than no hint, so the contract is enforced by a test rather than by memory.
npm updatealone won't move the pin — the devDep is pinned exactly, not as a range. Usenpm install --save-dev ...@latest(or@<version>) to change the pin.
You usually don't have to do this by hand (#110)
Publishing and consumer updates form a closed loop:
- Publish is CI-driven. Merging a release to
mainin a BFW library publishes it to npm, tags it, and creates the GitHub Release — see.github/workflows/publish.yml(reusable; other libraries adopt it via the thin caller intemplates/.github/workflows/publish.yml). - The beacon tells consumers. After a publish, every org repo pinning the package receives a
bfw-library-publisheddispatch. The receiver workflow (installed into.github/workflows/bysyncon npm projects) opens an upgrade PR that runs the exact commands above — bump and sync — with the doctor report in the PR body. You review and merge. - A weekly sweep reconciles stragglers (bfw-process#113): repos that missed the beacon get the same PR.
bfw-process doctorwarns when behind. Doctor compares the pin against the npm registry's latest (best-effort; skipped offline), so staleness shows up in every doctor run — and on the canonical repo it flags the reverse failure: a version merged tomainbut never published.
Authoring this package
This repo self-hosts: it uses its own process on itself. See SPEC.md for the Phase 2 spec and .bfw-process/config.json for its own configuration. Contributions and amendments require review from at least one co-owner.
License
MIT © Brad Frost Web LLC — Brad Frost, Ian Frost
