# Phase 02 — Classification

**Mode:** DELEGATE → `migration-classifier` (terminal worker, fresh context).
**Workflow CLI param:** `--workflow=migration`.
**Inputs (must exist on entry):** `tmp/${MIGRATION_ID}/intent.json` (from Phase 01).
**Outputs (must exist on exit):** `tmp/${MIGRATION_ID}/classification.md` + user-confirmed bucket counts recorded in checkpoint.

---

## Entry Gate [MANDATORY]

```bash
devforgeai-validate phase-check ${SESSION_ID} --workflow=migration --from=01 --to=02
```
IF exit != 0: HALT — Phase 01 incomplete or skipped.

---

## Reference Loading [MANDATORY]

```
# No required references for this phase. Phase 02 reads the workflow's
# intent.json artifact (written by Phase 01) and then delegates 100% of
# the bucket classification to the migration-classifier subagent via a
# single Task() call. The subagent runs in fresh context and loads its
# own bucket catalog; the orchestrator only reads the resulting
# classification.md back. No skill reference Reads are required.
```

---

## Step 2.1: Verify Intent Artifact

**EXECUTE:**
```
Read(file_path="tmp/${MIGRATION_ID}/intent.json")
```
Parse and confirm the JSON has the 5 required fields: `from_pattern`, `to_pattern`, `to_type` (file/folder/cli), `scope_dirs`, `exclusions`.

**VERIFY:**
- The file exists and parses as JSON.
- All 5 required fields are present and non-empty (`exclusions` may be `[]`).

IF any field missing: HALT — return to Phase 01 to complete the intent capture.

**RECORD:**
```bash
devforgeai-validate phase-record ${SESSION_ID} --workflow=migration --phase=02 --step=intent-verified
```

---

## Step 2.2: Delegate to `migration-classifier`

This step is the skill's first subagent delegation. The classifier runs in a **fresh context** — it does not inherit your conversation state; it reads only what its prompt names. This is anti-skip layer 1: an isolated context cannot rationalize past the EXECUTE step.

**EXECUTE:**

Issue exactly ONE `Task()` call:

```
Task(
  subagent_type="migration-classifier",
  description="Classify every <from_pattern> occurrence across <scope> for <MIGRATION_ID>",
  prompt="Classify every occurrence of the migration's from_pattern across the configured scope.

MIGRATION_ID: ${MIGRATION_ID}

Read tmp/${MIGRATION_ID}/intent.json for FROM_PATTERN, SCOPE_DIRS, EXCLUSIONS.

Walk every SCOPE_DIRS entry with Grep(pattern=FROM_PATTERN, output_mode=\"files_with_matches\"), drop any path matching any EXCLUSIONS pattern, then for every remaining file classify each occurrence into exactly ONE bucket per your prompt's bucket catalog: READ-OP / LISTING / PATH-VALIDATION / DOC / EXCLUDED / ALREADY-MIGRATED.

Emit tmp/${MIGRATION_ID}/classification.md per your Output Format (per-file table + summary table + FILES-NEEDING-NO-EDIT + EXCLUDED + MIXED lists).

Return a one-paragraph summary including: total files processed, total occurrences, the bucket count table, the count of MIXED + NO-EDIT + EXCLUDED files, and the absolute path to the written artifact.

Do not Write anywhere except tmp/${MIGRATION_ID}/classification.md. Do not Edit any file. Terminal worker: do not invoke other subagents."
)
```

**VERIFY:**
- The `Task()` returned a summary paragraph (non-empty).
- The artifact exists on disk:
  ```
  Glob(pattern="tmp/${MIGRATION_ID}/classification.md")  # MUST return exactly 1 path
  ```
- The artifact is well-formed Markdown with a `## Summary Table` section:
  ```
  Grep(pattern="^## Summary Table", path="tmp/${MIGRATION_ID}/classification.md")
  ```

IF the artifact is missing OR the Task returned an empty summary: HALT. Do NOT silently re-classify inline. Re-invoke the classifier with the same prompt, or escalate via AskUserQuestion if the classifier reports a structural problem with the scope/intent.

**RECORD:**
```bash
devforgeai-validate phase-record ${SESSION_ID} --workflow=migration --phase=02 --step=classification-delegated
```

---

## Step 2.3: Present Bucket Counts + User Confirmation

The classifier ran in a fresh context. You must NOT trust its numbers blindly — display them to the user and get explicit confirmation before the orchestrator commits to the migration's actual scope.

**EXECUTE:**

Read the classification summary table from disk:
```
Read(file_path="tmp/${MIGRATION_ID}/classification.md")
```
Locate the `## Summary Table` section and extract the bucket → occurrences / files counts. Display them to the user verbatim, including total files processed, MIXED count, FILES-NEEDING-NO-EDIT count, and EXCLUDED count.

Then issue AskUserQuestion:

```
AskUserQuestion:
  Question: "Classification complete. <TOTAL_FILES> files, <TOTAL_OCC> occurrences across the buckets above. Proceed to Phase 03 (transform-rules authoring + cluster planning) with this scope?"
  Header: "Classification Approval"
  Options:
    - label: "Proceed (Recommended)"
      description: "Confirm bucket counts; orchestrator + user will co-author transform-rules.md in Phase 03."
    - label: "Narrow exclusions"
      description: "Add exclusion patterns and re-classify (returns to Phase 01 with appended exclusions)."
    - label: "Abort migration"
      description: "Stop the workflow. Artifacts under tmp/${MIGRATION_ID}/ remain for inspection."
  multiSelect: false
```

**VERIFY:**
- The user selected exactly one option.
- The decision is recorded in the checkpoint:
  - "Proceed" → set `phase_02.user_confirmation = true` in `tmp/.migration-checkpoint-${SESSION_ID}.yaml`.
  - "Narrow exclusions" → write the new exclusion patterns into `tmp/${MIGRATION_ID}/intent.json` and HALT this phase (workflow returns to Phase 01).
  - "Abort migration" → write `phase_02.status = "aborted"` in the checkpoint and HALT the workflow.

**RECORD:**
```bash
devforgeai-validate phase-record ${SESSION_ID} --workflow=migration --phase=02 --step=user-confirmation
```

---

## Exit Gate [MANDATORY]

```bash
devforgeai-validate phase-complete ${SESSION_ID} --workflow=migration --phase=02 --checkpoint-passed
```
IF exit != 0: HALT.

---

## Phase 02 Success Criteria

- [ ] `tmp/${MIGRATION_ID}/classification.md` exists on disk with a complete per-file table + summary table + MIXED / NO-EDIT / EXCLUDED lists.
- [ ] The `migration-classifier` returned a summary paragraph confirming bucket counts.
- [ ] The orchestrator did NOT classify any file inline — the classifier did 100% of the bucketing work.
- [ ] The user explicitly approved the classification before Phase 03 may begin.
- [ ] The checkpoint records `phase_02.user_confirmation` (or `aborted` / `narrow-exclusions-redo`).
