src/main/resources/targets/claude/skills/core/plan/x-migrate-templates/SKILL.md
Assists migration of a v1 epic document to the v2 value-driven template (EPIC-0070). Parses v1 technical blocks (Packages, Contratos, SOLID, Observabilidade), classifies each block with a safe default heuristic, and optionally asks the operator for confirmation per block (--interactive). Side-effects: writes epic.md in v2 format atomically, creates ADRs for 'virar ADR' decisions, updates system.md via x-update-system-architecture. Supports --dry-run and recovery from interrupted sessions.
npx skillsauth add edercnj/ia-dev-environment x-migrate-templatesInstall 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.
Assists the migration of a v1 epic document (ai/epics/<epic-id>/epic-<epic-id>.md or ai/epics/<epic-id>-*/epic-<epic-id>.md) to the v2 value-driven template introduced in EPIC-0070. The migration is information-preserving — no technical decision from v1 is silently discarded.
/x-migrate-templates <epic-id> — migrate the epic to v2 (non-interactive by default — applies safe heuristics automatically)/x-migrate-templates <epic-id> --interactive — migrate with per-block confirmation prompts/x-migrate-templates <epic-id> --dry-run — preview diff and classification without writing| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| EPIC-ID | String | Yes | — | 4-digit zero-padded epic identifier (e.g., 0050). Also accepts full form epic-0050. |
| --interactive | Boolean | No | false | Show per-block confirmation prompts (AskUserQuestion). Default is non-interactive (Rule 20 — EPIC-0061). |
| --dry-run | Boolean | No | false | Show diff + simulated answers (default: "manter") without writing any files. |
| --non-interactive | Boolean | No | DEPRECATED | Emits WARN; equals default behavior. Removed in 2 releases. |
| --resume | Boolean | No | false | Resume from a previous interrupted session state-file at .claude/state/template-migrate-<epic-id>.json. |
EPIC-ID from argv (strip epic- prefix if present, zero-pad to 4 digits).ai/epics/epic-<EPIC-ID>*/. If not found, abort with EPIC_DIR_MISSING.ai/epics/epic-<EPIC-ID>*/epic-<EPIC-ID>.md.## 3. Hipótese & OKRs or ## Refinement Verdict block → already v2. Exit 0 with: INFO: epic already in v2 — nothing to do.--resume flag is set, load state from .claude/state/template-migrate-<EPIC-ID>.json:
originalHash matches SHA-256 of current epic.md content. Mismatch → abort with EXTERNAL_EDIT_DETECTED.decisions[] (blocks already processed), set resume point.Parse the v1 epic markdown and extract the following technical block types:
| v1 Block Pattern | Detected By |
|------------------|-------------|
| Packages / Hexagonal | ## Packages, ## Arquitetura, section containing package paths |
| Contratos / Endpoints | ## Contratos, ## API, ## Endpoints |
| SOLID principles | ## SOLID, ## Princípios, section referencing SRP/OCP/LSP/ISP/DIP |
| Observabilidade | ## Observabilidade, ## Métricas, ## Logs |
| Segurança técnica | ## Segurança, ## Security, ## PCI |
| Decisões inline | Any section containing **Decisão:**, **ADR:**, decisão arquitetural |
| Outros blocos | Any remaining section not mapped to v2 structure |
If a section fails to parse (e.g., malformed markdown, unclosed code fence), abort with:
ERROR PARSER_ERROR: section "<heading>" at line <N> could not be parsed.
Epic.md NOT modified — state preserved.
For each extracted block, apply classification heuristics:
| Block Type | Default Classification | Reasoning |
|------------|----------------------|-----------|
| Packages / Hexagonal | move-to-system-md → §1-3 (Stack/Persistência/Comunicação) | Architectural topology belongs in system.md |
| Contratos / Endpoints | move-to-system-md → §3 (Integrações) | Interface contracts persist beyond a single epic |
| SOLID | discard | Governed by Rule 03/04 — always applicable, no per-epic value |
| Observabilidade | move-to-system-md → §4 (Decisões de Observabilidade) | SLO/alert decisions are cross-epic |
| Segurança técnica | move-to-system-md → §2 (Segurança) or create-adr | Security decisions warrant ADR when novel |
| Decisões inline | create-adr | Inline decisions are best canonicalized as formal ADRs |
| Outros blocos | keep-in-epic | Unknown content defaults to preservation |
Classification result for each block includes: { type, content, classification, targetSection, rationale }.
--interactive)When --interactive is active, for each classified block:
AskUserQuestion(question: "Block: <heading>\nContent preview: <first 3 lines>\nProposed: <classification> → <targetSection>\n[1] Accept [2] Override: move-to-system-md [3] Override: create-adr [4] Override: keep-in-epic [5] Discard")
Persist each confirmed decision to the state-file immediately after confirmation.
When not --interactive (default): apply heuristics without prompting. Print a summary table of classifications at the end.
Status: tbd (placeholder — run /x-refine-epic to refine)epic-<EPIC-ID>.md.tmp.ai/epics/epic-<EPIC-ID>*/reports/migration-log-epic-<EPIC-ID>.md.If --dry-run: print the composed v2 document as a diff preview. Skip all writes. Exit 0.
Execute side-effects for blocks classified as move-to-system-md or create-adr:
move-to-system-md blocks:
Skill(skill: "x-update-system-architecture", model: "sonnet", args: "<EPIC-ID>") [conditional: not flag.dry_run]
create-adr blocks: Write a new ADR file at docs/adr/ADR-NNNN-<slug>.md (next available ADR number) with the extracted decision content. ADR number is determined by scanning existing docs/adr/ADR-*.md files.
If any side-effect fails, log a WARNING but do not roll back the already-written epic v2 (atomicity scoped to epic.md only; side-effects are idempotent and re-runnable).
Remove .claude/state/template-migrate-<EPIC-ID>.json on successful completion (session no longer needed). On failure, preserve state-file for --resume.
State-file schema at .claude/state/template-migrate-<EPIC-ID>.json:
{
"epicId": "epic-<EPIC-ID>",
"originalHash": "<sha256-of-v1-epic-md>",
"startedAt": "<ISO-8601>",
"decisions": [
{ "block": "<heading>", "classification": "<type>", "targetSection": "<opt>", "confirmedAt": "<ISO-8601>" }
],
"resumePoint": "<heading-of-next-unprocessed-block>"
}
Re-invocation with --resume loads this state, verifies originalHash, and continues from resumePoint.
| Code | Condition |
|------|-----------|
| EPIC_DIR_MISSING | ai/epics/epic-<ID>*/ not found |
| PARSER_ERROR | v1 section is malformed; file not written |
| EXTERNAL_EDIT_DETECTED | epic.md changed since session started (hash mismatch) |
# Default non-interactive migration (apply heuristics, no prompts)
/x-migrate-templates 0050
# Interactive migration with per-block confirmation
/x-migrate-templates 0050 --interactive
# Dry-run — preview diff without writing
/x-migrate-templates 0050 --dry-run
# Resume an interrupted session
/x-migrate-templates 0050 --resume
# Full epic-id form also accepted
/x-migrate-templates epic-0036 --interactive
x-update-system-architecture (story-0070-0006) for move-to-system-md side-effects — Rule 13 INLINE-SKILL.pr-watch-*.json pattern (Rule 45) for session persistence.--non-interactive is deprecated; non-interactive is the default./help./x-refine-epic epic-<ID> to obtain refinementVerdict.status = approved for the migrated epic.development
Documentation freshness gate: validates 6 dimensions (readme, api, adr, etc.) per PR.
testing
Conditional dep-policy gate: CVEs, licenses, versions, freshness; SARIF + report.
documentation
Incrementally updates the service or system architecture document; never regenerative.
development
Scans code and git history for leaked credentials, API keys, and tokens; SARIF output.