---
name: fp-discover
description: Seed domain context for this repo. Scans the codebase, infers architecture/stack/conventions/patterns, writes foundation files into fastpace/context/, and raises context.level to L2. Run ONCE per repo (brownfield) or at project start (greenfield). Triggers on /fp-discover.
---

# fp-discover

Bootstrap the domain context for this repo so future sessions start at L2 (code + domain context) instead of L1 (code alone). The output is a suite of markdown files any AI runtime can rehydrate from — plain git, no cloud.

## Preflight

1. Confirm `fastpace/fastpace.config.yaml` exists. If not, tell the user to run `fastpace` first and stop.
2. If `fastpace/context/` already has files, ask: "Context exists — add only what's missing, or re-run from scratch?" Default to additive.
3. Respect `.gitignore`. Skip `node_modules/`, `dist/`, `build/`, `.next/`, `.cache/`, `coverage/`, `.git/`, `vendor/`, `venv/`, `__pycache__/`.

## Process

1. **Sample, don't scan.** Read top-level `package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml` / `Gemfile` / `pom.xml` first. Then read 1 top-level README, 1 config per framework, and one or two representative source files per detected module.
2. **Detect the stack** (see detection matrix below). Record with confidence levels.
3. **Infer architecture.** Is it monorepo? Layered? Hexagonal? Serverless? Where are entry points? What's the data layer?
4. **Infer conventions.** Naming case (camel/snake/pascal/kebab), commit style (conventional vs free-form via `git log --oneline -n 30`), test file location/pattern, branch model.
5. **Extract glossary candidates** — domain nouns that appear in route paths, type names, or README but aren't generic programming terms. If you can't extract any confidently, leave `glossary.md` with just a header + "# Domain terms go here."
6. **Write the foundation files** (see formats below). Create `fastpace/context/` if missing.
7. **Update `fastpace/fastpace.config.yaml`**:
   - `context.level` → `L2`
   - `project.name` → detected package name
   - `project.type` → one of `node-service`, `python-service`, `go-service`, `rust-service`, `web-app`, `cli-tool`, `library`, `monorepo`, or `unknown`
   - `project.naming` → detected case convention
   - `project.commit_style` → `conventional` if > 50% of last 30 commits match `^(feat|fix|chore|docs|refactor|test|perf|build|ci|revert)(\(.+\))?:`, else `free-form`
8. **Summarize** — what you wrote, what's `(inferred)`, what needs the user's help.

## Detection matrix

| Signal | Suggests |
|---|---|
| `package.json` with `"type": "module"` | ESM Node project |
| `next.config.*` | Next.js web app |
| `astro.config.*` | Astro site |
| `vite.config.*` | Vite-based SPA or lib |
| `tsconfig.json` + `"composite": true` | TS project references / monorepo-ish |
| `pnpm-workspace.yaml` / `lerna.json` / `turbo.json` | Monorepo |
| `Dockerfile` + `cmd/` dir | Go service |
| `pyproject.toml` with `[tool.poetry]` | Poetry-managed Python |
| `requirements.txt` + `manage.py` | Django |
| `fastapi` in deps | FastAPI service |
| `@aws-sdk/*` or `serverless.yml` | Serverless / AWS Lambda |
| `prisma/` dir or `drizzle.config.*` | TypeScript ORM in use |
| `migrations/` dir | Schema-first DB layer |
| `terraform/` or `infra/` dir | IaC present, note in architecture.md |

## Foundation files — formats (exact)

### `fastpace/context/architecture.md`

```markdown
# Architecture

## Overview

<2-4 sentences: what this repo does, at what layer>

## Structure

- **Repository layout:** <monorepo with N packages | single app | …>
- **Primary modules:** <list with one-line purpose each>
- **Entry points:** <HTTP routes / CLI commands / queue consumers>
- **Data layer:** <db + cache + indices as applicable>

## External dependencies

- <service>: <what role>

## Deploy target

<where it runs, best-guess or `(unknown)`>
```

### `fastpace/context/stack.md`

```markdown
# Stack

- **Language(s):** <node 20.11 | python 3.12 | …>
- **Framework(s):** <express 4.19 | next 15 | django 5 | …>
- **Package manager:** <pnpm | yarn | poetry | …>
- **Test:** <vitest | jest | pytest | …>
- **Build/bundle:** <vite | webpack | esbuild | none | …>
- **CI:** <github-actions | gitlab-ci | none-detected>
- **Deploy:** <docker | vercel | fly | unknown>
```

### `fastpace/context/conventions.md`

```markdown
# Conventions

- **Naming:** <camelCase for vars, PascalCase for types, …>
- **Commits:** <conventional | free-form>  (detected from last 30 commits)
- **Tests:** <colocated as *.test.ts | in tests/ dir | …>
- **Branches:** <feature/* | feat/* | (unknown)>
- **PR reviews:** <unknown — ask the team>
```

### `fastpace/context/glossary.md`

```markdown
# Glossary

Domain terms. Extracted from code + README.

<leave empty or seeded with 1-3 high-confidence terms — NEVER fabricate>
```

### `fastpace/context/patterns.md`

```markdown
# Patterns

Recurring code idioms worth preserving.

<only list patterns you can see in the code; skip if none are obvious>
```

### `fastpace/context/decisions.md` (append-only — seed with inferences)

```markdown
# Decisions

Append-only log of architectural and engineering decisions. Never rewrite prior entries.

## <YYYY-MM-DD> — <short title>  (inferred)
**Context:** <what the code suggests>
**Decision:** <the choice>
**Consequences:** <tradeoffs>
**Author:** fp-discover (inferred — verify)
```

Mark everything you inferred with `(inferred)` so the user can correct.

### `fastpace/context/learnings.md`

```markdown
# Learnings

Append-only log of hard-won knowledge. Grows as the team works with fastpace.

<leave the file with just this header — learnings come from real incidents, not scans>
```

## Rules

- **Never fabricate.** If you can't tell something with confidence, write `(unknown)` or `(inferred)`. The user would rather correct than be misled.
- **Append-only discipline.** `decisions.md` and `learnings.md` never get rewritten — only appended. If you're re-running on an existing repo, *never* touch existing entries.
- **Prefer empty over wrong.** An empty `glossary.md` with "# Domain terms go here" is better than five made-up terms.
- **Keep files short.** Each foundation file should be < 100 lines after this pass. The user will grow them.
- **Don't paste file contents back at the user.** Write the files; summarize what changed.
- **Don't read the whole repo.** Aim for < 50 file reads. If you need more, sample.

## Output (exact)

End with a block like this:

```
✓ context seeded at fastpace/context/  (level: L1 → L2)

  architecture.md   written  (modules: N, entry points: N)
  stack.md          written
  conventions.md    written  (commit style: conventional)
  glossary.md       written  (empty — run /fp-teach to populate)
  patterns.md       written  (1 pattern extracted)
  decisions.md      written  (3 inferred decisions — please review)
  learnings.md      written  (empty)

  config updated: project.type=<type>, project.naming=<case>, context.level=L2

  next:
   - review decisions.md and remove/confirm "(inferred)" entries
   - /fp-teach <subsystem> to add depth
```

## Integration

- After running, the recommended next commands are `/fp-teach` (for anything you couldn't infer) and `/fp-write-prd` (if the user wants to start a feature).
- If the detection matrix didn't match anything, recommend `/fp-teach architecture` so the user can describe the stack manually.

## Exit criteria

- 7 foundation files written (or existing ones preserved with new additions).
- Config level raised to L2.
- Summary block printed.
- Nothing outside `fastpace/context/` and `fastpace/fastpace.config.yaml` was modified.
