Help us improve
Share bugs, ideas, or general feedback.
From erpaval
Autonomous software development workflow for Claude Code. Classifiers route scope, complexity, and spec readiness through Explore/Research/Plan/Act/Validate/Compound phases, persisting lessons to `.erpaval/solutions/` for reuse.
npx claudepluginhub theagenticguy/erpaval --plugin erpavalHow this skill is triggered — by the user, by Claude, or both
Slash command
/erpaval:erpavalThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Reference | When to load |
references/classifiers.mdreferences/compound.mdreferences/context-packets.mdreferences/flow.mdreferences/glossary.mdreferences/orchestrator.mdreferences/solution-categories.yamlreferences/validation-playbook.mdreferences/write-protocol.mdtemplates/INDEX.mdtemplates/brainstorms/requirements.mdtemplates/session/explore.yamltemplates/session/intake.yamltemplates/session/lessons.yamltemplates/session/recall.yamltemplates/session/research.yamltemplates/session/session.yamltemplates/session/task-skeleton.mdtemplates/session/validation.yamltemplates/solutions/lesson-bug.mdImplements production AI coding workflows: self-correction loops, pre-flight discipline rules, orchestration patterns, hook events, agents. For Claude Code, Cursor, 32+ agents.
Guides specification-driven AI development workflows by breaking projects into 2-4 hour sessions using 13 commands like /plansession, /implement, /validate, and /phasebuild.
Generates feature specs, implementation plans with task checklists, and project loop infrastructure via interactive user interviews on scope, risk tolerance, and validation.
Share bugs, ideas, or general feedback.
| 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/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/task-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 |
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.
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.
Each phase has a completion gate enforced by TaskCreate / TaskUpdate / TaskList. 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.
Task 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.
Two steps the orchestrator always runs before Explore, so Compound can actually fire at the end of the session.
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.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:
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.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.
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.
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.
[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 | Purpose | Execution method | Parallelizable with |
|---|---|---|---|
| Explore | Build mental model of the codebase | Parallel Agent (Explore subagents — split by module, single message) | Research |
| Research | Fetch live API docs, versions, patterns | Parallel Agent (researcher — split by domain, single message) | Explore |
| Plan | Derive tasks from EARS spec + deps | Orchestrator + TaskCreate/TaskUpdate | None (needs E+R) |
| Act | Implement via parallel Agent calls | One message per wave, all tasks in run_in_background=true | Per dependency graph |
| Validate | Verify correctness, quality, security | Agent tool (Opus) + static tools | Partially |
| Compound | Extract lessons from session | Orchestrator + compound.md procedure | None (post-merge) |
Research agents start with
date +"%Y-%m-%d"(always) andcontext7(for library/API/SDK lookups). Default recency window is the last 6 months — agentic-AI libraries change monthly.
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 layoutPlaceholder tokens (NNN, <hex>, <slug>, <domain>, T-AC-X-Y) are defined in references/glossary.md.
.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.
Every session starts by reading prior lessons and ends by writing new ones:
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/.erpaval-recall.py per task during Plan → Act, populating each packet's Prior Lessons section via tag / module scoring.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.
| 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 | Agent used |
|---|---|
| Explore | Built-in Explore subagent |
| Research | Plugin researcher agent |
| Act | general-purpose subagents (haiku/sonnet/opus per task) |
| Validate | opus subagents for code quality and security review |
| Compound | Orchestrator + compound.md procedure (invokes opus for CL-LESSONS) |
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 |