---
name: discovery-intake
description: >
  Discovery phase 7 — derive a small set of compact artifacts in .claude/ from
  the canonical docs/ tree. No mirror of ADRs or full C4: skills read those
  directly from docs/. Intake produces only what needs a different shape
  (yaml) or a token-economic summary. Idempotent.
user-invocable: true
---

# /discovery-intake

Phase 7. Bridges `docs/` (canonical, human-reviewable) to `.claude/` (compact runtime artifacts).

**Driver agent:** `planner` proposes the diff, user approves, then writes.
**Reads:** all of `docs/`.
**Writes:**
- `.claude/project.yml` — yaml derivation (different shape, not a copy)
- `.claude/memory/architecture.md` — **compact summary, 20–40 lines max** (full C4 stays in `docs/architecture/`)
- `.claude/memory/requirements.md` — FR↔UC index (~1 line per FR with linked UCs)

**Does NOT write:**
- ADRs — skills and agents read `docs/decisions/ADR-*.md` directly.
- Full architecture detail — lives in `docs/architecture/c4-*.md`.
- Full FR/NFR/UC text — lives in `docs/requirements/` and `docs/use-cases/`.

This avoids drift: there is **one source of truth per artifact**.

---

## preconditions

1. Read `docs/.discovery-state.md`. ABORT if any of phases 1-6 is not `complete`.
   - Print missing phases and exit with `❌ Error: phases [list] incomplete. Run /discovery first.`
2. Verify NFR file has no `⚠️ NEEDS METRIC` flags. ABORT if found — invariants must be measurable.
3. Verify all FRs have `Verifiable by` filled.

---

## mapping (docs/ → .claude/)

| Source | Destination | Transform |
|--------|-------------|-----------|
| `docs/glossary.md` → entities | `project.yml.domain.entities` | List of entity names |
| `docs/requirements/non-functional.md` | `project.yml.invariants` | One invariant per measurable NFR |
| `docs/use-cases/UC-*.md` | `project.yml.critical_flows` | Title + description + tables touched |
| `docs/architecture/c4-context.md` + `c4-container.md` | `memory/architecture.md` | **Executive summary, 20–40 lines.** Containers + tech + layer invariants + pointer to `docs/architecture/c4-*.md` for diagrams and detail. |
| `docs/requirements/functional.md` + `docs/use-cases/` | `memory/requirements.md` | Index linking FR→UCs (one line per FR, ~30 lines total) |
| `docs/decisions/ADR-*.md` | — (no copy) | Skills and agents reference `docs/decisions/ADR-*.md` directly. |

**Gate-protected areas inference:** scan `docs/decisions/` for ADRs marked with `gate_protected: true` in frontmatter, plus auto-add `migrations/` and any path mentioned in NFRs about security or compliance. Propose `project.yml.gate_protected_areas` for user review.

---

## flow

1. **Plan phase** — read all `docs/`. Generate the proposed `.claude/` diff in memory.
2. **Show diff** — print:
   ```
   📥 Discovery → .claude/ intake plan

   .claude/project.yml
   ━━━━━━━━━━━━━━━━━━
   ➕ domain.entities: [organization, user, restaurant, menu, order]
   ➕ invariants:
       - Tenant Isolation (NFR-SEC-01): All DB queries filter by org_id
       - API Latency (NFR-PERF-01): p99 < 200ms on GET /api/v1/*
   ➕ critical_flows:
       - Place Order (UC-02): validate menu → check stock → charge → notify

   .claude/memory/architecture.md  (executive summary, ~30 lines)
   .claude/memory/requirements.md  (12 FRs indexed to 8 UCs)

   Note: ADRs and full C4 stay in docs/ — read directly by agents and skills.

   Proceed? (y / edit / abort)
   ```

3. **Apply** — on `y`:
   - Write `project.yml` (preserve existing keys not derived from docs).
   - Rewrite `memory/architecture.md` as a **20–40 line executive summary**
     with `<!-- generated by /discovery-intake on YYYY-MM-DD — full C4 in docs/architecture/ -->` header.
     Include: container list, tech stack, layer invariants, communication paths.
     Skip diagrams; reference `docs/architecture/c4-container.md` for them.
   - Generate `memory/requirements.md` index — one line per FR with linked UCs.
   - Update `docs/.discovery-state.md` → `phase_7_intake.status: complete` + `last_intake: <date>`.
   - **No ADR copy step.** ADRs remain in `docs/decisions/` only.

4. **Edit** — open the proposed `project.yml` for inline edit, then re-confirm.

5. **Abort** — exit without changes.

---

## idempotency

- Re-running `/discovery-intake` after editing `docs/` only updates affected sections.
- `memory/architecture.md` is fully regenerated each run (it's a derived summary). To customize, edit `docs/architecture/c4-*.md` instead — the next intake reflects it.
- `project.yml` keys NOT derived from docs (e.g. `tenant.column`, custom invariants added manually) are preserved.

---

## phase 8 — sync FRs to tracker (optional)

After the `.claude/` writes succeed, check `stack.yml → tracker.type`.

- Not set, `none`, or section missing → skip silently. Done.
- `linear` → run Linear sync (below).
- `github` → run GitHub sync (TODO — not implemented yet; skip with notice).

### Linear sync (hybrid model)

Goal: every approved FR in `docs/requirements/functional.md` exists in Linear as a
**parent issue** with the FR's design content as description. This makes Linear
the runtime tracker for state (status, assignee, sprint) while `docs/` stays the
canonical design source.

Requires the Linear MCP server (e.g. `linear-server`) to be configured. The
calling session must have `mcp__linear-server__*` tools available — discovery-intake
runs in the main session, so the user's permissions apply.

Steps:

1. **Resolve team:** read `stack.yml → tracker.linear.team_id`.
   - If empty, call `mcp__linear-server__list_teams()` and ask the user to pick.
     Persist the chosen `team_id` back into `stack.yml`.
2. **Ensure label:** read `stack.yml → tracker.linear.fr_label` (default `fr`).
   - Check the team's labels; create the label if missing (one-time setup).
3. **For each FR in `docs/requirements/functional.md`:**
   - Title: `[FR-N] <FR title>`
   - Description: the full FR markdown block (Actor, Trigger, Outcome, Verifiable by).
   - Labels: `[fr_label]`
   - **Lookup first:** search Linear for an issue with the same title prefix `[FR-N]`.
     - Found → call `mcp__linear-server__save_issue(id, title, description, labels)` to update.
     - Not found → call `mcp__linear-server__save_issue(title, description, teamId, labels)` to create.
   - **Idempotent:** skip update if description hash matches the doc's content hash
     (write hash into a small index file: `docs/.tracker-sync.md`).
4. **Detect orphans:** Linear issues with the `fr` label whose `[FR-N]` ID is not
   present in `docs/requirements/functional.md`. Print as a warning:
   ```
   ⚠️ Linear issue [FR-08] exists but is not in docs. Manually triage:
      - rename to remove the FR-N prefix, or
      - add FR-08 back to docs/requirements/functional.md
   ```
5. **Update state file:** `docs/.discovery-state.md` adds:
   ```
   ## phase_8_tracker_sync
   tracker: linear
   last_synced: <today>
   fr_synced: <N>
   fr_orphans: <N>
   ```

### Failure handling

- MCP not available / tool errors → print warning, continue. The intake still
  succeeds; only the tracker sync is skipped. The user can retry by re-running
  `/discovery-intake` after fixing the MCP setup.
- Network failures → same. Sync is best-effort, not blocking.

---

## post-intake

Print:
```
✅ Intake complete.

Next steps:
  /sync-schema           # if you have a database schema, populate memory/schema.md
  /feature FR-01         # implement the first FR (linked to its Linear parent)
  /feature <description> # start your first feature
```

If this is the first intake (no prior `.claude/memory/architecture.md` content), suggest:
```
First intake detected. Recommended first feature:
  /feature Bootstrap project scaffold per the C4 container plan
```

---

## stop conditions

- Preconditions fail → exit with error and instructions.
- User says `abort` → no writes.
- Conflict between `project.yml` manual edits and intake plan → ask user to resolve per-key.
