Workflow for autonomous software development with Claude Code. Classifiers route scope, complexity, directory state, and spec readiness before committing to Explore / Research / Plan / Act / Validate, then close the loop with a Compound step that persists lessons to `.erpaval/solutions/` for future sessions. Optional HMW reframing and EARS specification add structured rigor — Claude judges when to run them. Each Act subagent edits its own Markdown task packet section-by-section per the write ...
Scanned 9/7/2026
Install to Claude Code
npx -y skills add theagenticguy/erpaval --skill erpaval --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Erpaval?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/theagenticguy-erpaval-erpaval)More formats (shields.io, HTML) on the badges page.
---
name: erpaval
description: >
Workflow for autonomous software development with Claude Code.
Classifiers route scope, complexity, directory state, and spec readiness
before committing to Explore / Research / Plan / Act / Validate, then
close the loop with a Compound step that persists lessons to
`.erpaval/solutions/` for future sessions. Optional HMW reframing and EARS
specification add structured rigor — Claude judges when to run them. Each
Act subagent edits its own Markdown task packet section-by-section per the
write protocol, and the orchestrator monitors with `wc -l`. Use when the
user asks to implement a feature autonomously, build with agents, use
ERPAVal, plan and execute a coding task, delegate to subagents, do
agent-driven development, extract lessons, recall prior lessons, or
mentions autonomous coding workflow or compound engineering.
---
## Contents
| Reference | When to load |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `references/flow.md` | The graph — intake, build loop, validate/compound, cycles |
| `references/classifiers.md` | Prompt text for each `CL-*` classifier |
| `references/fan-out.md` | Per-phase subagent counts + the one-message parallel-launch rule |
| `references/glossary.md` | `CP-*`, `CL-*`, gates, cycles, zones, placeholder tokens |
| `${CLAUDE_PLUGIN_ROOT}/skills/product-discovery/references/roles/hmw-framer.md` | HMW substep (hard-dep on `product-discovery`; run when `CL-RIGOR` asks for HMW) |
| `${CLAUDE_PLUGIN_ROOT}/skills/product-discovery/references/roles/ears-specifier.md` | EARS substep (hard-dep on `product-discovery`; run when `CL-RIGOR` asks for EARS) |
| `references/orchestrator.md` | Per-phase runbook — Task-tool lifecycle, Agent patterns |
| `references/context-packets.md` | Per-packet YAML schemas + two-gate review + auto-merge rules |
| `references/write-protocol.md` | Canonical write-protocol block (copied into every Act prompt) |
| `references/validation-playbook.md` | 3-layer validation + closed-loop toolchain |
| `references/compound.md` | Dual-track lesson schema + recall retrieval algorithm |
| `templates/session/worklog-skeleton.md` | Per-task packet skeleton with embedded write protocol |
| `templates/session/` | YAML schemas the orchestrator seeds into `.erpaval/sessions/<id>/` at runtime |
| `templates/specs/` | EARS spec and task-list skeletons for the Framing substep |
| `templates/solutions/` | Lesson templates (bug, knowledge) the Compound phase writes from |
| `templates/brainstorms/` | HMW requirement skeletons for the Framing substep |
| `templates/INDEX.md` | Recall-phase index of lessons by category, read at session start |
# ERPAVal — adaptive autonomous software development
A six-phase workflow with two framing substeps and a compounding tail. The orchestrator (main Claude Code session) runs classifiers to decide which phases apply, delegates implementation to subagents, and persists Markdown + YAML packets under `.erpaval/` so future sessions start smarter than this one.
## The graph at a glance
```mermaid
flowchart LR
IN[Intake + Recall bootstrap] --> SCOPE{Scope?}
SCOPE -->|coding| COMPLEX{Complexity?}
SCOPE -->|non-coding| ROUTE[Upstream skill]
COMPLEX -->|1-file fix| DIRECT[Direct fix]
COMPLEX -->|multi-module or rebuild| RESUME{New or resume?}
RESUME -->|new| NEW[erpaval-new.py]
RESUME -->|resume| PRIOR[Load prior session]
NEW --> DIR{Dir state?}
PRIOR --> DIR
DIR --> RIGOR{Rigor?}
RIGOR -.->|fuzzy| HMW[HMW frame]
RIGOR -.->|contract unclear| EARS[EARS spec]
HMW --> EARS
EARS --> ER[Explore + Research]
RIGOR -->|crisp| ER
ER --> PLAN[Plan]
PLAN --> G1{Gate 1}
G1 -.->|revise| PLAN
G1 -->|approved| ACT[Act · waves]
ACT --> VAL[Validate]
VAL -.->|fail| ACT
VAL -->|pass| G2{Gate 2}
G2 --> MERGE[Merge]
MERGE --> COMP[Compound · extract lessons]
COMP --> DONE([Done])
```
Full three-view graph with every cycle is in `references/flow.md`. Dashed edges are named cycles.
## Strict phase gating via TaskCreate / TaskUpdate / TaskList
Each phase has a completion gate enforced by the `TaskCreate` / `TaskUpdate` / `TaskList` todo-list tool family (distinct from the `Agent` subagent-launcher). Every implementation task is wired with `addBlockedBy` so the task system itself prevents out-of-order execution. No skipping, no parallel execution across gates, no early starts.
The todo-list tools hold authoritative state. YAML packets under `.erpaval/sessions/` are read-only hints that inform which tasks to create and what goes in their `prompt`. Per-task Markdown packets at `.erpaval/sessions/<id>/tasks/T-AC-X-Y.md` double as subagent work logs — the agent edits them section-by-section per `write-protocol.md`, and the orchestrator monitors with `wc -l`. Partial progress on disk survives timeouts and SendMessage interrupts; state held in working memory does not.
See `references/orchestrator.md` for the per-phase runbook.
## Session 0 — mandatory intake scaffolding
Two steps the orchestrator always runs before Explore, so Compound can actually fire at the end of the session.
1. **Recall first (always).** `uv run ${CLAUDE_PLUGIN_ROOT}/skills/erpaval/tools/erpaval-recall.py bootstrap` surfaces category counts + `INDEX.md` path. Cold repos print `no prior lessons` and proceed. The `SessionStart` hook also emits this via `additionalContext`, but the tool call is the authoritative record — run it.
2. **Decide new vs resume (after `CL-COMPLEXITY` returns multi-module / rebuild).** `CL-RESUME` reads the request, `ls .erpaval/sessions/session-*/` (sorted by mtime), and the top-5 prior `session.yaml` files, then emits one of:
- **new session** — run `uv run ${CLAUDE_PLUGIN_ROOT}/skills/erpaval/tools/erpaval-new.py --request "<raw_request>"`. Creates `.erpaval/sessions/session-<hex>/intake.yaml`, ensures `.gitignore` and `INDEX.md`. **Required** — without a `session-<hex>/` dir, the Stop hook's six-gate check never clears and Compound silently no-ops.
- **resume session** — read the prior `session.yaml` + latest `tasks/*.md`, append the new ask to `intake.yaml.raw_request`, continue from the last completed gate. Do not scaffold a new `session-<hex>/`.
For 1-file fixes, `CL-COMPLEXITY` exits the flow before Session 0 step 2 — recall-only is correct; no session dir needed.
See `references/classifiers.md` for the `CL-RESUME` prompt and `references/orchestrator.md` for the runbook.
## Pre-phase classifiers — where adaptation lives
Before Explore starts, the orchestrator runs classifiers to decide which phases to run. Claude judges — the user never picks from a menu.
| Classifier | Question | Skips / routes |
| ----------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| **CL-SCOPE** | Is this a coding task? | Non-coding → route to `/research`, `/product-discovery`, `/product-strategy`, `/working-backwards`, `/customer-research`, etc. |
| **CL-COMPLEXITY** | 1-file fix · multi-module · rip-and-replace? | 1-file → skip ERPAVal, just fix |
| **CL-RESUME** | New session or resume a prior one? | new → `erpaval-new.py`; resume → read prior `session-<hex>/` and continue. Runs only when `CL-COMPLEXITY` is multi-module / rebuild |
| **CL-DIR** | Empty dir · existing code · rebuild-in-place? | Empty → skip Explore, start at Research |
| **CL-RIGOR** | Problem crisp, or needs HMW / EARS? | Crisp → skip both; fuzzy → HMW; contract-unclear → EARS; both when needed |
| **CL-SPEC** | PRD / stack / concept ready? | Missing → loop through `/product-discovery`, `/build-stack` (product-discovery covers PRD drafting and design-thinking methodology) |
| **CL-VALIDATE** | All 3 validation layers green? | Fail → C4 back to Act |
| **CL-C2** | Attempt-4 escalation in a stuck subagent? | fix-directly / respawn / missing-prereq (C3) |
| **CL-LESSONS** | Session produced novel learnings? | Yes → write to `.erpaval/solutions/`; no → skip |
See `references/classifiers.md` for each classifier's prompt text.
## Optional rigor — HMW + EARS
`CL-RIGOR` decides whether to run these substeps. Both are well-suited to subagent delegation (bounded creative task, durable file output). erpaval hard-deps on `product-discovery` for these substeps: the orchestrator seeds `brainstorms/NNN-<slug>-requirements.md` or `specs/NNN-<slug>/spec.md` from `${CLAUDE_PLUGIN_ROOT}/skills/product-discovery/templates/hmw-skeleton.md` / `ears-spec-skeleton.md` and spawns one general-purpose Task per substep that reads `${CLAUDE_PLUGIN_ROOT}/skills/product-discovery/references/roles/hmw-framer.md` (or `ears-specifier.md`) as its role prompt.
- **HMW** (fuzzy problems) — customer-problem template, 3 of 9 d.school strategies, NN/g-validated HMW statements.
- **EARS** (unclear contracts) — 5 templates (Ubiquitous, Event-driven, State-driven, Optional feature, Unwanted behavior). Each AC carries `[P]` (parallel-safe) or `Dependencies: AC-X-Y`. Plan derives tasks directly.
Skip both when the ask names a specific user segment, an observable outcome with a metric, and no solution verbs — see `${CLAUDE_PLUGIN_ROOT}/skills/product-discovery/references/frameworks/how-might-we.md` (HMW skip test) and `${CLAUDE_PLUGIN_ROOT}/skills/product-discovery/references/frameworks/ears.md` (EARS skip test).
## Phase summary
| Phase | Purpose | Execution method | Parallelizable with |
| ------------ | --------------------------------------- | ------------------------------------------------------- | -------------------- |
| **Explore** | Build mental model of the codebase | **4–7 parallel `Explore` agents** (one per perspective) | Research |
| **Research** | Fetch live API docs, versions, patterns | **Parallel `researcher` agents** — one per domain | Explore |
| **Plan** | Derive tasks from EARS spec + deps | Orchestrator + `TaskCreate`/`TaskUpdate` | None (needs E+R) |
| **Act** | Implement via parallel `Agent` calls | **All wave tasks in one message**, `run_in_background` | Per dependency graph |
| **Validate** | Verify correctness, quality, security | **4–8 parallel Opus dimension agents** + static tools | Partially |
| **Compound** | Extract lessons from session | Orchestrator + `compound.md` procedure | None (post-merge) |
Subagent counts per phase live in `references/fan-out.md`. Every phase except
Plan and Compound fans out to multiple parallel `Agent` calls launched in **one
message** — current Claude models under-delegate by default, so running a
fan-out phase as a single agent (or inline in the orchestrator thread) is a bug,
not a shortcut.
## Fan-out and grounding are the default, not the exception
Two standing rules govern every session. Both counteract failure modes the
orchestrator falls into when left to its own defaults.
- **Fan out wide, every phase.** Explore, Research, Act waves, and Validate all
launch multiple subagents in parallel in a single message. The targets and the
one-message launch discipline are in `references/fan-out.md`. The orchestrator
coordinates; the subagents do the work.
- **Ground before you build.** No code is written against a library, API, or
version that the Research phase hasn't grounded in current docs first —
Context7 (`resolve-library-id` → `query-docs`) for library work, then the
search MCP fleet per `${CLAUDE_PLUGIN_ROOT}/skills/research/references/search-strategies.md`.
An un-grounded version pin or API surface in `CP-RESEARCH` blocks Plan. See
`references/orchestrator.md` § Research for the mandate.
## When to use ERPAVal
`CL-COMPLEXITY` decides before committing to the full flow.
| Scenario | Classifier verdict |
| ---------------------------------------- | --------------------------------------- |
| Feature touching multiple modules | multi-module → full flow |
| Bug fix in a single file | 1-file-fix → skip ERPAVal |
| Greenfield project setup | multi-module + CL-DIR=empty → skip E |
| Rip-and-replace rebuild | rebuild → full E+R + destructive Wave 1 |
| Refactoring with behavioral preservation | multi-module → full flow |
| Integrating a new dependency or API | multi-module → heavy Research phase |
| Quick script or one-off tool | 1-file-fix → skip ERPAVal |
## `.erpaval/` directory — two-zone layout
Placeholder tokens (`NNN`, `<hex>`, `<slug>`, `<domain>`, `T-AC-X-Y`) are defined in `references/glossary.md`.
```text
.erpaval/
INDEX.md committed — pointer from CLAUDE.md
solutions/ committed — dual-track lessons
<category>/ one folder per entry in
references/solution-categories.yaml
brainstorms/ committed — HMW outputs
NNN-<slug>-requirements.md
specs/ committed — EARS specs + derived tasks.md
NNN-<slug>/
spec.md
tasks.md
sessions/ gitignored — orchestrator-coupled, ephemeral
.nudged persistent ledger of session-ids already
nudged by compound_nudge.py (one line per id)
session-<hex>/
intake.yaml
recall.yaml
explore.yaml
research-<domain>.yaml
tasks/T-AC-X-Y.md
validation.yaml
lessons.yaml
session.yaml
```
Single `.gitignore` line: `.erpaval/sessions/`. The durables compound across team. Session state is orchestrator-coupled (subagent types, tool IDs, task schema) and a secrets surface — archive to object storage if audit is needed.
## Recall + Compound — the compounding loop
Every session starts by reading prior lessons and ends by writing new ones:
- **Session start** — the plugin `SessionStart` hook (`hooks/session_start_bootstrap.py`) emits category counts from `.erpaval/solutions/` as `additionalContext`. Fires once per session; no-ops for projects without `.erpaval/`.
- **Pre-Act** — the orchestrator queries `erpaval-recall.py` per task during Plan → Act, populating each packet's Prior Lessons section via tag / module scoring.
- **Mid-session** — Claude invokes recall ad-hoc when a new sub-problem emerges that prior sessions may have hit.
- **Post-merge** — Compound runs as the sixth phase. CL-LESSONS filters candidates by novelty + reusability. Writes to `solutions/<category>/<slug>.md`, updates `INDEX.md`, adds the CLAUDE.md pointer if missing, records `sessions/<id>/lessons.yaml`. The `Stop` hook (`hooks/compound_nudge.py`) fires a one-shot `decision: block` when all six gates hold (see Tools and hooks table); once fired, the session-id is written to `.erpaval/sessions/.nudged` and won't re-fire.
Compound can also run ad-hoc when the user wants to force-extract lessons mid-session. See `references/compound.md` for the dual-track schema, scoring formula, and operating sequence.
## Ecosystem integration
### Upstream skills (run before ERPAVal)
| Skill | When to use first |
| -------------------------------------------- | -------------------------------------------------------------------------------------- |
| **Product Discovery** (`/product-discovery`) | Define what to build before planning how (PRD drafting, HMW, EARS, user stories, JTBD) |
| **Tech Stack Builder** (`/build-stack`) | Select technologies for greenfield projects |
| **Product Strategy** (`/product-strategy`) | Business strategy frameworks (Rumelt, Wardley, Minto, Working Backwards) |
`CL-SPEC` loops through these automatically if any are missing.
### Phase-level agent mapping
| Phase | Agent used |
| -------- | ------------------------------------------------------------------------------------ |
| Explore | 4–7 parallel built-in `Explore` subagents, one per perspective |
| Research | Parallel plugin `researcher` agents, one per library/domain |
| Act | `general-purpose` subagents (haiku/sonnet/opus per task), all wave tasks in parallel |
| Validate | 4–8 parallel `opus` subagents, one per quality/security dimension |
| Compound | Orchestrator + `compound.md` procedure (invokes opus for CL-LESSONS) |
## Tools and hooks
Hooks live at `hooks/` and are UV-shebang Python scripts built on `framework.py`. All three hooks are fail-open via `framework.run_hook` — any uncaught exception logs to stderr and exits 0, so a broken hook cannot wedge a session.
| Hook | Event | Role |
| ---------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `session_start_bootstrap.py` | SessionStart | Emit `.erpaval/solutions/` category counts via `additionalContext`. Fires once per session and only when a `sessions/session-<hex>/` dir was modified in the last 24h — cold repos stay silent. |
| `validate_packet.py` | PostToolUse | Pydantic schema-check writes under `.erpaval/`. Early-exits on non-erpaval paths. Also drops `/tmp/claude-erpaval-active-<session_id>` as a cross-hook "this Claude session touched ERPAVal" marker. |
| `compound_nudge.py` | Stop | One-shot `decision: block` when Compound is pending. Six gates: erpaval-active marker, `session-<hex>` name, fresh `validation.yaml` (<2h), no `lessons.yaml`, not nudged this session (HookState), not in `.erpaval/sessions/.nudged` persistent ledger. |
Imperative tools under `tools/` — PEP 723 scripts invoked via `uv run` by the orchestrator:
| Tool | Purpose | Invoked by |
| --------------------- | ---------------------------------------------------------------- | ----------------------------- |
| `erpaval-new.py` | Scaffold `.erpaval/sessions/session-<hex>/` + seed `intake.yaml` | Orchestrator at session start |
| `erpaval-recall.py` | Tag-scored grep over `.erpaval/solutions/**.md` | Orchestrator per Act task |
| `erpaval-validate.py` | Pydantic schema check on YAML packet writes (CLI version) | Manual / CI — hook is primary |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!