beat
CLAUDE.md9 starsChanged 7 months agoMITView on GitHub
Beat is a Claude Code plugin that provides an agent-driven BDD (Behavior-Driven Development) workflow. It uses Gherkin .feature files as the single source of truth for behavior specifications. Beat is not an application — it is a set of skills (SKILL.md files) that Claude Code loads as a plugin.
The file
We split this CLAUDE.md into the rules it gives an agent
10 rules. About 0 are common, 1 is distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 78
When installed in a user's project, Beat creates this structure:
- Very specific: line 158
Spec self-review: After writing each artifact, /beat:design runs a four-check pass (placeholder / consistency / scope / ambiguity) and …
- Very specific: line 168
Test files include // @feature: <file>.feature and // @scenario: <name> comments
- Distinctive: line 169
Verify checks these annotations for bidirectional traceability
- Very specific: line 251
After changing any skill description → run skill-triggering/run-all.sh
- Very specific: line 252
After changing enforcement rules (Hard Gate, Rationalization Table) → run pressure/run-all.sh
- Very specific: line 253
After changing skill content → run skill-content/run-all.sh
- Very specific: line 263
Run the skill command (e.g., /beat:design, /beat:plan)
- Very specific: line 264
Verify the skill produces correct artifacts and status.yaml updates
- Very specific: line 284
If we ever want to publish Beat to the canonical openai/plugins curated marketplace, that's a separate manual step (open a PR upstream that …
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What Is Beat
Beat is a Claude Code plugin that provides an agent-driven BDD (Behavior-Driven Development) workflow. It uses Gherkin .feature files as the single source of truth for behavior specifications. Beat is not an application — it is a set of skills (SKILL.md files) that Claude Code loads as a plugin.
Installation
claude --plugin-dir /path/to/beatArchitecture
Plugin Structure
beat/
├── .claude-plugin/plugin.json # Claude Code plugin manifest
├── .codex-plugin/plugin.json # Codex plugin manifest (with interface block)
├── .agents/plugins/marketplace.json # Codex marketplace manifest — makes this repo a single-plugin marketplace
├── plugins/beat/ # Codex plugin overlay (symlinks to root files: skills, assets, .codex-plugin, references)
├── assets/ # Brand icons (composerIcon, logo) for Codex
├── skills/ # Each subdirectory = one invocable skill (SKILL.md + synced references/)
│ ├── design/ # /beat:design — create change + generate spec artifacts
│ ├── plan/ # /beat:plan — task breakdown with multi-role review
│ ├── apply/ # /beat:apply — TDD implementation
│ ├── verify/ # /beat:verify — 5-dimension verification
│ ├── archive/ # /beat:archive — sync features + archive completed change
│ ├── explore/ # /beat:explore — thinking partner mode; ends by declaring an exit (small / standard / too-big / blocked / drop)
│ ├── to-issue/ # /beat:to-issue — turn a settled exploration into a tracker issue (or epic + sub-issues)
│ ├── setup/ # /beat:setup — create beat/config.yaml + the agent docs (issue-tracker.md, CODING_STANDARDS.md, Agent docs block)
│ └── distill/ # /beat:distill — reverse-engineer specs from code
├── references/ # Source of truth for shared schemas — edit here, then run scripts/sync-references.mjs
│ ├── status-schema.md # status.yaml format
│ ├── config-schema.md # config.yaml format
│ ├── testing-conventions.md # Annotation format and e2e test style reference
│ ├── project-layout.md # Map of every project-level path Beat writes (authority for paths)
│ ├── context-format.md # GLOSSARY.md glossary format (Layer 1 living docs)
│ ├── adr-format.md # docs/adr/ ADR format + three-condition gate (Layer 2 living docs)
│ ├── architecture-format.md # beat/ARCHITECTURE.md hub + module README format (Layer 3 living docs)
│ ├── route-schema.md # beat/routes/<name>/ map + nodes (research / prototype / decision / change); status is derived
│ ├── verify-findings.md # verify.md front matter — findings that /beat:apply fix-from-verify consumes
│ ├── handoff-report.md # The "## Beat Handoff" block every skill ends with, plus the rhythm-stage-result suffix
│ ├── unattended-mode.md # How skills behave under an orchestrator: defaults, decision briefs, sensitivity, per-skill mapping
│ ├── decision-brief.md # Ten-line brief a skill writes when it must stop for a human in unattended mode
│ ├── issue-tracker-github.md # docs/agents/issue-tracker.md template — GitHub (gh)
│ ├── issue-tracker-gitlab.md # docs/agents/issue-tracker.md template — GitLab (glab)
│ ├── issue-tracker-other.md # docs/agents/issue-tracker.md template — any other tracker
│ ├── coding-standards-template.md # CODING_STANDARDS.md template
│ ├── lint-tools.md # How and when skills run validate-beat.mjs / lint-features.mjs
│ ├── tool-mapping.md # Cross-platform tool name mapping (root only)
│ └── codex-agents-snippet.md # Per-project AGENTS.md snippet for Codex (root only)
├── scripts/sync-references.mjs # Syncs /references and /scripts into each skill's references/ and scripts/ (see header)
├── scripts/validate-beat.mjs # Deterministic checks: status.yaml, routes, verify.md, config, .orig residue, --pre-archive, --stale-paths, --handoff, --layout
├── scripts/lint-features.mjs # Feature-file linter (annotations, layer tags, user story, tags, placeholders, README index)
├── docs/migrations/ # Upgrade prompts an agent runs inside a target project (0.6-project-layout.md)
├── NOTICE.md # Third-party attribution (mattpocock-skills, superpowers — both MIT)
├── hooks/ # Claude Code hooks (Codex ignores; replaced by AGENTS.md snippet)
│ ├── hooks.json # SessionStart hook config
│ └── session-start # Detects Beat project, injects workflow context
├── tests/ # Automated skill tests (claude -p headless)
│ ├── test-helpers.sh # Shared assertion framework
│ ├── run-all.sh # Run all fast tests (--integration for pipeline)
│ ├── analyze-token-usage.py # Token analysis for test sessions
│ ├── skill-triggering/ # Layer 1: Description CSO validation
│ ├── skill-content/ # Layer 2: Enforcement awareness smoke tests
│ ├── pressure/ # Layer 3: Anti-rationalization under pressure
│ ├── validator/ # Deterministic fixtures for scripts/validate-beat.mjs (no LLM)
│ └── pipeline/ # Layer 4: End-to-end pipeline (--integration)
└── README.mdHow It Works in Target Projects
When installed in a user's project, Beat creates this structure:
<project>/
├── GLOSSARY.md # Layer 1 — domain glossary (lazy, created on first term)
├── CODING_STANDARDS.md # Reviewer-facing judgement rules (written by /beat:setup)
├── CLAUDE.md | AGENTS.md # Contains the "## Agent docs" pointer block (written by /beat:setup)
├── beat/
│ ├── config.yaml # Optional project config (language, context, rules)
│ ├── ARCHITECTURE.md # Layer 3 — architecture hub (lazy, multi-module projects)
│ ├── changes/ # Active and archived changes
│ │ ├── <change-name>/ # One directory per active change
│ │ │ ├── status.yaml # Change lifecycle state
│ │ │ ├── proposal.md # Optional: why this change exists
│ │ │ ├── features/ # Gherkin feature files (mandatory by default)
│ │ │ │ └── *.feature
│ │ │ ├── design.md # Optional: technical decisions
│ │ │ ├── tasks.md # Optional: implementation checklist
│ │ │ └── verify.md # Written by /beat:verify: findings front matter + report
│ │ └── archive/ # Completed changes (YYYY-MM-DD-<name>/)
│ ├── routes/ # Work too big for one change (lazy)
│ │ └── <route-name>/
│ │ ├── route.md # Destination / decisions so far / not yet specified / out of scope
│ │ └── status.yaml # Nodes + blocked_by edges; node status derived from changes
│ └── features/ # Persistent living documentation
│ └── <capability>/ # Organized by capability after sync
│ ├── *.feature
│ └── README.md
├── docs/
│ ├── adr/ # Layer 2 — ADRs (lazy, three-condition gate)
│ │ └── NNNN-slug.md
│ └── agents/
│ └── issue-tracker.md # Tracker, labels, dispatch conventions (required for /beat:to-issue)
└── packages|src/<module>/
└── README.md # Layer 3 — module README (lazy, on public-interface change)Pipeline Flow
explore ──exit──► [to-issue ──label──►] design → plan → apply ⇄ verify → archive
│ │ │ (fix-from-verify / incremental)
│ │ └── tasks (review depth follows preset)
│ └── [proposal] → gherkin → [design] (preset: full / standard / minimal / technical)
├─ too-big → beat/routes/<name>/ (map + nodes); each change node re-enters at explore/design (to-issue: epic + sub-issues)
├─ blocked → research (AFK) / prototype (HITL) / decision (HITL) node, then explore again
└─ drop → nothing is built; the issue (if any) is closed with the reasonFor purely technical changes (tooling, deps, refactor): gherkin can be skipped, proposal becomes the driver.
Explore ends by declaring one exit (small, standard, too-big, blocked, drop) with the facts behind it. /beat:to-issue is optional: it writes the conclusion into a tracker issue (an epic with sub-issues for a route) so an orchestrator or a person can run design later without the conversation; the dispatch label is added only when the user asks. The preset chosen in design sets the strength of later phases: minimal/technical get a test-coverage-only plan review and a single verify subagent, and /beat:apply upgrades them to standard when the diff crosses config.yaml preset_upgrade thresholds. Verify writes verify.md; apply fix-from-verify fixes the open CRITICALs (explicit ids for anything else); re-runs are incremental from verification.sha and bounded by convergence rules (severity floor, prose ceiling, iteration ramp, round cap — see skills/verify/SKILL.md "Convergence"). A full re-run is the user's choice; archive never requires it. Apply never pushes — pushing comes after archive. Every skill ends with the ## Beat Handoff block.
- design: Creates worktree + change container + generates spec artifacts (proposal, gherkin, design.md) + commits
- plan: Creates execution plan (tasks.md) with multi-role review against spec artifacts + commits
- apply: TDD implementation — gherkin-driven (every scenario must have a test) or proposal-driven (when gherkin skipped). Verifies worktree isolation (should exist from design/plan).
- verify: Dispatches independent subagent(s) to verify against artifacts (two in parallel at standard strength, one at minimal); writes
verify.mdfindings; incremental on re-run - archive: Syncs features to
beat/features/as living documentation (merging the change'sdesign.mdinto an existing capabilitydesign.mdrather than overwriting it) + moves change tobeat/changes/archive/+ rewrites every tracked reference to the oldbeat/changes/<name>path + commits the archive as the last commit on the feature branch, then hands off tosuperpowers:finishing-a-development-branchfor merge/PR. Archive runs before the PR, never after it is merged.
Key Concepts
- Project-level paths (
GLOSSARY.md,CODING_STANDARDS.md,docs/agents/issue-tracker.md, the## Agent docsblock,docs/adr/,beat/…) are defined inreferences/project-layout.md; it is the authority, and skills point at it instead of hardcoding paths. Projects created before 0.6 migrate withdocs/migrations/0.6-project-layout.md. - status.yaml is the state machine — schema defined in
references/status-schema.md. Phase advances forward only. Pipeline entries use inline YAML flow style:{ status: done }.presetrecords the artifact preset and drives later-phase strength;routelinks a change to its route node./beat:verifyrecords its outcome in the top-levelverificationfield (status, counts,sha,mode; it never advances phase);/beat:archivewarns when archiving a change without a passing, full verification record. No field outside the schema —node scripts/validate-beat.mjs <project>rejects unknown keys. - routes (
beat/routes/<name>/, schemareferences/route-schema.md) hold work too big for one change: a map plus nodes withblocked_byedges. Node status is always derived (a change node is done when its change is archived), never written, so there is no second state machine to drift. Rhythm or any dispatcher only sees one change per task; parallelism is a human reading the frontier. - config.yaml is optional project config — schema in
references/config-schema.md. Controls artifact language, injects project context, and adds per-artifact rules (proposal,gherkin,design,tasks,adr).rules.adrapplies at every ADR trigger point, so every skill that can write an ADR (including/beat:explore) reads the config; a projectdocs/adr/TEMPLATE.mdtakes precedence over Beat's built-in ADR template. - Unattended mode (
references/unattended-mode.md) is on only when the run carries a stage-result nonce (Rhythm). Questions take defaults recorded inbeat/changes/<name>/decisions/assumed.md; a decision that meets the ADR gate or matchesconfig.yamlsensitivebecomes a brief (references/decision-brief.md) and the run stops withblocked-on: decision; the handoff suffix carriesblocked-on/decision/sensitive/diverging. Archive pushes and opens a ready PR with a "決定與影響" section instead of invoking finishing-a-development-branch. Explore is never unattended. - Gherkin is mandatory by default but can be skipped for purely technical changes (tooling, deps, refactoring without behavior change). When skipped, proposal drives plan, apply, and verify.
- verify uses independent subagents (Agent tool:
Explorefor spec verification,general-purposefor code review) to avoid context bias. When verifying distilled specs (source: distill), it switches to accuracy mode. - distill works in reverse (code → spec), marks features with
@distilledtag, and relies on/beat:verifyfor independent accuracy verification. A distill change setstasks: skipped(nothing to implement) and flows distill → verify → archive; future changes to the distilled area use the normal flow in their own change containers.
Living Documentation (three layers)
Beat maintains three layers of project-level living documentation alongside the per-change artifacts. All three are lazy — created on first need, never preemptively. They complement the per-change archives, not replace them.
- Layer 1 —
GLOSSARY.mdat the project root (glossary, the same file mattpocock'sdomain-modelingwrites). Domain vocabulary, one canonical term per concept, opinionated about synonyms. Maintained inline by/beat:design(four-challenge check before writing gherkin),/beat:distill(glossary check on terms recovered from code), and/beat:archive(scan synced features for undefined terms). Format:references/context-format.md. Optional grilling viamattpocock-skills:grill-with-docswhen ambiguity is complex. - Layer 2 —
docs/adr/NNNN-slug.md(decisions). 1-3 sentence ADRs gated by three conditions: hard-to-reverse + surprising without context + result of a real trade-off. Offered at six trigger points:/beat:explore(decision capture during exploration),/beat:design(per Key Decision),/beat:plan(review rejections),/beat:apply(implementation-forced choices),/beat:distill(Key Decisions recovered from code — rationale from evidence or the user, never invented),/beat:archive(last-mile sweep when zero ADRs written). Format:references/adr-format.md. ADRs live atdocs/adr/rather thanbeat/adr/because the ADR format is an industry standard (Nygard 2011) with its own tool ecosystem; Beat only triggers and offers, while the files belong to the project and outlive Beat if the plugin is removed. - Layer 3 —
beat/ARCHITECTURE.mdhub + moduleREADME.mdspokes (structure & intent). Hub stays under ~150 lines: one Mermaid diagram, modules table, constraints referencing ADRs. Each module README under ~100 lines: purpose, public interface, dependencies, tests. Vocabulary is intentionally unspecified — use the codebase's native terms (package/service/module/layer). Maintained by/beat:apply(hard prompt on public-interface change, README scaffold offer on new module),/beat:design(hub update suggestion on module-level architecture change),/beat:distill(README scaffold offer for distilled modules), and/beat:verify(Dimension 5, WARNING tier, advisory only). Format:references/architecture-format.md. Structural snapshots (file tree, symbol map) are derive-tool territory — Beat doesn't generate them. - Spec self-review: After writing each artifact,
/beat:designruns a four-check pass (placeholder / consistency / scope / ambiguity) and fixes issues inline. Adapted fromsuperpowers:brainstorming.
Testing Architecture
Beat supports a three-layer testing architecture that connects feature files to tests at the appropriate level:
Layer 1: E2E Tests — @e2e tagged scenarios → e2e tests or BDD step definitions (using project's e2e framework)
Layer 2: Behavior Tests — @behavior tagged scenarios → tests with annotation linking (using project's test framework):
- Feature files include
# @covered-by: <path/to/test.ts>between the tag and scenario line - Test files include
// @feature: <file>.featureand// @scenario: <name>comments - Verify checks these annotations for bidirectional traceability
Layer 3: Unit Tests — No feature binding, driven by proposal risk points or developer judgment
Annotation conventions:
In .feature files (annotation placed between tag and scenario line):
@behavior @happy-path
# @covered-by: src/services/__tests__/date-calculation.test.ts
Scenario: Monthly billing adjusts for short monthsIn test files (use the project language's comment syntax):
@feature: monthly-billing.feature
@scenario: Monthly billing adjusts for short monthsGranularity guidance — Scenarios should describe behavior (what the system does), not function specs (how a function works). See design/SKILL.md for Gherkin creation guidelines.
Proposal-driven testing — When gherkin is skipped (technical changes), testing is driven by proposal.md risk points and success criteria. Tests use the project's test framework without feature file annotations.
Dependencies
Requires the superpowers plugin for the rigor inside a phase: brainstorming (explore, design), using-git-worktrees (design, plan, apply, distill), writing-plans (plan), test-driven-development / systematic-debugging / subagent-driven-development (apply), finishing-a-development-branch (archive). Each has an inline fallback when not installed. Beat suppresses the hand-offs those skills would otherwise make (brainstorming → writing-plans, SDD → finishing) because Beat's phases decide the next step.
Optionally integrates with mattpocock-skills at the edges of the pipeline: grilling + domain-modeling (explore / design, when a glossary term is genuinely ambiguous; both model-invoked — grill-with-docs is user-invoked and unreachable from a skill), pr (archive in unattended mode), research and prototype (explore, for a blocked exit of that kind), retro (mentioned after archive). All optional with graceful fallback. The route map format is adapted from its wayfinder skill (see NOTICE.md). The "when which" guidance lives in README "Companion Skills" and docs/DESIGN_PRINCIPLES.md "Companions, Not Owners".
NOTICE.md records third-party attribution for content adapted from these projects (both MIT-licensed).
Superpowers Integration
Beat cooperates with Superpowers via a SessionStart hook (hooks/session-start). When beat/config.yaml or beat/changes/ exists, the hook injects context telling Claude to transition to Beat workflow after brainstorming instead of writing-plans directly. Skills reference Superpowers via MUST invoke prerequisites with anti-rationalization enforcement (Hard Gate, Rationalization Table, Red Flags).
Design Philosophy
See docs/DESIGN_PRINCIPLES.md for the full design philosophy — core beliefs, testing philosophy, pipeline design rationale, and what Beat is and isn't. Consult it when evaluating changes that affect multiple skills or the overall direction.
Development Guidelines
Editing Skills
Each skill is a single SKILL.md file with YAML frontmatter (name, description) followed by markdown instructions. Skills are self-contained — they reference schemas in references/ but don't import code.
Schema Changes
references/status-schema.md, references/config-schema.md, references/route-schema.md and references/verify-findings.md are the single sources of truth. Every skill that reads/writes these files must follow the schemas exactly. If you change a schema, audit all skills that reference it, update scripts/validate-beat.mjs, and run tests/validator/run.sh.
References sync
/references and /scripts are the source of truth; skills/<name>/references/ and skills/<name>/scripts/ are synced copies. After editing anything under either, run node scripts/sync-references.mjs (or --check for CI). Do not hand-edit synced copies. Rationale in the script header.
Lint tools
Two scripts carry the checks that are deterministic (references/lint-tools.md): validate-beat.mjs (status.yaml / routes / verify.md / config schema, .orig residue, --pre-archive, --stale-paths, --handoff) and lint-features.mjs (feature-file conventions). Skills call them as node <skill-dir>/scripts/<name>.mjs so they work the same under the Claude Code plugin, the Codex plugin (plugins/beat/scripts symlink plus the per-skill copies) and npx skills add (which copies one skill folder, scripts included). They need Node 18+ and no packages. When a rule can be written as a script, put it there and reduce the prose to "run it, fix what it lists".
Testing Changes
Beat has a four-layer automated test suite using claude -p headless mode. Tests are in tests/.
Run fast tests (~20 min):
cd tests && ./run-all.shRun all tests including pipeline integration (~50 min):
cd tests && ./run-all.sh --integrationFour test layers:
| Layer | What it tests | Scripts |
| Skill Triggering | Naive prompts trigger correct Beat skill | skill-triggering/ |
| Skill Content | Skills know their enforcement rules (smoke test) | skill-content/ |
| Pressure | Anti-rationalization holds under implicit pressure | pressure/ |
| Pipeline Integration | End-to-end design → plan → apply → verify → archive | pipeline/ (--integration only) |
| Validator | Schema fixtures for scripts/validate-beat.mjs, deterministic, seconds | validator/run.sh |
When to run tests:
- After changing any skill description → run
skill-triggering/run-all.sh - After changing enforcement rules (Hard Gate, Rationalization Table) → run
pressure/run-all.sh - After changing skill content → run
skill-content/run-all.sh
Notes:
- Tests use
claude -p --output-format stream-json --verboseand grep for tool invocations - Some tests are non-deterministic (LLM behavior varies) — a single flaky fail doesn't indicate a real problem
- Pressure tests assert the rule the prompt pressures, nothing more: for a Superpowers gate, that the skill was invoked (
ASSERT_SKILL), never how Superpowers executed it; for one of Beat's own gates (feature sync,.origcleanup, subagent dispatch, updating an existing test), the observable result (ASSERT_FILE,ASSERT_NO_FILE,ASSERT_FILE_CHANGED,ASSERT_TOOL). A scenario whose assertion cannot fail on the behaviour it pressures is not a test. Pressure scenarios tempt the agent without ordering a skip; explicit-override scenarios (*-explicit-*) have the user order one and assert the informed-skip promise viaASSERT_OUTPUT - macOS compatible (Perl-based timeout fallback, no GNU coreutils needed)
Manual testing is still useful for verifying the full user experience:
- Install the plugin in a test project
- Run the skill command (e.g.,
/beat:design,/beat:plan) - Verify the skill produces correct artifacts and status.yaml updates
Codex Distribution
Beat is installable on Codex directly from this GitHub repo — no separate marketplace fork or sync step. The repo is structured as a single-plugin Codex marketplace:
.agents/plugins/marketplace.jsondeclares one pluginbeatwithsource.path: "./plugins/beat".plugins/beat/is a thin overlay containing symlinks back to repo-root files (.codex-plugin/,skills/,assets/,references/,README.md,LICENSE). Single source of truth at root, no duplication.
source.path: "./" (root as plugin) was tried first but Codex's plugin scanner does not pick up content when marketplace and plugin overlap at the same path — the subdirectory layout matches the convention in openai/plugins and other working marketplaces.
End-user install (two steps because the Codex CLI has no plugin-install subcommand — only marketplace add/upgrade/remove):
codex plugin marketplace add https://github.com/kirkchen/beat- Inside Codex UI plugins panel, install Beat.
See docs/INSTALL-CODEX.md for the full user-facing flow.
Codex doesn't support hooks, so the SessionStart context injection performed by hooks/session-start does not run on Codex. The replacement is a per-project AGENTS.md snippet — see references/codex-agents-snippet.md for the text.
If we ever want to publish Beat to the canonical openai/plugins curated marketplace, that's a separate manual step (open a PR upstream that copies the plugin into their plugins/beat/ subdirectory — same shape we already use locally). The current setup intentionally does not automate that.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

