java/src/main/resources/targets/claude/skills/core/plan/x-epic-decompose/SKILL.md
Complete decomposition of a system specification into an Epic, individual Story files, and an Implementation Map with dependency graph and phased execution plan. Orchestrates spec analysis, rule extraction, story identification, and implementation planning.
npx skillsauth add edercnj/claude-environment x-epic-decomposeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Orchestrate the full decomposition of a system specification into three deliverables: an Epic, individual Stories, and an Implementation Map. Coordinate the work of three focused skills, each handling one deliverable.
x-epic-create, x-story-create, or x-epic-map skills when all three deliverables are neededRead these files before starting:
Templates (output structure) — read all three:
.claude/templates/_TEMPLATE-EPIC.md (RA9 v2: 9 sections).claude/templates/_TEMPLATE-STORY.md (RA9 v2: 9 sections).claude/templates/_TEMPLATE-IMPLEMENTATION-MAP.mdRA9 planning contract (source of truth for 9-section model):
.claude/skills/planning-standards-kp/SKILL.md — Defines all 9 RA9 sections, granularity per level (Epic/Story/Task), Packages catalog format, and Decision Rationale micro-template. Read before generating Sections 2 and 8.Decomposition philosophy:
references/decomposition-guide.md (bundled with this skill)If any template is missing, stop and tell the user.
RA9 guidance (EPIC-0056): For each generated Epic and Story, explicitly fill:
- Section 2 (Packages Hexagonal): Map packages from spec analysis to the 5 hexagonal layers. Propagate epic-level catalog as subsets to each story.
- Section 8 (Decision Rationale): Extract architectural decisions. Minimum 1 item per Epic/Story using the 4-line micro-template. Task accepts
N/A — <reason>.
P1. DETECT -> x-git-worktree detect-context (EPIC-0049 / RULE-001, inline)
P2. ENSURE BRANCH -> x-internal-epic-branch-ensure --epic-id XXXX (RULE-001, inline)
1. ANALYSIS -> Read spec, identify rules, stories, dependencies, phases (inline)
1.5. JIRA -> Determine Jira integration mode (conditional, inline)
2. EPIC -> Generate Epic file with rules, story index, DoR/DoD (inline)
3. STORIES -> Generate one story file per story with contracts, Gherkin, sub-tasks (inline)
4. MAP -> Generate Implementation Map with dependency graph, phases, critical path (inline)
4.5. JIRA LINKS -> Create Jira dependency links (conditional, inline)
P4. CONSOLIDATED -> x-planning-commit --scope chore --subject "full decomposition (...)" (RULE-007, inline)
P5. PUSH -> x-git-push --branch epic/XXXX (optional, inline)
5. REPORT -> Save all files, validate quality, report summary (inline)
Per story-0049-0021 Section 3.2, x-epic-decompose uses a single consolidated commit in Step P4 covering the full batch (epic + N stories + implementation map) rather than letting each sub-skill (x-epic-create, x-story-create, x-epic-map) commit individually. The sub-skills are called in this orchestrator with their own --dry-run effectively set — they WRITE the artifacts but do NOT invoke their own P4 / P5 steps (the orchestrator owns the commit). This yields git log --oneline containing one audit-trail entry per decomposition instead of N+2, matching the operator expectation that x-epic-decompose foo --spec bar.md is a single logical mutation.
Before generating anything, read references/decomposition-guide.md. It explains the
layer-by-layer approach that drives the entire decomposition:
The guide also covers:
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-P1-Worktree-Detect
Invoke x-git-worktree detect-context so subsequent phases know whether the current checkout is already inside an epic worktree.
Skill(skill: "x-git-worktree", args: "detect-context")
Fail-open (RULE-006): any detect-context failure is logged and Phase P2 proceeds.
<!-- TELEMETRY: phase.end -->Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-P1-Worktree-Detect ok
epic/<ID> Branch (EPIC-0049 / RULE-001)Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-P2-Epic-Branch-Ensure
Resolve the effective epic ID (next-available auto-increment when not supplied, as in Phase 2 below), then ensure the canonical epic/<ID> branch exists locally AND on origin:
Skill(skill: "x-internal-epic-branch-ensure", args: "--epic-id <XXXX>")
Abort with EPIC_BRANCH_ENSURE_FAILED on any non-zero exit — a consolidated audit trail cannot be produced without the canonical branch.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-P2-Epic-Branch-Ensure ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-1-Analysis
references/decomposition-guide.mdBash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-1-Analysis ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-1_5-Jira-Decision
Before generating any artifacts, determine if Jira integration is desired.
Verify that the Jira MCP tool (mcp__atlassian__createJiraIssue) is available.
If the tool is NOT available, set jiraContext = { enabled: false } and skip to
Phase 2 silently — do not warn the user.
Antes de prompt ao usuario, verificar as flags de Jira:
Se --no-jira estiver presente: definir jiraContext = { enabled: false } e pular
para a Phase 2. Log: "Jira integration skipped (--no-jira, EPIC-0042)"
Se --jira <PROJECT_KEY> estiver presente: usar a chave de projeto fornecida
diretamente. Pular AskUserQuestion (Step 1.5.2). Descobrir o cloudId chamando
mcp__atlassian__getAccessibleAtlassianResources. Usar o id do primeiro site
disponivel como cloudId. Se a chamada falhar ou nao retornar sites, alertar o
usuario e definir jiraContext = { enabled: false }. Caso contrario, definir
jiraContext = { enabled: true, cascadeToStories: true, projectKey: "<PROJECT_KEY>", cloudId: "<cloudId>" }.
Log: "Jira integration via --jira flag: project {PROJECT_KEY}, cascade to stories (EPIC-0042)"
Pular para a Phase 2.
Se nenhuma flag estiver presente: prosseguir para o Step 1.5.2 (prompt interativo compativel com a versao anterior).
Use the AskUserQuestion tool:
question: "Deseja criar o épico e as histórias no Jira?"
header: "Jira"
options:
- label: "Sim, criar tudo no Jira"
description: "Criar o épico e TODAS as histórias como issues no Jira automaticamente via MCP"
- label: "Apenas o épico no Jira"
description: "Criar somente o épico no Jira. As histórias serão apenas markdown"
- label: "Não, apenas markdown"
description: "Gerar apenas os arquivos markdown sem integração com Jira"
multiSelect: false
Based on user selection:
"Sim, criar tudo no Jira":
question: "Qual a chave do projeto Jira? (ex: PROJ, MYAPP, TEAM)"
header: "Projeto"
cloudId by calling mcp__atlassian__getAccessibleAtlassianResources.
Use the first available site's id as the cloudId. If the call fails or returns
no sites, warn the user and set jiraContext = { enabled: false }.jiraContext = { enabled: true, cascadeToStories: true, projectKey: "<key>", cloudId: "<cloudId>" }"Apenas o épico no Jira":
cloudId (same as above)jiraContext = { enabled: true, cascadeToStories: false, projectKey: "<key>", cloudId: "<cloudId>" }"Não, apenas markdown":
jiraContext = { enabled: false }The jiraContext is passed to all subsequent phases and used to control Jira issue creation.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-1_5-Jira-Decision ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-2-Epic
Follow the instructions in .claude/skills/x-epic-create/SKILL.md:
plans/ for existing epic-XXXX folders, use next available; default 0001)plans/epic-XXXX/story-XXXX-YYYY IDs)plans/epic-XXXX/epic-XXXX.md following _TEMPLATE-EPIC.mdJira Integration (if jiraContext.enabled == true):
After generating the Epic markdown file:
mcp__atlassian__createJiraIssue to create an Epic issue:
cloudId: jiraContext.cloudIdprojectKey: jiraContext.projectKeyissueTypeName: "Epic"summary: The Epic title (from the generated header)description: The "Visão Geral" section textcontentFormat: "markdown"additional_fields: { "labels": [{ "name": "generated-by-ia-dev-env" }, { "name": "epic-XXXX" }] } (where epic-XXXX is the local ID for bidirectional sync)jiraContext.epicIssueKey with the returned key<CHAVE-JIRA> in the generated Epic markdown with the actual Jira key<CHAVE-JIRA> to EPIC-XXXX (Jira: falha na criação),
leave jiraContext.epicIssueKey absent (do NOT set it to an empty string or invalid value),
and continue. In Phase 3, stories will be created without a parent link when
jiraContext.epicIssueKey is absent, maintaining non-blocking behaviorIf jiraContext.enabled == false: replace <CHAVE-JIRA> with — in the Epic markdown.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-2-Epic ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-3-Stories
Follow the instructions in .claude/skills/x-story-create/SKILL.md:
For each story in the Epic's index:
[Dev], [Test], [Doc] — MUST include at least one [Test] Smoke/E2E sub-taskGenerate files as plans/epic-XXXX/story-XXXX-YYYY.md following _TEMPLATE-STORY.md.
Jira Integration (if jiraContext.cascadeToStories == true):
Pass jiraContext to the story generation logic. For each generated story:
mcp__atlassian__createJiraIssue to create a Story issue:
cloudId: jiraContext.cloudIdprojectKey: jiraContext.projectKeyissueTypeName: "Story"summary: The story titledescription: The user story text from Section 3 (the "Como Persona..." paragraph)contentFormat: "markdown"parent: jiraContext.epicIssueKey (links the story to the parent epic) — include only if jiraContext.epicIssueKey is present; omit entirely when absentadditional_fields: { "labels": [{ "name": "generated-by-ia-dev-env" }, { "name": "story-XXXX-YYYY" }] } (where story-XXXX-YYYY is the local story ID for bidirectional sync)<CHAVE-JIRA> in the story markdown with the returned Jira key<CHAVE-JIRA> to —, continue with remaining storiesIf jiraContext.cascadeToStories == false or jiraContext.enabled == false:
replace <CHAVE-JIRA> with — in all story markdowns.
No additional AskUserQuestion is needed — the cascade decision was already made in Phase 1.5.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-3-Stories ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-4-Map
Follow the instructions in .claude/skills/x-epic-map/SKILL.md:
Generate plans/epic-XXXX/IMPLEMENTATION-MAP.md following _TEMPLATE-IMPLEMENTATION-MAP.md.
If Jira keys are available (from Phase 3), include them in the dependency matrix's
Chave Jira column.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-4-Map ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-4_5-Jira-Links
If jiraContext.enabled == true and jiraContext.cascadeToStories == true, and all
stories have Jira keys:
mcp__atlassian__createIssueLink:
cloudId: jiraContext.cloudIdtype: "Blocks"inwardIssue: the blocker's Jira key (the issue that blocks)outwardIssue: the current story's Jira key (the issue that is blocked)If linking fails for some stories, log warnings but do not fail the pipeline. This step is best-effort — Jira links are a convenience, not a hard requirement.
<!-- TELEMETRY: phase.end -->Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-4_5-Jira-Links ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-P4-Consolidated-Commit
If --dry-run is set, log "dry-run, skipping commit" and skip this phase entirely.
Otherwise, collect the full path set produced by Phases 2, 3, and 4 (epic file + all story files + implementation map + any templates newly written) and issue a single consolidated commit via x-planning-commit:
Skill(skill: "x-planning-commit",
args: "--scope chore --epic-id <XXXX> --paths plans/epic-<XXXX>/epic-<XXXX>.md,plans/epic-<XXXX>/story-<XXXX>-0001.md,...,plans/epic-<XXXX>/IMPLEMENTATION-MAP.md --subject \"full decomposition (epic + <N> stories + map)\"")
Rationale for consolidation over per-sub-skill commits (see Workflow Overview note above): the operator experiences x-epic-decompose as one logical mutation; history reads as chore(epic-XXXX): full decomposition (epic + 22 stories + map) rather than 24 interleaved commits.
Idempotency: re-running an identical decomposition yields commitSha=null + noOp=true from x-planning-commit. No additional diff check is required in this phase.
On COMMIT_FAILED (exit 4 from x-planning-commit), abort with the same error code.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-P4-Consolidated-Commit ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-P5-Push
If --dry-run is set, log "dry-run, skipping push" and skip.
Otherwise, push the canonical epic branch so the full decomposition is observable on origin:
Skill(skill: "x-git-push", args: "--branch epic/<XXXX>")
On push failure, log a WARNING and continue. Do NOT abort — the local commit is preserved.
<!-- TELEMETRY: phase.end -->Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-P5-Push ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-epic-decompose Phase-5-Report
All files are saved inside plans/epic-XXXX/ (the epic's dedicated folder).
Report summary:
If Jira integration was active, also report:
<PROJECT_KEY>)<JIRA-KEY> (or "falha" if failed)Before reporting, validate that all generated artifacts meet these quality gates:
[Test] Smoke/E2E in Section 8**Status:** Pendente field in the headerepic-XXXX) for bidirectional syncstory-XXXX-YYYY) for bidirectional syncIf any story fails validation, fix it before saving. Do not skip validation.
<!-- TELEMETRY: phase.end -->Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-epic-decompose Phase-5-Report ok
Cenario, DADO, QUANDO, ENTÃO, E, MAS| Scenario | Action |
|----------|--------|
| Spec file not found or empty | Abort with message: Spec file not found or is empty. Provide a valid path. |
| Template file missing (_TEMPLATE-EPIC.md, _TEMPLATE-STORY.md, or _TEMPLATE-IMPLEMENTATION-MAP.md) | Stop and tell the user which template is missing |
| Jira MCP tool unavailable | Set jiraContext = { enabled: false }, skip Jira integration silently |
| Jira Epic creation fails | Warn the user, set <CHAVE-JIRA> to EPIC-XXXX (Jira: falha na criacao), continue |
| Jira Story creation fails for a story | Warn, set <CHAVE-JIRA> to — for that story, continue with remaining stories |
| Circular dependency detected in story graph | Abort with message listing the cycle and affected stories |
| Story fails quality validation (Phase 5) | Fix the story before saving — do not skip validation |
| x-internal-epic-branch-ensure fails (Phase P2) | Abort with EPIC_BRANCH_ENSURE_FAILED; canonical branch is required for the consolidated commit |
| x-planning-commit exit 4 (Phase P4) | Abort with COMMIT_FAILED; artifacts written but not versioned |
| x-planning-commit exit 0 + noOp=true (Phase P4) | Silent no-op — re-execution idempotency confirmed; continue to Phase P5 |
| x-git-push fails (Phase P5) | WARN only; local commit preserved; operator re-runs manually |
| --dry-run set | Phases P4 and P5 become no-ops with log line "dry-run, skipping commit" / "dry-run, skipping push" |
This skill requires all three templates (_TEMPLATE-EPIC.md, _TEMPLATE-STORY.md, _TEMPLATE-IMPLEMENTATION-MAP.md). Unlike other orchestrators, there is no graceful fallback — missing templates halt execution because the output format is strictly defined.
Before delivering, verify:
| Skill | Relationship | Context |
|-------|-------------|---------|
| x-epic-create | Delegates to | Phase 2 follows x-epic-create/SKILL.md instructions for Epic generation |
| x-story-create | Delegates to | Phase 3 follows x-story-create/SKILL.md instructions for Story generation |
| x-epic-map | Delegates to | Phase 4 follows x-epic-map/SKILL.md instructions for Implementation Map |
| x-epic-implement | Followed by | Generated artifacts are consumed by epic implementation |
| x-task-implement | Followed by | Individual stories can be implemented via /x-task-implement |
| _TEMPLATE-EPIC.md | Reads | Output format for Epic file |
| _TEMPLATE-STORY.md | Reads | Output format for Story files |
| _TEMPLATE-IMPLEMENTATION-MAP.md | Reads | Output format for Implementation Map |
| references/decomposition-guide.md | Reads | Decomposition philosophy and layer-by-layer approach |
| mcp__atlassian__createJiraIssue | Calls (conditional) | Jira Epic and Story creation when jiraContext.enabled |
| mcp__atlassian__createIssueLink | Calls (conditional) | Jira dependency linking in Phase 4.5 |
| x-git-worktree | Calls (Phase P1) | Detect-context (EPIC-0049 / RULE-001) |
| x-internal-epic-branch-ensure | Calls (Phase P2) | Ensure epic/<ID> exists locally + origin (EPIC-0049 / RULE-001) |
| x-planning-commit | Calls (Phase P4) | Single consolidated commit (epic + N stories + map) without code pre-commit chain (EPIC-0049 / RULE-007) |
| x-git-push | Calls (Phase P5) | Push canonical epic branch to origin (optional) |
V2-gated: only runs when the decomposed epic declares
planningSchemaVersion: "2.0"(seeded into the generatedexecution-state.json). For v1 epics: skip silently (Rule 19).
x-epic-decompose produces (a) the epic, (b) N story files, and (c) the implementation-map-XXXX.md. Lifecycle semantics:
Em Refinamento → Pendente at the end of decomposition (decomposition is complete, ready for planning).**Status:** Pendente (they start unplanned).Planejamento column is populated with the literal value Pendente for every story row (template token {{PLANNING_STATUS}} resolved at render-time to the real string Pendente).Steps (final phase of decomposition, before the commit):
Detect v2 via the epic's seeded execution-state.json. If v1: skip.
For the epic file, transition its status:
java -cp $CLAUDE_PROJECT_DIR/java/target/classes \
dev.iadev.adapter.inbound.cli.StatusFieldParserCli \
write plans/epic-XXXX/epic-XXXX.md Pendente
Note: LifecycleTransitionMatrix does NOT currently list Em Refinamento (it is a pre-lifecycle marker). If the CLI returns exit 40 because the current status is Em Refinamento (not in the 6-value enum), treat that as the accepted initial state and proceed: re-invoke with a direct file edit fallback (sed-replace the line) when and only when the current literal is Em Refinamento. Otherwise respect exit 40 and abort.
For each generated story file, verify the literal **Status:** Pendente is present (StatusFieldParserCli read returns Pendente). Exit 0 required per story; exit 20 on any story aborts the decomposition.
In the implementation-map-XXXX.md template, replace every {{PLANNING_STATUS}} placeholder with Pendente.
Stage the epic, all stories, and the implementation map; commit with x-git-commit:
Skill(skill: "x-git-commit", args: "docs(epic-XXXX): decompose — epic Pendente, N stories, implementation map")
Fail-loud: any story missing or malformed → abort (RULE-046-08).
tools
Documentation automation v2: stack-aware generation from documentation.targets.
development
Generates or updates CI/CD pipelines per project stack with actionlint validation.
tools
Generates ADRs from architecture-plan mini-ADRs with sequential numbering and index update.
development
Formats source code; first step of the pre-commit chain (format -> lint -> compile).