# Phase 02: Epic Framing

## Entry Gate

```bash
devforgeai-validate phase-check ${SOLARCH_ID} --workflow=solution-architecture --from=01 --to=02 --project-root=. 2>&1
```

| Exit Code | Action |
|-----------|--------|
| 0 | Proceed to Phase 02 |
| 127 | CLI not installed — proceed without enforcement |
| Other | HALT — previous phase not complete |

---

## Contract

| Attribute | Value |
|-----------|-------|
| **PURPOSE** | Establish WHICH epic this Solution Architecture decomposes and confirm its scope. One Solution Architecture Document is produced per epic. This phase frames the epic — it identifies the `EPIC-NNN`, confirms what the epic delivers, and bounds it against the System Architecture's system boundary. It does NOT write a separate `.epic.md` file: the Solution Architecture Document IS the per-epic artifact, and the feature decomposition produced in Phase 07 is the substantive epic-creation work absorbed from `spec-driven-architecture` Phase 11. |
| **REFERENCE** | `.claude/skills/spec-driven-solution-architecture/references/solution-architecture-output.schema.json` |
| **STEP COUNT** | 4 mandatory steps |

## Phase Exit Criteria

Before this phase can complete, ALL of the following MUST be true:

- [ ] `epic_ref` recorded, matching `^EPIC-[0-9]{3,}$`
- [ ] Existing epic source file located and read, OR a new-epic framing explicitly recorded
- [ ] `epic_scope` confirmed with the user (summary, in-scope, out-of-scope)
- [ ] Epic scope bounded inside the System Architecture `system_boundary` (Phase 01)

**IF any criterion is unmet: HALT. Do NOT proceed to Phase 03.**

---

## Reference Loading

```
Read(file_path=".claude/skills/spec-driven-solution-architecture/references/solution-architecture-output.schema.json")
```

The `epic_ref` property (pattern `^EPIC-[0-9]{3,}$`) is the field this phase
populates. IF the Read fails: HALT — "Phase 02 output contract not loaded."

Do NOT rely on memory of previous reads. Load fresh every time this phase executes.

---

## Mandatory Steps

### Step 2.1: Determine the Epic

**EXECUTE:**
```
IF $EPIC_ID was provided and matches ^EPIC-[0-9]{3,}$:
  epic_ref = $EPIC_ID
  epic_mode = "existing"
ELSE:
  Glob(pattern="devforgeai/specs/epics/EPIC-*.epic.md")
  IF matches found:
    AskUserQuestion — present the existing epics, ask which epic this Solution
    Architecture decomposes. Include a "Frame a new epic" option.
    IF the user selected an existing epic: epic_ref = that; epic_mode = "existing"
    IF the user selected "Frame a new epic": epic_mode = "new"
  ELSE:
    epic_mode = "new"

  IF epic_mode == "new":
    Determine the next id: take the highest NNN across the Glob matches
    (devforgeai/specs/epics/EPIC-*.epic.md), add 1; if no epics exist, EPIC-001.
    epic_ref = "EPIC-{NNN+1}"   # zero-padded to 3 digits minimum
```

Generate the next id from the live `Glob` result — never from memory of a prior
epic frontier.

**VERIFY:**
- `epic_ref` matches `^EPIC-[0-9]{3,}$`
- `epic_mode` is one of `existing` / `new`

**RECORD:**
```bash
devforgeai-validate phase-record ${SOLARCH_ID} --workflow=solution-architecture --phase=02 --step=2.1 --project-root=. 2>&1
```
```json
{ "phase": "02", "step": "2.1", "epic_ref": "<EPIC-NNN>", "epic_mode": "<existing|new>" }
```

---

### Step 2.2: Locate and Read the Epic Source

**EXECUTE:**
```
Glob(pattern="devforgeai/specs/epics/${epic_ref}-*.epic.md")
IF a file is found:
  Read(file_path=<that file>)
  Extract the epic's stated scope, its feature list, and any requirement
  references (FR-NNN) it already carries → epic_source.
ELSE:
  epic_source = null   # new epic — scope is framed fresh in Step 2.3
```

A `new` epic with no source file is expected and valid; record the absence
explicitly rather than silently omitting it.

**VERIFY:**
- `epic_mode == "existing"` ⇒ either the epic file was read, OR the user is
  informed no file exists and confirms framing the scope fresh
- `epic_mode == "new"` ⇒ `epic_source` recorded as `null`

**RECORD:**
```bash
devforgeai-validate phase-record ${SOLARCH_ID} --workflow=solution-architecture --phase=02 --step=2.2 --project-root=. 2>&1
```
```json
{ "step": "2.2", "epic_source_file": "<path|null>", "epic_source_present": "<true|false>" }
```

---

### Step 2.3: Confirm the Epic Scope

**EXECUTE:**

Frame the epic against two inputs from the Phase 01 checkpoint — the System
Architecture `system_boundary` and (via the System Architecture's
`source_pm_plan`) the prioritized requirements — plus `epic_source` if present:

```
epic_scope = {
  name: "<short human-readable epic name>",
  summary: "<one-paragraph statement of what this epic delivers>",
  in_scope: [ "<capability inside this epic>", ... ],
  out_of_scope: [ "<capability explicitly NOT in this epic — deferred or another epic>", ... ],
  requirement_refs: [ "FR-NNN", ... ]   # PM-plan requirements this epic realizes
}
```

State a one-line recommendation derived from `epic_source` / the system boundary,
then `AskUserQuestion` to confirm the scope. Every epic capability MUST fall
inside the System Architecture `in_system` set — an epic capability that lands in
`out_of_system` is a scope conflict: HALT and AskUserQuestion.

**VERIFY:**
- `epic_scope.summary` is a non-empty paragraph
- `in_scope` has ≥ 1 entry
- No `in_scope` capability contradicts the System Architecture `out_of_system` set
- The user confirmed the scope (response non-empty)

**RECORD:**
```bash
devforgeai-validate phase-record ${SOLARCH_ID} --workflow=solution-architecture --phase=02 --step=2.3 --project-root=. 2>&1
```
```json
{ "step": "2.3", "epic_scope": { ... }, "user_confirmed_scope": true }
```

---

### Step 2.4: Record the Epic Framing

**EXECUTE:**
```
Assemble the epic framing for downstream phases. Components (Phase 03), interface
contracts (Phase 04), the data model (Phase 05), and the feature decomposition
(Phase 07) are ALL scoped to this epic — nothing outside epic_scope.in_scope is
designed.
```

**VERIFY:**
- `epic_ref` and `epic_scope` are both populated

**RECORD:**
```bash
devforgeai-validate phase-record ${SOLARCH_ID} --workflow=solution-architecture --phase=02 --step=2.4 --project-root=. 2>&1
```
```json
checkpoint.phases["02"] = {
  "status": "completed",
  "epic_ref": "<EPIC-NNN>",
  "epic_mode": "<existing|new>",
  "epic_source_file": "<path|null>",
  "epic_scope": { "name": "...", "summary": "...", "in_scope": [...],
                  "out_of_scope": [...], "requirement_refs": [...] }
}
```

---

## Exit Gate

```bash
devforgeai-validate phase-complete ${SOLARCH_ID} --workflow=solution-architecture --phase=02 --checkpoint-passed --project-root=. 2>&1
```

| Exit Code | Action |
|-----------|--------|
| 0 | Phase 02 complete — proceed to next phase |
| 127 | CLI not installed — proceed without enforcement |
| Other | HALT — checkpoint/step validation failed |

---

## Phase Transition Display

```
Display:
  "Phase 02 Complete: Epic Framing"
  "Epic: {epic_ref} ({epic_mode})  |  {epic_scope.name}"
  "In scope: {count} capabilities  |  Requirements covered: {count}"
  "Proceeding to Phase 03: Component Decomposition"
```
