| 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):
- Tests — the specification of correctness
- Schemas — the architecture
- 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):
- Read
master.md — it contains the app description and generation instructions
- Read all schemas in
schemas/ — these are the contracts
- Read all parts — each
parts/*/master.md has a prompt, each parts/*/schema.ts has a contract
- Generate code into
src/ — satisfy every contract
- Install dependencies — run
npm install (or equivalent)
- Run tests — they must all pass
- Fix until green — if tests fail, fix the generated code and re-run
- 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):
tests/visual/ — pixel-diff tests against reference images. Primary correctness signal.
tests/interaction/ — Playwright behavior (click, hover, type, focus).
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:
- Read
master.md
- Read schemas and parts
- Generate code
- Run tests
- Fix until green