Skip to content
 
 

Repository files navigation

firm

Why

One engineer wearing every hat, with a producer keeping them coherent. firm is the engineering operating system that handles the work around the code: the roles, skills, workflows, gates, and contracts that turn an idea into shipped, defensible software. It exists to stop three recurring failures: repeating work already done, repeating mistakes already made, and forgetting steps under pressure.


A Claude Code plugin that turns a feature idea into shipped, defensible software — without skipping any discipline. Twenty skills and six agents, each owning one seam of the engineering process, orchestrated by a producer that keeps them coherent.


Quickstart

scripts/firm-plugins.sh sync --rails   # 1. install (or update) firm's core + Rails tiers — restart Claude Code to apply
  1. Onboard the repo — run the firm-onboard skill (in the Rails tier); it writes .firm/profile.yml so every portable reviewer is grounded on your codebase.
  2. Drive a feature/grill-with-docs (shape it) → /break-down (decompose into a GitHub Epic) → /epic-autopilot (ship it, one PR per issue).

New to firm? Read on. In a hurry? The three lines above are the whole path.

See it run

A fresh machine installs firm from this repo, onboards a real Rails app, and the gate catches five planted convention violations — then a reasoned waiver, the config-driven PR-reference check, and the pluggable external-tools seam, ending with an empty git status (leaves no trace). Distilled from a real recorded acceptance run (11/11 claims passed):

firm acceptance demo

And act 2 — the judgement layer. Same repo, but Claude Code drives: the convention-reviewer agent (seam A6) reads the Profile, grades its findings beyond what the deterministic cops catch — including a failing test masquerading as coverage, an honest false-positive call on a stock Rails route, and a blind spot in firm's own gate, escalated as a firm issue:

firm judgement layer demo

And act 3 — the full arc. A product-owner request ("a coffee shop selling one subscription") driven end to end in a single session: the grill shapes six decisions, the break-down sequences five sub-issues with a safe stop, the build lands red→green on real modular engines (generated by seams — which surfaced a real gem bug, fixed and filed upstream on camera), firm's gate then reviews the session's own code, and the proof is a live server creating an active subscription with no payment keys at all:

firm full arc demo

Adopting firm from scratch? Start with the self-serve guide — five short documents that take a newcomer from install to a first shipped feature: install · concepts & the seam model · configure your ecosystem · extend firm · the disciplines & why.


The feature assembly line

A feature moves through five stations. Not every station fires on every feature — the right ones fire based on what the feature touches. The producer routes cross-seam work.

STATION 1 — Shape the work (before a line of code is written)
  strategy (B9)             At cycle start or on a direction shift. Write/refresh STRATEGY.md:
                            product goals, success metrics, tracks and personas in scope.
                            The upstream anchor brainstorm and plan read.
  story-writer (B6)         Always. Turn the idea into a well-formed GitHub issue:
                            one goal, Given/When/Then criteria, non-goals, test expectation.
  architecture-advisor (B7) If the feature crosses an architectural boundary or needs
                            a design decision. Options analysis + draft ADR.
  decompose-change (B1)     If the scope contains multiple concerns. Split first.
  producer (B4)             If the feature touches two or more seams. Sequence the
                            hand-offs and name the build order.

STATION 2 — Review the design (before code)
  skeptic (B3)              Any design doc, plan, or ADR. Independent adversarial review:
                            surfaces assumptions, blind spots, and known-unknowns.

STATION 3 — Build (during implementation, on the diff)
  decisions-from-diff (B2)  Every PR. Reads the diff and drafts ADRs for decisions
                            worth a reviewer's attention.
  perf-reviewer (A3)        If queries, serializers, or migrations are touched.
  security-reviewer (A4)    If auth, PII, or gem dependencies are touched.
  integration-resilience (C1) If a new outbound HTTP call or third-party client is added.
  boundary-reviewer (C2)    If the diff crosses an engine boundary.
  accessibility-review      If the UI changes.
  observability-check (A5)  If a new operation is added. Is it observable?
  test-strategist (A1)      Confirm the test coverage strategy is right for the change.
  mutation-testing          Kill alive mutations in the touched paths.

STATION 4 — Ship
  communicator (B5)         Write the PR description in house format and the operator's voice.
  release-gatekeeper (B8)   Three-gate pre-deploy: developer DoD, QA quality gate,
                            operational readiness (SHIP / CONDITIONAL / HOLD).

STATION 5 — After
  compound                  At cycle end. "What did this teach, and where does each lesson belong?"
                            Routes by scope: reusable patterns to docs/solutions/, conventions to
                            AGENTS.md/CLAUDE.md, terms to CONTEXT.md, the rest by hand-off. Silence
                            ("nothing worth compounding") is a valid output.
  retrospective             If something went wrong, harvest the lesson into a gate or memory.
  firm-gap-check            At session end, check if firm has a gap worth recording.

Quick rule: if you're not sure which station applies, ask the producer. It reads SEAMS.md, finds the seam(s) the task crosses, and sequences the hand-offs.


Commands

Slash commands you invoke directly (from engineering-core, available in every repo). Type /<name>; in a headless or background session use the fully-qualified /engineering-core:<name>.

Command What it does
/grill-me Interviews you relentlessly about a plan or decision until it is sound, recommending an answer to every question.
/grill-with-docs The same grilling, but writes the proposal as it crystallises — maintains CONTEXT.md, records decisions inline, mirrors to the docs vault. For work that deserves a permanent record.
/break-down Turns an accepted proposal into a GitHub Epic + structurally-linked sub-issues (the real Sub-issues API), after grilling delivery: phases, dependencies, effort, safe stopping points.
/epic-autopilot Drives an Epic to completion, one sub-issue per fresh self-chaining session: works the next unblocked issue test-first, opens a documented PR, merges only when green, then launches the next session. --once = one hop; --no-merge = stop before merge. Never merges red; halts and escalates on a genuine block.
/note-break-point Quickly logs a break-point (a place your process slipped) to the ledger, to become a hook later.
/firm-self-improve On-demand, scans the session for what you did by hand and, where a reusable tool would remove that toil, builds it to firm's bar (a Why + a self-test) — plan-first and human-gated, routing each tool to firm / your repo / the backlog. Silent when there is nothing worth automating.

The delivery arc: /grill-with-docs (shape it) → /break-down (decompose it) → /epic-autopilot (ship it).


Install

firm is a set of Claude Code plugins, published through its own marketplace. A Rails repo needs two tiers; onboard the repo once they are enabled.

  1. Add the marketplace (once per machine):

    /plugin marketplace add davidslv/firm-os
    
  2. Install the tiers you need:

    /plugin install engineering-core@firm     # universal disciplines — everywhere
    /plugin install engineering-rails@firm    # Rails tier: firm-onboard + reviewers + flag detection + ux-audit
    

    engineering-rails depends on engineering-core.

  3. Onboard the target repo — run the firm-onboard skill in the repo. It detects the stack, writes .firm/profile.yml, builds the catalogue, and grounds every portable reviewer against this repo. Nothing else works until the Profile exists, so this is the first step in any new repo.

One command (shell) — fresh machine or one that already has firm:

scripts/firm-plugins.sh sync         # add marketplace + install if missing + update if present
scripts/firm-plugins.sh sync --rails # also handle the engineering-rails tier

Update (a machine that already has firm)

firm plugins are versioned, so a machine only sees changes after an update, and a plugin update applies on the next Claude Code session (the CLI prints "restart to apply"). Either run the script, or update by hand:

scripts/firm-plugins.sh update
# interactively, inside a session:
/plugin marketplace update firm
/plugin update engineering-core@firm      # and engineering-rails@firm if installed

scripts/firm-plugins.sh sync is the safe default: it installs if missing and updates if present, whichever the machine needs. (The full curated toolset and the declarative settings.json live in SETUP.md.)


The full roster

engineering-core — install everywhere

Skills (procedures invoked in the current context):

Skill Seam What it does Eval
strategy B9 Strategic anchoring Creates/updates STRATEGY.md: product goals, success metrics, tracks and personas in scope. The loop's upstream anchor for brainstorm and plan gate ◇
story-writer B6 Requirements quality Well-formed GitHub issue: one goal, testable ACs, non-goals, escalation policy 3/3 ‡
architecture-advisor B7 Architecture guidance Options analysis + draft ADR before code is written. Companion to decisions-from-diff (reactive) and skeptic (adversarial) 3/3 ‡
release-gatekeeper B8 Release readiness Three-gate pre-deploy: DoD, QA quality gate, operational readiness. SHIP / CONDITIONAL / HOLD 2/3 ‡
decisions-from-diff B2 Decision capture Reads a diff, surfaces architectural decisions, drafts MADR ADRs 3/3 ‡
decompose-change B1 Decomposition Splits a large or mixed-concern change into stacked, revertable PRs 2/3 ‡
test-strategist A1 Testing Picks the right test level and finds adversarial edges the happy path misses 3/3 ‡
observability-check A5 Observability "Is this change observable?" — detect signal, diagnose context, acceptance criteria 3/3 ‡
communicator B5 Communication PR descriptions, commit messages, Slack updates in the operator's voice and house format 3/4 ‡
producer B4 Delivery planning Orchestrates multi-seam work: routes hand-offs, holds build order, runs integration gate 3/4 ‡
ticket-sync B10 Ticket currency Mid-work: keeps the ticket the source of truth at three triggers — progress snapshots, open decisions (never pre-assigned), and decisions that supersede stale criteria. Silence is a valid output eval added; not yet 3-vote scored
firm-gap-check meta Post-session: surfaces a gap firm should fill (missing skill, check, or automation) 1/3 ‡
retrospective meta After a bug or incident: routes the lesson to a gate/hook or personal memory 2/3 ‡
compound compounding Cycle-end router: routes each learning to its home by scope (docs/solutions/, AGENTS.md, CONTEXT.md, or a hand-off). Silence is a valid output gate ◇ + regression-guard ¶
blast-radius blast-radius Change-time forcing function: scores a change's blast radius, decides with the human whether a feature toggle is warranted, and governs the flag's whole life via the .firm/flags.yml ledger (mandatory expiry) until removal gate ◇

Agents (independent workers in a fresh context):

Agent Seam What it does Eval
skeptic B3 Epistemic honesty Adversarial design reviewer: surfaces assumptions, blind spots, known-unknowns, BLOCK/CAUTION/PROCEED 1/3 ‡

engineering-rails — install in any Ruby or Rails repo (Profile-driven)

The portable Rails and Ruby-gem reviewers. Each reads a per-repo Profile (.firm/profile.yml, see plugins/engineering-rails/docs/profile-schema.md) for the stack, engines, asset layout, test command, and integrations, so the same reviewer is correct on any repo instead of one hard-coded codebase. The seams move here from the core and domain tiers; the seam-ownership gate keeps exactly one owner each.

Skills:

Skill Seam What it does Eval
integration-resilience C1 Integration resilience Checklist for any new outbound HTTP call: timeout, retry, idempotency, DLQ, observability. Reads the Profile's integrations 2/3 ‡ (re-verified 2026-06-22; case 1 delta +)
mutation-testing C-A1 Mutation testing Decides what an alive Ruby mutation means: add test, simplify, or accept as unkillable. Grounded on the Profile's test_framework 3/4 ‡
accessibility-review ux-audit Audits Rails/Hotwire/Tailwind UI against WCAG 2.2 AA. Reports file:line, SC, impact, fix 3/3 ‡
ux-audit runtime-ux Runtime, browser-driven UX audit when a runnable URL exists: delegates to an external UX-audit tool (a11y/perf/journeys/copy/visual), surfaces verdict.json in firm's five house buckets graded verified, degrades to the static accessibility-review when tool/URL absent 2/2 ‡ (case 1 delta+, first real lift) + gate ◇
firm-onboard onboarding The entry-point that makes firm productive on a fresh repo: a deterministic detector writes the per-repo Profile (stack, versions, engines, asset pipeline, test command, integrations), then a grill fills intent (criticality, ownership, constraints) into a per-engine catalogue and augments AGENTS.md/CLAUDE.md non-destructively. Has an optional external-tool signal seam for churn/hotspot evidence gate ◇

Agents:

Agent Seam What it does Eval
migration-safety-reviewer A2 Data safety Reviews DB migrations: lock risk, concurrent index, reversibility, backfill safety against live data 3/3 ‡
perf-reviewer A3 Performance N+1 reads, missing FK indexes, query-cost regressions. Runs FK scanner pre-check 2/3 ‡
security-reviewer A4 Security Dependency PRs (safe to merge?) + diff review: secrets, tenant scoping, auth, injection 3/4 ‡ (re-verified 2026-06-22 post-relocation; cases 2,3 delta +)
boundary-reviewer C2 Engine boundary Cross-engine model/scope/service reach + asset-manifest footgun. Runs cross-association scanner; reads engines and asset layout from the Profile 3/4 ‡ (2026-06-22; case 1 over-flags engine↔host assoc, delta −)
convention-reviewer A6 Convention conformance Judges the Rails-way residue no cop catches: resource-vs-verb, logic placement, association modelling, tautology / wrong-seam tests. Reads the Profile; emits a deviation dossier eval added (#404 pattern); not yet 3-vote scored

Verified (3-vote), 2026-06-20 — full roster. All nineteen skills and agents were re-scored with EVAL_JUDGE_VOTES=3 … --save-outputs and committed under evals/outputs/ (eight dated run dirs, …T014006 through …T124931). What the runs showed:

  • Single-judge lows were mostly understated. communicator 1/3→3/4, security-reviewer 2/3→4/4, retrospective 0/3→2/3, engine-boundary-reviewer 2/4→4/4 (its "regression" was judge noise), decompose-change 1/3→2/3, decisions-from-diff 2/3→3/3, migration-safety-reviewer 2/3→3/3.
  • Some held, some fell — genuine, not noise. Clean 3/3s confirmed: story-writer, architecture-advisor, test-strategist, observability-check. Held weak: skeptic 1/3 (fabricates findings), release-gatekeeper 2/3 (no lift), integration-resilience 2/3 (over-flags a clean integration). Fell on pressure-testing: firm-gap-check ~2/3→1/3 (no silence / no autonomous write), perf-reviewer 3/3→2/3 (grades a deterministic FK-index catch "likely" not "verified"). The old "use 3 votes and skeptic/release-gatekeeper pass" note is retired.

Nine skill/eval follow-ups remain open: producer, communicator, mutation-testing, skeptic, release-gatekeeper, decompose-change, firm-gap-check, integration-resilience, perf-reviewer.

§ Re-scored 2026-06-22 (Phase 4, #31). The boundary-reviewer is the relocated, Profile-driven form of the old engine-boundary-reviewer (which scored 4/4 ‡ under its domain-named, hard-coded form). Its eval was re-grounded onto a neutral Profile fixture (evals/fixtures/boundary-reviewer/profile.yml) and renamed to evals/boundary-reviewer.json; the four cases and their assertions are unchanged in shape. The 3-vote re-score (resolver fixed so the WITH arm actually loads the role) gives 3/4: cases 2, 3, 4 pass, and case 1 regresses (delta −) because the reviewer over-flags a legitimate engine↔host association, the known pre-existing weak spot.


Convention & TDD governance — the .firm/ gate

The engineering-rails tier is not only reviewers; it governs the Rails way with a self-contained toolchain that installs under a gitignored .firm/ and leaves no trace in the target repo (proposal 0008). firm install lays down the sidecar — its own bundle, config, an exceptions ledger, tool pins, and a native git pre-push hook — and firm update refreshes the pinned tool versions. The gate blocks a deviation locally, overridable only with a recorded reason: FIRM_OVERRIDE="rule@path: reason".

  • Deterministic cops (in .firm/hooks/checks.d/, each with a self-test, all ledger-aware): hatch-lock (escape hatches from Rails' own walls), rest-shape (non-resourceful routes), herb-view (ActiveRecord in ERB), and the TDD-quality pair tdd-private-probe / tdd-internal-mock. A test-presence check blocks a behaviour-bearing change with no matching test.
  • Orchestrated tools: brakeman (static, from the sidecar) and bullet (runtime, injected into the host's own test run) — never into the host's committed bundle — plus any deterministic analysis tools a repo registers in .firm/tools.yml (optional, plural). The one deterministic RuboCop cop firm turns on is Rails/UniqueValidationWithoutIndex.
  • The A6 convention-reviewer judges the residue no cop catches (resource-vs-verb, logic placement, tautology / wrong-seam tests) and emits a deviation dossier. Its rubrics: plugins/engineering-rails/docs/rails-conventions-rubric.md (state modelling) and plugins/engineering-rails/docs/tdd-good-bad-rubric.md (test quality).
  • Generators (.firm/generators/) scaffold convention-correct, test-first, unbranded Rails; a reusable capability made while working is harvested upstream into engineering-rails, a host-tool gap becomes a suggested PR (e.g. firm-suggest-strong-migrations.sh), never a silent edit.

Default is local-only (binds your machine, no committed trace, proposal 0007); a shared mode that commits the gate for a whole team is an explicit, off-by-default opt-in. Full design in proposal 0008.


Eval score key

All 19 scores are verified (3-vote), 2026-06-20. Every fraction in the roster (the rows) is a committed EVAL_JUDGE_VOTES=3 run saved under evals/outputs/ — a reproducible record, not a single-judge estimate. See the note above for what each run found. scripts/check-roster.sh guards eval presence; the numbers trace to the dated artifacts.

Each case is rated by whether the WITH arm passes and whether the skill helps vs. the baseline (delta +/0/−).

Notation Meaning (verified 3-vote)
n/m of m cases, n passed under a 3-judge majority
delta + the skill's WITH arm passed where the bare baseline failed — it helped
delta 0 WITH and WITHOUT agreed — the skill matched the baseline on that case
delta − regression — WITH failed where the baseline passed
gate ◇ not a judge eval: proof is a deterministic gate (proposal D9). strategy is gate-checked by scripts/check-strategy.sh (present-and-complete STRATEGY.md), which ships a self-test over a valid and an invalid fixture
gate ◇ + regression-guard ¶ compound is a forcing function, so per proposal D9 + D12 its proof is the procedural release-gatekeeper "did this cycle compound and decide correctly, including silence?" gate (#29), not eval lift. evals/compound.json (rich / barren / routing cases) is kept as a REGRESSION GUARD only: at 3 votes it scores 3/3 with every delta 0, meaning the WITH arm matches the bare baseline and never does worse. It is not evidence of lift; a one-shot WITH-vs-WITHOUT prompt cannot measure a skill whose value is that it runs every cycle. See D12 for the full finding (including a fixed regression and an eval-harness side-effect on real memory)

To re-score any skill: EVAL_JUDGE_VOTES=3 bash scripts/run-evals.sh --save-outputs evals/<skill-name>.json


Reference docs

Doc What it contains
docs/architecture.md How firm is put together and why: the tiers, the seam model, the .firm/ sidecar, the gate, and the pluggable external-tools + ecosystem seams
docs/guide/ The self-serve guide: install, concepts, configure-your-ecosystem, extend-firm, the disciplines
proposals/ Numbered design proposals; 0008 decides firm's Rails convention + TDD governance (the .firm/ gate), 0007 the leaves-no-trace overlay
SETUP.md The full curated toolset + declarative settings.json; install and update paths
docs/sdlc-role-profiles.md Evidence-grounded SDLC role profiles (8 roles, boundary table, RACI)
plugins/engineering-core/SEAMS.md The 8 core seams (B1–B8, A1–A5) and house rules
docs/skill-authoring.md How to author a skill/agent: the seam: key, dispatch tier, WHEN NOT clause, the CI gates

Quality gates

Five checks run in CI (.github/workflows/) and the pre-commit hook, so firm holds its own standards automatically rather than by reminder:

  • Why-section gate (scripts/check-why-sections.sh) — every authored file declares a Why.
  • Roster gate (scripts/check-roster.sh) — README counts, roster membership, one-owner-per-seam (the seam: frontmatter key), and the ≤1024-char description limit all match what is on disk.
  • Self-test suite (scripts/run-self-tests.sh) — runs every *.self-test.sh / test-*.sh across the plugins as one command (over a Ruby matrix in CI): the cops, the .firm/ gate, the sidecar installer, the generators, the validators, and the plugin install/update script. A regression fails the build.
  • Eval suite (scripts/run-evals.sh) — each judgment skill ships an eval proving it beats the baseline; scores are single-judge and indicative until a committed 3-vote --save-outputs run (see evals/README.md).
  • Strategy gate (scripts/check-strategy.sh) — a deterministic check that a STRATEGY.md is present and carries its four required sections (proposal D9: a mechanical skill is gated, not judged). Ships a self-test over a valid and an invalid fixture (--self-test).

See docs/skill-authoring.md to add a new skill or agent to firm's standard.


Structure

firm/
├── plugins/
│   ├── engineering-core/       # 15 skills + 1 agents + hooks + commands
│   │   ├── SEAMS.md
│   │   ├── skills/             # strategy, story-writer, architecture-advisor, release-gatekeeper,
│   │   │                       # decisions-from-diff, decompose-change, test-strategist,
│   │   │                       # observability-check, communicator, producer,
│   │   │                       # firm-gap-check, retrospective, compound, blast-radius, ticket-sync
│   │   ├── agents/             # skeptic
│   │   ├── commands/           # break-down, grill-me, grill-with-docs, note-break-point,
│   │   │                       # epic-autopilot, firm-self-improve (+ its harvest/route/gen-cop toolkit)
│   │   ├── scripts/            # external-tool-evidence.sh (generic multi-provider adapter) + self-test
│   │   ├── docs/               # ecosystem-schema.md, tools-registry.md
│   │   ├── examples/           # ecosystem.example.yml, tools.example.yml
│   │   └── hooks/              # verify-gate.sh
│   └── engineering-rails/      # 5 skills + 5 agents (Profile-driven; install in any Ruby/Rails repo)
│       ├── SEAMS.rails.md
│       ├── docs/               # profile-schema.md, tdd-good-bad-rubric.md,
│       │                       # rails-conventions-rubric.md, generators-and-harvest.md
│       ├── examples/           # profile.example.yml
│       ├── scripts/            # validate-profile.sh + validate-pins.sh (+ self-tests), firm-update.sh (+ test),
│       │                       # runtime-ux-tool.sh (shared runtime UX-audit helper) + self-test + fixtures/runtime-ux/,
│       │                       # ux-boot.sh (optional local boot for the runtime audit) + self-test
│       ├── skills/             # integration-resilience, mutation-testing, accessibility-review,
│       │                       # ux-audit (runtime UX audit; delegate to an external UX-audit tool + surface + grade; gate-checked),
│       │                       # firm-onboard (detector + Profile + grill/catalogue + knowledge merge; gate-checked)
│       │                       #   → the .firm/ gate (proposal 0008): firm-install/firm-gate/firm-suggest-strong-migrations,
│       │                       #     cops/ (hatch-lock, rest-shape, herb-view, tdd-private-probe, tdd-internal-mock),
│       │                       #     generators/ (firm-generate-model), config/rubocop.yml
│       └── agents/             # migration-safety-reviewer, perf-reviewer, security-reviewer,
│                               # boundary-reviewer, convention-reviewer
├── evals/                      # 24 eval files: one per judgment skill/agent, plus the firm-self-improve command
├── proposals/                  # numbered design proposals (0001–0008)
├── scripts/
│   ├── firm-plugins.sh         # atomic install/update of firm's own plugins (+ self-test)
│   ├── run-self-tests.sh       # runs every *.self-test.sh / test-*.sh as one suite (CI matrix)
│   ├── run-evals.sh            # the eval runner (--save-outputs writes a score artifact)
│   ├── check-why-sections.sh   # the Why-section gate
│   ├── check-roster.sh         # the roster / seam-ownership / description gate
│   └── check-strategy.sh       # the STRATEGY.md gate (D9; --self-test over valid/invalid fixtures)
├── statusline/                 # operator statusline
└── docs/                        # design records, backlog, glossary, role profiles

About

An engineering operating system for Claude Code — the work around the code: planning, sequencing, test-first delivery, convention gates, honest PRs. Works best with Ruby on Rails.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages