| name | design-verification |
| description | This skill should be used when the user asks to "verify the design", "check the design against the codebase", "validate the design doc", "check for blockers", "will this design work", or after writing a design document to catch schema conflicts, type mismatches, and pipeline assumptions before implementation, "check assumptions", "what am I assuming", "verify assumptions", "surface assumptions". |
| tools | Read, Glob, Grep, Task, Bash, Write, Edit, WebFetch, WebSearch, AskUserQuestion |
Design Verification
Verify a design document against the actual codebase to catch conflicts, gaps, and incorrect assumptions before implementation. This is the gate between "this sounds right" and "this will actually work."
Announce at start: "Running design-verification to check this design against the codebase for blockers and gaps."
When to Use
- After writing or updating a design document
- Before creating a GitHub issue from a design
- Before writing an implementation plan
- When the user asks "will this work with our app?"
Process
Step 1: Load the Design Document
Find the design from the linked GitHub issue:
-
If issue is in the lifecycle context (the issue number was passed as an argument or set by create-issue earlier in the session):
gh issue view <issue_number> --json body --jq '.body'
Extract the content between <!-- feature-flow:design:start --> and <!-- feature-flow:design:end --> markers.
- If markers are found: use the extracted content as the design document.
- If markers are absent: the design has not been merged into the issue yet. Stop and instruct the user: "No design found in issue #<issue_number>. Run
feature-flow:design-document first to merge the design into the issue."
- If the extracted content is a reference link (
Design is too large to inline — see comment: <url>): fetch the comment URL via gh api <url> --jq '.body' and use that content instead.
-
If the user specified a file path directly (legacy support for pre-2026-04-23 design docs in docs/plans/):
Read the file at the specified path. Announce: "Loading design from file (legacy path): <path>."
-
Fallback — no issue and no path: Stop and instruct the user: "No design source found. Pass the issue number (issue: N) or a file path (design_doc: /path/to/doc.md)."
After loading, extract all proposed changes from the design content.
Step 2: Load Project Context
Check for a .feature-flow.yml file in the project root:
- If found, read the
platform, stack, and gotchas fields
- For each entry in
stack, look for a matching reference file at ../../references/stacks/{name}.md (relative to this skill's directory)
- For the declared
platform, load the platform reference from ../../references/platforms/{platform}.md (use mobile.md for ios, android, or cross-platform)
- If a stack has no matching reference file, note it and use
WebSearch to research known gotchas for that technology
If .feature-flow.yml does not exist, offer to create it via auto-detection:
- Detect platform and stack from project files (see
../../references/auto-discovery.md)
- Present detected context to user and ask for confirmation
- If confirmed, write
.feature-flow.yml and continue with the detected context
- If declined, proceed with the base checklist only
See ../../references/project-context-schema.md for the full schema documentation.
Step 3: Explore the Codebase (Tagged Domains)
Launch parallel exploration agents to understand the areas affected by the design. Organize results into 5 tagged domains so each verification batch (Step 4) receives only its relevant context instead of the full exploration dump.
Use the Task tool with subagent_type: "Explore" and model: "haiku" (see ../../references/tool-api.md — Task Tool).
Announce before dispatching: "Dispatching 5 exploration agents in parallel: schema, pipeline, ui, config, patterns."
Dispatch all 5 domain agents in a single message (parallel):
- Schema agent — Migration files, ORM models, type definition files (
*.d.ts, types.ts)
- Pipeline agent — API route files, hook files, pipeline files, shared type consumers
- UI agent — Component files, layout files, navigation components
- Config agent —
tsconfig.json, eslint config, next.config.*, package.json
- Patterns agent — Directory structure (2-3 representative paths), naming convention samples (2-3 files), error handling examples
Expected output per agent: Each agent returns free-form text describing what it found. The orchestrator slots each agent's text output into exploration_results by the domain it was dispatched for (schema, pipeline, ui, config, or patterns). The orchestrator assigns the domain key — agents do not self-report it.
Failure handling: If an agent fails, retry it once. If it fails again, use an empty string for that domain's content and log a warning: "[domain] exploration failed — that domain's context will be absent from relevant batch agents." If an agent succeeds but finds no relevant files for the project (e.g., a UI-less CLI project has no component files), treat its output as an empty string — this is correct and safe to pass to batch agents.
Aggregate results into exploration_results:
exploration_results = {
schema: <content from schema agent>,
pipeline: <content from pipeline agent>,
ui: <content from ui agent>,
config: <content from config agent>,
patterns: <content from patterns agent>
}
Step 4: Run Verification Checklist
Dispatch parallel verification agents to check the design against the codebase. Each agent handles a thematic batch of checklist categories.
Read references/checklist.md for the full detailed checklist. The checklist is partitioned into 8 batches (6 using <!-- batch: N --> markers in checklist.md, plus Batch 7 defined inline below, plus Batch 8 conditionally dispatched when design_preferences is present):
| Batch | Agent | Categories |
|---|
| 1 | Schema & Types | 1. Schema Compatibility, 2. Type Compatibility |
| 2 | Pipeline & Components | 3. Pipeline/Flow, 4. UI Component Inventory, 5. Cross-Feature Impact |
| 3 | Quality & Safety | 6. Completeness, 7. Cost & Performance, 8. Migration Safety |
| 4 | Patterns & Build | 9. Internal Consistency, 10. Pattern Adherence, 11. Dependencies, 12. Build Compatibility |
| 5 | Structure & Layout | 13. Route & Layout Chain, 14. Structural Anti-Patterns |
| 6 | Stack/Platform/Docs | 15. Stack-Specific, 16. Platform-Specific, 17. Project Gotchas, 18. Documentation Compliance |
| 7 | Implementation Quality | 19. Type Narrowness, 20. Error Strategy Completeness, 21. Function Complexity Forecast, 22. Edge Case Enumeration, 23. Stack Pattern Compliance |
| 8 | Design Preferences | 24. Design Preferences Compliance |
| 9 | External Assumptions | 25. External Assumptions |
assumptions-only flag: If assumptions-only is present in ARGUMENTS, skip Batches 1–8 entirely and run only Batch 9. Announce: Running assumption verification only (Batches 1-8 skipped). Then proceed directly to Batch 9 dispatch below.
Verification depth filtering: Before dispatching, consult the Verification Depth table below. Only dispatch batches containing at least one applicable category for the design's scope. Pass the list of applicable categories to each agent so it skips non-applicable categories within its batch.
Dispatch
Use the Task tool with subagent_type: "Explore" and model: "sonnet" for Batches 1-5 and Batch 7 (see ../../references/tool-api.md — Task Tool for correct parameter syntax). Launch all applicable batch agents in a single message to run them concurrently. Announce: "Dispatching N verification agents in parallel..." (If assumptions-only is in ARGUMENTS, only Batch 9 is dispatched — see the assumptions-only flag above.)
Context passed to each agent:
Universal context (every batch):
- The full design document content
- Its assigned checklist categories (partitioned from
references/checklist.md using batch markers)
- The
.feature-flow.yml content (for stack/platform/gotchas context)
- The list of applicable categories for this batch (from verification depth filtering)
In addition to the universal context above, each batch receives the following domain-filtered sections from exploration_results (produced by Step 3). Empty strings from agents that find no relevant files or that failed are passed as-is — no conditional logic required. Include the relevant domain values as named sections in the agent's prompt (e.g., ## Schema Exploration\n[content]):
| Batch | exploration_results sections included |
|---|
| 1 — Schema & Types | schema |
| 2 — Pipeline & Components | pipeline + ui |
| 3 — Quality & Safety | schema + config + patterns |
| 4 — Patterns & Build | patterns + config |
| 5 — Structure & Layout | ui |
| 6 — Stack/Platform/Docs | (see Batch 6 section below) |
| 7 — Implementation Quality | schema + patterns |
| 9 — External Assumptions | (no exploration_results sections — Batch 9 uses live fetching via WebFetch/WebSearch) |
Expected return format per agent:
Each agent returns a list of results, one per category checked:
[{ category: string, status: "PASS" | "FAIL" | "WARNING", finding: string }]
Batch 6 — Conditional Dispatch
Batch 6 (Stack/Platform/Docs) is only dispatched if .feature-flow.yml exists with a non-empty stack, platform, or gotchas field, or if Context7 is available (see ../../references/tool-api.md — Context7 MCP Tools for availability check). If none of these conditions are met, skip Batch 6 entirely. When the conditions are met, use the Task tool with subagent_type: "Explore" and model: "sonnet" for Batch 6 and include it in the same single-message launch as Batches 1-5 and 7 so all agents run concurrently.
Context passed to the Batch 6 agent:
- The full design document content
- The check instructions for categories 15-18 (defined inline below in this SKILL.md, not from checklist.md)
- The
.feature-flow.yml content (stack, platform, gotchas, context7 field) and stack reference files
- The list of applicable categories for this batch (from verification depth filtering)
- (No
exploration_results sections — Batch 6 operates on project config files and documentation, not codebase exploration results)
Batch 6 sources its check instructions from this SKILL.md (not from checklist.md):
-
Stack-Specific Checks — Run every check from the loaded stack reference files (e.g., Supabase PostgREST limits, Next.js server/client boundaries)
-
Platform-Specific Checks — Run checks from the platform reference file (e.g., mobile backward compatibility, feature flag requirements)
-
Project Gotchas — Check every entry in .feature-flow.yml gotchas against the design. Each gotcha is a mandatory verification item.
-
Documentation Compliance (Context7) — If .feature-flow.yml has a context7 field and the Context7 MCP plugin is available, verify the design uses current patterns from official documentation. Query relevant Context7 libraries for the specific patterns the design proposes (auth flows, data fetching, client setup, etc.) and check for:
If Context7 is not available, skip category 18 and note: "Context7 not available — documentation compliance check skipped."
Batch 7 — Implementation Quality
Batch 7 checks whether the design's proposed implementation can meet the coding standards in references/coding-standards.md. It is always dispatched (universally applicable to all design scopes). Use the Task tool with subagent_type: "Explore" and model: "sonnet". Include it in the same single-message launch as Batches 1-6 and Batch 8 (if dispatched) so all agents run concurrently.
Context passed to the Batch 7 agent:
- The full design document content
- The check instructions for categories 19-23 (defined inline below)
- The
schema and patterns sections from exploration_results (per the Context Filter Map above)
- The relevant sections from
references/coding-standards.md (extracted using <!-- section: slug --> markers)
Batch 7 categories:
-
Type Narrowness Audit — Check every type mentioned or implied in the design:
-
Error Strategy Completeness — Check every external call and user input point:
-
Function Complexity Forecast — Check proposed operations for complexity:
-
Edge Case Enumeration — Check for completeness of edge case handling:
-
Stack Pattern Compliance — Check against loaded stack reference files:
Batch 8 — Conditional Dispatch (Design Preferences)
Batch 8 (Design Preferences) is only dispatched if .feature-flow.yml exists and the design_preferences key is present (regardless of value). If design_preferences is absent, skip Batch 8 entirely. When the condition is met, use the Task tool with subagent_type: "Explore" and model: "sonnet" for Batch 8 and include it in the same single-message launch as Batches 1-7 so all agents run concurrently.
Context passed to the Batch 8 agent:
- The full design document content
- The check instructions for category 24 (from
references/checklist.md — look for the <!-- batch: 8 --> marker)
- The codebase exploration results from Step 3
- The
.feature-flow.yml content (specifically the design_preferences field values)
Batch 9 — Conditional Dispatch (External Assumptions)
Batch 9 (External Assumptions) is conditionally dispatched based on the content of the design document. Before dispatching, scan the design document text for any of the following signals:
- URLs: Any string matching
https:// (external service references)
- OAuth keywords: Any of
oauth, oidc, smart, .well-known (case-insensitive)
- Cross-service phrases: Any of
same as, like we did for, reuse the (case-insensitive)
- API endpoint patterns: Any of
/api/, /v1/, /v2/, /v3/ (REST endpoint path fragments)
If no signals are detected: Skip Batch 9 entirely. Add Category 25 to the results as:
{ "category": "25. External Assumptions", "status": "PASS", "finding": "No external service references detected — assumption verification not required." }
Do not log a warning — this is the expected path for internal-only designs. If assumptions-only is active and no signals are detected, present a brief report with only the Category 25 PASS result: "No external assumptions found to verify." Skip the full report template.
If signals are detected: Dispatch a single Batch 9 agent using the Task tool with subagent_type: "Explore" and model: "sonnet". In the normal flow, include it in the same single-message launch as Batches 1-8 so all agents run concurrently. If assumptions-only is active, dispatch Batch 9 as a standalone single-agent message (no other batches to co-dispatch).
Context passed to the Batch 9 agent:
- The full design document content
- The check instructions for Category 25 (from
references/checklist.md — look for the <!-- batch: 9 --> marker)
- The full content of
references/assumption-patterns.md
- The full content of
references/discovery-endpoints.md
- The
.feature-flow.yml content (for project context)
- The list of detected signals (URLs, OAuth keywords, cross-service phrases, API patterns found in the design)
Agent behavior:
The Batch 9 agent has access to WebFetch and WebSearch. It should:
- For each detected signal, identify which assumption pattern(s) from
assumption-patterns.md apply
- Fetch live discovery documents or API specs where applicable (using endpoints from
discovery-endpoints.md)
- Compare the fetched facts against the design's stated assumptions
- Return results in the standard format:
[{ "category": "25. External Assumptions", "status": "PASS" | "FAIL" | "WARNING", "finding": "string" }]
If multiple distinct assumptions are verified, return one result object per assumption checked (each with category: "25. External Assumptions"). The orchestrator merges all into the unified report.
(No exploration_results sections are passed to Batch 9 — it operates on live-fetched API contracts, not codebase exploration results.)
Failure Handling
If an agent fails or crashes, retry it once. If it fails again, skip it and log a warning: "Batch N ([agent name]) failed — categories X-Y skipped. Continuing with available results." Do not stall verification for a single agent failure.
Consolidation
After all agents complete, merge results into the unified report table (same format as Step 5). Sort by category number. If a batch was skipped due to failure, add each of its categories to the report as status "SKIPPED" with finding: "Verification agent failed after retry — this category was NOT checked." In the summary, count SKIPPED categories separately and add a warning: "N categories could not be verified. Review these areas manually before proceeding." After consolidation, run the Scope critique pass (see ### Step 4.5: Scope critique below) — unless assumptions-only is active, in which case skip it (strategic critique is out of scope for assumption-only mode). Append the pass's findings block to the report, and for every row with status BLOCKER add one entry to the Step 5 ### Blockers list formatted as [Scope critique Q<N>] <finding>, before proceeding to Step 5.
Step 4.5: Scope critique
Run after Step 4 verification batches complete (codebase context already loaded). Ask five strategic-shape questions about the design's scope, dependencies, and observability. See references/scope-critique.md for the full prompt text, expanded red-flag list, and bias-resistance checklist.
When to run: Always, except when assumptions-only is active (assumption verification is a targeted mode; strategic critique is out of scope).
Five checklist questions:
- Should this exist in its current shape? Restate the problem in the reviewer's own words. Is it real and current, or speculative?
- Could it ship smaller? Count independent deliverables. For each declared dependency, verify by inspecting the referenced files — don't trust the description.
- Is there a simpler version? Documentation / config flag / soft hint / deletion that captures most of the value.
- Observability sanity. If the design gates on a capability unobservable from hooks/skills/APIs, flag for deferral or explicit proxy documentation.
- Config surface review. For each new config key: would anyone realistically flip this? If no, hardcode or drop.
Output: Append a ### Scope critique findings table to the design-verification report (format defined in references/scope-critique.md). Any BLOCKER-severity row is promoted to the top-level ### Blockers list per the Step 4 Consolidation call-out above (labelled [Scope critique Q<N>]).
Step 5: Report Findings
Present a structured report:
## Design Verification Report
**Design:** [path to design doc]
**Date:** [current date]
### Results
| # | Category | Status | Finding |
|---|----------|--------|---------|
| 1 | Schema Compatibility | FAIL | `keyword_phrase` is NOT NULL but design assumes nullable |
| 2 | Type Compatibility | FAIL | `SearchResult.service_id` is `string`, not `string \| null` |
| 3 | Pipeline Compatibility | WARNING | `useSearchPipeline` Phase 1 assumes service/location IDs |
| 4 | UI Components | PASS | All required components exist or are planned |
| ... | ... | ... | ... |
Before declaring a blocker, consider calling `advisor()` to sanity-check the blocker interpretation. Advisor sees the full design doc and codebase context.
### Blockers (FAIL — must fix before implementation)
1. [specific issue with exact file paths and line numbers]
2. [specific issue]
### Warnings (should address, not blocking)
1. [specific concern]
### Gaps (missing from design)
1. [what the design doesn't cover but should]
### Recommended Design Doc Updates
[Specific edits to make to the design document]
Step 6: Apply Corrections
If the user approves, update the design document with corrections:
- Add missing migration requirements
- Fix incorrect assumptions about column types or nullability
- Add sections for gaps (e.g., missing error handling, missing UI adaptations)
- Update counts and references to be accurate
Confirm each change with the user before applying.
YOLO behavior: If yolo: true is in the skill's ARGUMENTS, skip per-change confirmation. Auto-apply all recommended corrections and announce: YOLO: design-verification — Apply corrections → All corrections applied
Step 7: Write Back Gotchas
Review all FAIL and WARNING findings from the verification. Identify any that represent reusable project-specific pitfalls — issues that could bite future features, not just this one.
What qualifies as a gotcha:
- A constraint or limit discovered in the codebase that isn't obvious (e.g., a NOT NULL column that most designs would assume is nullable)
- An API or service behavior that contradicts common assumptions (e.g., silent truncation, undocumented rate limits)
- A pattern in the codebase that new features must follow but wouldn't be obvious to discover
What does NOT qualify:
- One-time design mistakes (e.g., "design said 5 columns but table has 6")
- Findings already covered by a stack reference file (e.g., PostgREST 1000-row limit is already in supabase.md)
If any qualifying gotchas are found, present them:
I found findings that could prevent future bugs if added to your project gotchas:
1. "[specific gotcha phrased as a warning]"
2. "[specific gotcha]"
Add these to .feature-flow.yml?
Use AskUserQuestion with options:
- "Add all" with description: "Recommended — adds every finding to .feature-flow.yml as a project-wide warning for future sessions"
- "Let me pick" with description: "Choose which findings to persist — you'll be prompted one at a time"
- "Skip" with description: "Discard all findings — none will be saved to .feature-flow.yml"
YOLO behavior: If yolo: true is in the skill's ARGUMENTS, skip this question. Auto-select "Add all" and announce: YOLO: design-verification — Add gotchas → Add all ([N] gotchas added)
If approved, append to the gotchas list in .feature-flow.yml. If the file doesn't exist, create it first using auto-detection (see ../../references/auto-discovery.md).
Verification Depth
Adjust depth based on the design's scope:
| Design Scope | Depth |
|---|
| New page with new data model | Full checklist (all 14 base categories + stack/platform/gotchas + doc compliance + implementation quality 19-23 + Category 24 if design_preferences present) |
| New API route, existing data model | Categories 1-3, 5, 7-8, 10-12, 14, 18-23 + stack/platform/gotchas + Category 24 if design_preferences present |
| UI-only change, no schema changes | Categories 4-6, 9-10, 12-14, 19-23 + platform/gotchas + Category 24 if design_preferences present |
| Configuration or env change | Categories 7, 10-12, 14, 19-23 + stack/gotchas + Category 24 if design_preferences present |
Note: Category 25 (External Assumptions) is scope-independent — it is triggered by content signals in the design document, not by design scope. Always evaluated if signals are present, regardless of which row above applies.
Note: Step 4.5 (Scope critique) is also scope-independent — it runs for every design at every depth, except when assumptions-only is active. It is governed by its own run-condition, not by the table rows above.
Quality Rules
- Evidence-based: Every FAIL must include the exact file path, line number, and current value that conflicts with the design
- Actionable: Every finding must include a specific recommendation for how to fix it
- No false alarms: Only flag real conflicts. Do not flag theoretical concerns that are unlikely to occur.
- Complete: Check every proposed change in the design, not just the obvious ones
Additional Resources
Reference Files
For the full detailed verification checklist with specific checks per category:
references/checklist.md — Base verification checklist with 14 categories (Batches 1-5) plus Category 24 as Batch 8. Batches 6 (categories 15-18) and 7 (categories 19-23) are defined inline in this SKILL.md.
references/assumption-patterns.md — Verification patterns for Batch 9 (OAuth/OIDC, REST APIs, cross-service equivalence, data relationships, library APIs, environment, prior session, codebase)
references/discovery-endpoints.md — Known discovery endpoints for FHIR, OAuth/OIDC, REST (OpenAPI), GraphQL, gRPC, and cloud services (AWS, GCP, Azure, Vercel, Supabase)
For project context and stack/platform-specific checks:
../../references/project-context-schema.md — Schema for .feature-flow.yml
../../references/stacks/ — Stack-specific verification checks (supabase, next-js, react-native, vercel)
../../references/platforms/ — Platform-specific lifecycle adjustments and checks (mobile, web)