---
name: fp-validate
description: Lint PRDs, ERDs, and execution plans against fastpace conventions. Flags missing required sections, empty security blocks, broken ADR links, stories over 16h, stories without acceptance criteria, and glossary drift. Exit 1 on errors so CI can gate merges. Triggers on /fp-validate.
---

# fp-validate

Catch structural problems in planning artifacts *before* they reach a reviewer. Opinionated but small — rules are listed below so they're reviewable.

## Preflight

- If there are no artifacts under `fastpace/docs/` or `fastpace/exec-plans/`, print "nothing to validate" and stop.

## Rules checked

### PRDs (`fastpace/docs/prd/*.md`)
- **Required sections** (`## Summary`, `## Problem`, `## Goals`, `## Non-goals`, `## User stories`, `## Success metric`). Missing → **error**.
- **Frontmatter** with at least `title:` and `status:`. Missing → warning.

### ERDs (`fastpace/docs/erd/*.md`)
- **Required sections** (`## Overview`, `## Interface contracts`, `## Data model`, `## Security`, `## Acceptance criteria`). Missing → error.
- **Security section not empty** (< 20 characters of body after the heading → error). If genuinely "none", require a justification inline.
- **ADR links resolve** — any `ADR 0007` / `docs/adr/0007-…` reference must correspond to an actual file in `fastpace/docs/adr/`. Dead link → warning.

### Execution plans (`fastpace/exec-plans/*.json`)
- **Valid JSON** — parse error → error.
- **Has `waves[]`** — missing → error.
- **Every story has `name`** — missing → error.
- **No story > 16h** — warning (encourages splitting).
- **Every story has `acceptance_criteria[]`** — missing → warning.

### Context
- `learnings.md` should have `## <date> — title` entries when non-empty. Otherwise → warning.
- **Glossary drift** — if `glossary.md` defines "Tenant" (PascalCase) and a PRD/ERD uses "tenant" (lowercased) in a heading, flag → warning.

## Process

1. Prefer the CLI:
   ```
   fastpace validate        # human-readable output, exits 1 on error
   fastpace validate --quiet --no-hints
   ```
2. Fallback (no CLI): replicate the rules above by reading files directly. Print results in the same shape.

## Output format

```
⚡ fastpace validate · 2 error(s) · 3 warn(s)

  ✗ fastpace/docs/erd/oidc-migration.md  [erd-sections]
    ERD missing required section(s): security, acceptance criteria
    → fix: add "## security" (and the others) — see /fp-write-erd
  ! fastpace/docs/erd/cc-validation.md  [erd-adr-link]
    references ADR 0012 which was not found in fastpace/docs/adr/
    → fix: either create the ADR or remove the reference
  …

  2 error(s) — fix before merging.
```

## Rules of the skill itself

- **Read-only.** Don't auto-fix.
- **Cite the file** for every finding. `path:line` where possible, at least `path` otherwise.
- **Group by severity.** Errors first, warnings second.
- **Explain the "why" briefly.** "Security must be non-empty because we can't silently let an ERD skip it."
- **Don't re-report noise.** If the same rule fails on 12 files, mention it per file but keep each entry terse.

## Integration

- Run in CI as a merge gate: `fastpace validate || exit $?`.
- Pre-commit hook: same command; fast (no network, no AI).
- If the user just wants the raw list for automation, `fastpace validate --quiet --no-hints` is machine-friendly.
- When finished, suggest re-running after edits: "fix the two errors above, then rerun `fastpace validate`".

## Exit criteria

- Every error and warning printed with `path`, `[kind]`, `msg`, and a `→ fix:` line.
- The skill returns / exits 1 if any errors exist, 0 otherwise.
- Zero files modified.
