---
name: leap
description: "LEAP: LLM Engineered Application Pattern. Use when the user says 'build the app', 'Read master.md', 'rewrite this project', or when you find a master.md in the project root. Generates all code from prompts, runs tests, serves the app. Can also convert existing codebases into LEAP format."
allowed-tools: Bash Read Write Edit Glob Grep
argument-hint: "[master.md path]"
---

# LEAP — LLM Engineered Application Pattern

You are operating in a LEAP project. Code is not the product — prompts, schemas, and tests are. You are the compiler.

## Philosophy

- **Prompts** describe intent. They are declarative, not imperative.
- **Schemas** define contracts between parts. They ARE the architecture.
- **Tests** specify correctness. They are human-authored guardrails. They are the most valuable artifact.
- **Code** is a commodity. It is generated, not written. It is disposable. It lives in `src/` and is gitignored.

The guardrails hierarchy (most to least valuable):
1. Tests — the specification of correctness
2. Schemas — the architecture
3. Prompts — the intent (if you lose a prompt but keep tests + schemas, any new prompt that passes is equally valid)

## How to operate

When you encounter a LEAP project (has `master.md` at root):

1. **Read `master.md`** — it contains the app description and generation instructions
2. **Read all schemas** in `schemas/` — these are the contracts
3. **Read all parts** — each `parts/*/master.md` has a prompt, each `parts/*/schema.ts` has a contract
4. **Generate code into `src/`** — satisfy every contract
5. **Install dependencies** — run `npm install` (or equivalent)
6. **Run tests** — they must all pass
7. **Fix until green** — if tests fail, fix the generated code and re-run
8. **Run the app** — if `master.md` has a "Running the app" section, execute it

## Rules

- **Do not ask questions.** Do not summarize. Do not confirm. Just build.
- **Do not modify anything outside `src/`.** Prompts, schemas, and tests are human-authored. You only generate code.
- **`src/` must be self-contained.** No imports from outside `src/`. Copy type definitions inline if needed.
- **Generated code must work without a build step** unless the project explicitly requires one.
- **Tests are the authority.** If a test contradicts a prompt, the test wins.
- **Start immediately** after reading all schemas and parts.

## DO NOT CHEAT

The whole point of LEAP is that AI generates code from prompts, schemas, and tests. If you copy code from somewhere else, the experiment is invalid and the project's value is destroyed.

**Forbidden:**
- ❌ Copying code from npm, PyPI, crates.io, or any package registry
- ❌ Copying code from `_original/`, `_reference/`, or any other reference folder in the project
- ❌ Reading the original/upstream source code of the project you're generating
- ❌ Downloading the project as a reference (`npm pack`, `git clone` of the upstream, etc.)
- ❌ Using `WebFetch` or `WebSearch` to look up the implementation
- ❌ Asking another agent to write the code for you
- ❌ "Porting" or "translating" existing code

**Allowed inputs for generation:**
- ✅ `master.md` (root and per-part)
- ✅ `schemas/` (the contracts)
- ✅ `tests/` (the guardrails)
- ✅ Standard library / language documentation
- ✅ Your own knowledge of how to implement things from scratch

**Why this matters:** If you copy the reference, you've proven nothing — you've just laundered existing code through a prompt-shaped wrapper. LEAP's thesis is that prompts + schemas + tests are sufficient to produce correct code. Copying invalidates the experiment.

**If a prompt is ambiguous:** Make your best guess from the tests. If tests don't disambiguate, ask the user. Never resolve ambiguity by reading the original source.

**If `_original/` exists in the project:** It is the user's reference, NOT yours. Treat it as if it doesn't exist during generation. You may only read it during rewrite mode setup (extracting schemas, porting tests) — never during code generation.

## Project structure

A LEAP project follows this structure:

```
master.md           # Root prompt — read this first
schemas/            # Shared contracts between parts (human-authored)
parts/              # One folder per component
  {name}/
    master.md       # Prompt for this part
    schema.ts       # Contract for this part
    parts/          # Optional: recursive sub-parts
tests/              # Human-authored behavioral tests
src/                # GITIGNORED — you generate this
```

## When regenerating

- If `src/` is empty — generate everything
- If a specific part's prompt changed — regenerate that part only
- After any generation — run all tests

## Spec authoring

Before writing any spec file, open `master.md` (or `spec/overview.spec.md` for multi-surface targets) with three required sections:

- **Binding source** — what this spec is being written *against*. Options: manpage, observed runtime behavior, ARIA pattern + explicit axis picks, reference tool output, user's mental model. Declare it in one line per source.
- **Design picks** — the axes where the external contract is multi-valued, and which value you chose. "Follow WAI-ARIA Combobox pattern" is vacuous; "autocomplete=list, selection-follows-focus=true, focus=aria-activedescendant" is a contract.
- **Out of scope** — explicit exclusions. This cuts ~80% of downstream ambiguity.

**External contracts are not specs.** Manpages understate reality. Reference tools behave wrong-by-design (Apple Calculator chains `2 + 3 × 4 = 20`). ARIA patterns admit multiple orthogonal variants. Spec must encode what the *artifact* does, not what the docs claim.

### Engine spec vs platform-adapter spec

For any multi-surface or platform-specific target:

- `spec/engine/` — pure. No platform vocabulary. The algorithm, the state machine, the contract.
- `spec/platform/<target>/` — allowed to name platform types (SwiftUI, DOM, ANSI, `clap`). Thin adapter to the engine.

The engine is testable without the platform. Any value that is a *function of engine state* belongs in the engine, not the view/adapter. View looks up; view does not compute.

### Schemas are refined types

A `string` type is rarely enough. A combobox `id` must be CSS-selector-safe (`:r1:` is a valid HTML id but breaks selectors). A path must be canonical. Declare refinements — branded types in TS, enums and structs in Swift/Rust, validators in Python.

## Tests are spec-discovery, not just spec-verification

On unfamiliar terrain, first-draft specs are wrong. Tests routinely force the spec to be rewritten, not just the code. This is *correct LEAP behavior*, not a process violation.

The commit sequence `spec → tests → spec' → src` is expected. If tests fail because the spec is wrong, fix the spec first, then regenerate code. If tests fail because the code is wrong, fix the code. Never silence a test to make code pass.

**Test-artifact class is part of the spec.** Declare the class, pin the tooling:

| Surface | Required test class | Notes |
|---|---|---|
| Web | Playwright e2e + axe-core a11y + visual regression | pin browser version |
| Native (macOS/iOS) | Accessibility-tree snapshot | pixel snapshots are fragile on SwiftUI; prefer structural |
| TUI | PTY-based snapshot | stream mocks silently pass real bugs |
| CLI | Byte-exact golden diff + checked-in regenerator script | pin reference tool version |

"No test-artifact class declared" = not LEAP-compliant.

## Rewrite mode — converting existing projects to LEAP

When the user asks to "rewrite" or "convert" an existing codebase into LEAP format:

### Step 1: Analyze the existing project

- Read the source code and understand the architecture
- Identify the public API — every exported function, class, type, constant
- Map the natural component boundaries (modules, classes, packages)
- Read the existing test suite — understand what's already tested

### Step 2: Extract schemas

- Create `schemas/` with type definitions covering the full public API
- Every function signature, every data type, every interface — extract it
- These become the contracts. Be exhaustive. Missing a schema means missing a guardrail.

### Step 3: Port tests

- Copy or rewrite existing tests into `tests/`
- Tests must be behavioral — test what the code does, not how it's structured
- Remove any tests that depend on implementation details (private functions, internal state)
- Add edge case tests you notice are missing in the original
- **Tests are the most valuable artifact.** Spend the most time here.

### Step 4: Decompose into parts

- Create `parts/` with one folder per natural component
- Each part gets a `master.md` prompt describing what that component does
- Each part gets a `schema.ts` with its specific contract
- Parts should be independent — no part's prompt should reference another part's implementation
- Keep parts small enough that an AI can generate each one correctly in a single shot

### Step 5: Write master.md

- Create root `master.md` describing the project, its purpose, and how parts connect
- Include tech constraints, generation rules, and verification steps
- Reference the original project for context

### Step 6: Verify the rewrite

- Add `src/` to `.gitignore`
- Delete or move aside the original source code
- Generate fresh code from the prompts: read `master.md` and build
- Run all ported tests
- If tests fail — improve prompts, add missing schema details, iterate
- Compare behavior against the original project

### Rewrite rules

- **Port tests first, write prompts second.** Tests anchor correctness; prompts are iterable.
- **Don't simplify the API.** The rewrite must be a drop-in replacement. Same public interface.
- **Don't skip edge cases.** If the original handles it, your tests must cover it.
- **Schemas must be complete.** Every public type, every exported symbol.
- **Keep the original's test cases.** They encode years of bug discoveries. Each test exists because something broke once.

## UI projects — web, native, TUI, CLI

All UI surfaces follow the general spec-authoring rules above: engine/platform split, test-artifact class declared, refined schemas, derived values in the engine (not the view). Surface-specific rules follow.

### Web

Web projects have a `design/` directory at the root.

- `design/tokens.json` — design system (colors, spacing, typography). Consume these.
- `design/references/` — reference images. Test fixtures, not documentation.
- `design/figma.json` — optional Figma export for traceability.

Web test types (all must pass):

1. **`tests/visual/`** — pixel-diff tests against reference images. Primary correctness signal.
2. **`tests/interaction/`** — Playwright behavior (click, hover, type, focus).
3. **`tests/a11y/`** — axe-core + keyboard nav + screen reader compliance.

Banned patterns (web):

- ❌ **DOM snapshot tests** — lock implementation, forbid regeneration
- ❌ **Class name assertions** — couple tests to a specific CSS approach
- ❌ **Rendered HTML string comparisons** — same problem
- ❌ **Tests that check framework-specific internals** (e.g., "is this a `React.forwardRef`")

When generating web code:

- Free to choose any framework, CSS approach, or DOM structure UNLESS `master.md` constrains you
- Consume `design/tokens.json` — do not hardcode colors, spacing, fonts
- Match rendered output to `design/references/*.png` — visual tests verify this
- Use `maxDiffPixelRatio` (typical: 0.01), not exact pixel matches
- Pin browser version in CI to eliminate cross-browser drift
- Never mock the browser for visual tests — real headless browser only

### Native (macOS / iOS)

- Engine (Core) library must be pure — no UI dependency. Unit-testable in isolation.
- UI layer (SwiftUI / AppKit) adapts the engine; does not duplicate logic.
- Prefer **accessibility-tree snapshots** over pixel snapshots — pixel tooling is fragile on SwiftUI, and XCTest itself can fail to load on fresh macOS + Xcode combinations. Document a fallback test runner (plain executable wrapping identical assertions) when XCTest is broken.
- Keyboard shortcuts belong in the *platform-adapter* spec — iOS/visionOS have no keyboard, cross-target portability is not free.

Banned patterns (native):

- ❌ **Derived display values computed in `@State`** — rebadging, formatting, filtering live in Core
- ❌ **Pixel snapshots as the primary contract** — use accessibility-tree / structural-view snapshots
- ❌ **`@main` App struct holding business logic** — `App` is adapter; logic is in Core

### TUI (interactive terminal)

- **Keyboard decode table is the load-bearing schema.** Escape-sequences → logical-key mapping lives in `schema/keymap.schema.*` or `spec/keyboard.spec.md`. First-class artifact, not buried in code.
- **Render at the frame level, not per-widget.** One `render-loop.spec.md` + `render-frame.schema.*` (frame = lines + final flag) collapses per-widget render pipelines into one.
- **PTY-based testing is non-negotiable.** Stream-mocking stdin/stdout silently passes raw-mode, cursor-escape, and SIGINT bugs. Use `node-pty` (via `@homebridge/node-pty-prebuilt-multiarch` on Node 22 + darwin-arm64) or the equivalent in your runtime.
- **Respect `NO_COLOR`** — disable styling but keep terminal control codes. They are different things.
- **SIGINT handling is part of the spec.** Cursor restore, terminal mode restore, exit code 130. Not optional.

### CLI (stream-only, non-interactive)

- **Schema-first, not framework-derived.** Hand-author the args struct with invariants + docstrings. The arg-parsing framework (`clap`, `argparse`, `commander`) is a disposable adapter. Otherwise the framework IS the spec and the schema drifts silently.
- **Golden-file byte-exact diff** is the test class when reproducing a reference tool. Text-level assertions pass through invisible character differences (NBSP indent in `tree(1)`'s output is a classic).
- **Manpage ≠ reality.** Spec must be written against observed behavior of the reference binary, not its documentation. Include a checked-in `gen-golden.sh` that regenerates fixtures from the reference tool at a pinned version.
- **Stdout is output; stderr is errors; exit code is contract.** All three are part of the spec.

Banned patterns (CLI):

- ❌ **Framework-derived args schema** — makes the framework the spec
- ❌ **Text-level output assertions when byte-exact is required** — invisible characters pass through
- ❌ **Tests that shell out without pinning the reference tool version**

## For other AI agents

This skill is portable. The LEAP pattern works with any AI coding agent.
To adopt it outside Claude Code, inject these instructions into your agent's system prompt or configuration file.

The core contract is simple:
1. Read `master.md`
2. Read schemas and parts
3. Generate code
4. Run tests
5. Fix until green
