---
name: spec-driven-migration
description: >
  Reference-sweep migration workflow for the DevForgeAI dual-path codebase.
  Replaces every occurrence of a `from_pattern` with a `to_pattern` across a
  defined corpus via 4-layer anti-skip enforcement: classify-first, dual-path
  identical edits, fresh-context cluster workers, and global verification.
  Encodes the playbook proven on PR #68 (source-tree.md → source-tree/, 324
  files, 0 dual-path drift). Use when `/migrate-refs` is invoked, when a framework
  rename / retirement / library swap needs to land across many dual-path files,
  or when the user mentions a reference-sweep migration. Do NOT use for
  audit-finding-driven cleanup (use spec-driven-remediation) or general code
  refactoring without a defined from/to pattern.
metadata:
  author: DevForgeAI
  version: "1.0.0"
  category: framework-maintenance
  agent-skills-spec-version: "1.0"
  last-updated: "2026-05-20"
  derived-from: spec-driven-remediation v2.0.0 (structural sibling)
allowed-tools:
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - Task
  - AskUserQuestion
  - Bash(devforgeai-validate:*)
  - Bash(git:*)
  - Bash(diff:*)
model: opus
effort: High
---

# Spec-Driven Migration

Replace every occurrence of a `from_pattern` with a `to_pattern` across a defined
file scope, preserving the framework's dual-path (`.claude/` ↔ `src/claude/`)
byte-identity, with phase-enforced classification, parallel cluster workers, and
global verification. Every step uses Execute-Verify-Record to prevent token
optimization bias from skipping phases.

**The migration intent (from/to pattern + scope + exclusions) is the input. A
clean, dual-path-byte-identical codebase + a verifiable migration report is the
output. User approval gates every classification cutover and the final commit.**

**If ambiguous or conflicts detected: HALT and use AskUserQuestion**

---

## Execution Model

See **`.claude/rules/core/anti-skip-behavior.md`** for the canonical execution contract (expand inline; do not wait passively or offer execution options; honor every step of every phase; Self-Check violation taxonomy; Token-Optimization-Bias prohibition; governed by ADR-076). After invocation, execute Phase State Initialization immediately.

---

## Anti-Skip Enforcement Contract

Enforced structurally outside LLM control, not by this prose — by the framework's deterministic gates wired for this workflow: the `devforgeai-validate` phase gates, the `settings.json`-registered `.claude/hooks/` scripts, and `.claude/hooks/phase-steps-registry.json` (ADR-076). Behavioral residue: `.claude/rules/core/anti-skip-behavior.md`.

---

## Parameter Extraction

Extract parameters from conversation context markers set by `/migrate-refs`
command. See `references/parameter-extraction.md` for the extraction algorithm.

## Command Integration

| Context Marker | Set By | Description |
|----------------|--------|-------------|
| `$MIGRATION_ID` | /migrate-refs | Kebab-case session ID (e.g. `source-tree-2026-05-19`); resolves `tmp/${MIGRATION_ID}/` |
| `$FROM_PATTERN` | /migrate-refs | The literal string the migration replaces |
| `$TO_PATTERN` | /migrate-refs | The replacement (may carry a type-change signal — file/folder/CLI) |
| `$SCOPE` | /migrate-refs | Glob or directory list defining the migration corpus |
| `$EXCLUSIONS` | /migrate-refs | Path patterns to skip outright (templates, archives, historical) |
| `$DRY_RUN` | /migrate-refs | true = classification + transform-rules only, no edits |

---

## Phase State Initialization [MANDATORY FIRST]

Derive SESSION_ID from the migration ID:
```
SESSION_ID = "MIG-" + ${MIGRATION_ID}
# Example: "MIG-source-tree-2026-05-19"
```

```bash
devforgeai-validate phase-init ${SESSION_ID} --workflow=migration --project-root=.
```

| Exit Code | Meaning | Action |
|-----------|---------|--------|
| 0 | New workflow | State file created. Set CURRENT_PHASE = "00". |
| 1 | Existing workflow | Resume. Check checkpoint file for CURRENT_PHASE. |
| 2 | Invalid session ID OR unregistered workflow | HALT. If "unknown workflow", the CLI's WORKFLOW_SCHEMAS registry needs the `migration` entry (see [[project_research_workflow_cli_gap]] precedent — register and re-run). |
| 127 | CLI not installed | Continue without enforcement (backward compatibility). |

**Resume Detection:** If resuming, read checkpoint:
```
Read(file_path="{project-root}/tmp/.migration-checkpoint-${SESSION_ID}.yaml")
```
Extract `current_phase` and `phase_completion` to determine where to resume.

---

## Phase Orchestration Loop

```
FOR phase_num in range(CURRENT_PHASE, 07):
    phase_id = format(phase_num, "02d")

    1. ENTRY GATE: devforgeai-validate phase-check ${SESSION_ID} --workflow=migration --from={prev} --to={phase_id}
       IF exit != 0: HALT

    2. LOAD: Read(file_path="phases/{phase_files[phase_id]}")

    3. EXECUTE: Follow every step in the phase file (EXECUTE-VERIFY-RECORD triplets)
       - Each step's EXECUTE instruction tells you exactly what to do
       - Each step's VERIFY instruction tells you how to confirm it happened
       - Each step's RECORD instruction tells you what CLI command to call
       - Phase 02 and Phase 04 DELEGATE to subagents — invoke via Task(); do NOT inline their work

    4. RECORD: devforgeai-validate phase-record ${SESSION_ID} --workflow=migration --phase={phase_id}

    5. EXIT GATE: devforgeai-validate phase-complete ${SESSION_ID} --workflow=migration --phase={phase_id} --checkpoint-passed
       IF exit != 0: HALT
```

**Dry-Run Pass-Through:** If `$DRY_RUN == true`, the workflow runs all 6 phases (00→05)
sequentially with **no skip**. Phase 03 Step 3.3 writes `clusters.json` as `[]` (empty
array). Phase 04 invokes the cluster worker on the empty array — the worker honestly
reports "0 clusters to process" — and the phase advances normally. Phase 05 produces
WOULD-EDIT and WOULD-RESOLVE reports instead of live edits, ending with
`Verdict: DRY-RUN-COMPLETE`. Phase 06's Entry Gate halts on that verdict, leaving the
workflow at 6/7 completed phases — **this is the correct terminal state for a dry-run**.
No filesystem mutation occurs.

| Phase | Name | File | Mode |
|-------|------|------|------|
| 00 | Context Loading + Resume Detection | `phases/phase-00-context-loading.md` | INLINE |
| 01 | Scope & Intent | `phases/phase-01-scope-and-intent.md` | INLINE (interactive) |
| 02 | Classification | `phases/phase-02-classification.md` | DELEGATE → `migration-classifier` |
| 03 | Transform-Rules + Design-Sensitive Triage + Cluster Planning | `phases/phase-03-rules-and-triage.md` | INLINE (interactive) |
| 04 | Cluster Execution | `phases/phase-04-cluster-execution.md` | DELEGATE × N (parallel) → `migration-cluster-worker` |
| 05 | Global Verification | `phases/phase-05-verification.md` | INLINE |
| 06 | Commit & Memory | `phases/phase-06-commit.md` | INLINE |

---

## State Persistence

**Phase State:** `devforgeai/workflows/${SESSION_ID}-migration-phase-state.json`
**Session Memory:** `.claude/memory/sessions/${SESSION_ID}-migration-session.md`
**Checkpoint:** `{project-root}/tmp/.migration-checkpoint-${SESSION_ID}.yaml`
**Migration artifacts:** `tmp/${MIGRATION_ID}/` — `intent.json`, `classification.md`, `transform-rules.md`, `clusters.json`, `session.md`
**References:** `references/parameter-extraction.md`, `assets/templates/checkpoint-template.yaml`

---

## Workflow Completion Validation

```
# Dry-run terminal state: completed_count = 6 (Phase 06 intentionally halts on DRY-RUN-COMPLETE verdict)
# Real-run terminal state: completed_count = 7

IF intent.dry_run == true:
    IF completed_count < 6: HALT "DRY-RUN INCOMPLETE - {completed_count}/6 phases"
    IF completed_count == 6: "Dry-run complete (6/6 phases through verification) - Migration NOT committed"
ELSE:
    IF completed_count < 7: HALT "WORKFLOW INCOMPLETE - {completed_count}/7 phases"
    IF completed_count == 7: "All 7 phases completed - Migration workflow passed"
```

---

## Success Criteria

- [ ] `tmp/${MIGRATION_ID}/intent.json` captured (from_pattern, to_pattern, scope, exclusions, to_type)
- [ ] `tmp/${MIGRATION_ID}/classification.md` produced by `migration-classifier`; every occurrence bucketed
- [ ] `tmp/${MIGRATION_ID}/transform-rules.md` authored by orchestrator + user; covers every bucket
- [ ] Design-sensitive files identified and handled INLINE by the orchestrator (logic rewrites, not noun-swaps)
- [ ] Files partitioned into N clusters; `tmp/${MIGRATION_ID}/clusters.json` records the partition
- [ ] N parallel `migration-cluster-worker` invocations succeeded; every reported pair is `diff`-empty
- [ ] Global residual grep shows ZERO live `from_pattern` hits classified as transformable; every residual is intentional (DOC-historical / ALREADY-MIGRATED / EXCLUDED / FLAGGED-type-sensitive)
- [ ] Type-change-risk sites flagged by workers were hand-resolved by the orchestrator (or deferred to a documented follow-up phase)
- [ ] Final commit excludes the standing working-tree noise pattern (`settings.local.json`, `agent-memory/MEMORY.md`, `logs/`, `conviction-evidence`)
- [ ] No files modified without user approval (--dry-run respected)

---

## Reference Files

### Phase Execution (phases/ directory)

| File | Phase |
|------|-------|
| phase-00-context-loading.md | Context Loading + Resume Detection |
| phase-01-scope-and-intent.md | Scope & Intent (interactive) |
| phase-02-classification.md | Classification (delegates to migration-classifier) |
| phase-03-rules-and-triage.md | Transform-Rules + Design-Sensitive Triage + Cluster Planning |
| phase-04-cluster-execution.md | Parallel Cluster Execution (delegates to migration-cluster-worker × N) |
| phase-05-verification.md | Global Verification |
| phase-06-commit.md | Commit & Memory |

### Supporting References (references/ directory)

| File | Purpose |
|------|---------|
| transform-rules-schema.md | Canonical schema for `tmp/<id>/transform-rules.md` — per-bucket transformation grammar + type-change-bug declaration field |
| classification-bucket-catalog.md | Bucket definitions, recognition heuristics, transformation table — the SSOT loaded by Phase 02 + 03 + 04 |
| dual-path-protocol.md | The byte-identical rule + verification commands + dual-path mirror map |
| cluster-partitioning.md | Heuristics for partitioning N files into K clusters (rule-of-thumb sizes, uneven-scope handling) |
| type-change-bug-flagging.md | The trap catalog (Glob `*.md`, `[ -f ]`, "section of X", redirected Read) + the flagging protocol workers follow |
| verification-protocol.md | Residual-grep classification + revert-test pattern + how to interpret cluster-worker reports |
| parameter-extraction.md | `/migrate-refs` context-marker resolution + artifact-directory lookup |

### Subagents (terminal workers)

| Agent | Phase | Role |
|-------|-------|------|
| `migration-classifier` | 02 | Read-only; emits `classification.md` |
| `migration-cluster-worker` | 04 (×N parallel) | Dual-path identical edits per cluster |

### Templates (assets/templates/ directory)

| File | Purpose |
|------|---------|
| checkpoint-template.yaml | Migration checkpoint YAML structure |
| intent-template.json | `intent.json` structure (from_pattern, to_pattern, scope, exclusions, to_type) |
| transform-rules-template.md | Empty `transform-rules.md` the orchestrator + user populate |
| migration-report-template.md | Final migration report Markdown template |
