From prd2impl
Codebase vs PRD gap analysis — scan existing code against structured PRD requirements to identify what's implemented, partial, or missing. Use when the user says 'gap scan', 'what's missing', 'scan codebase', or after /prd-analyze.
How this skill is triggered — by the user, by Claude, or both
Slash command
/prd2impl:skill-2-gap-scanThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<SUBAGENT-STOP>
Automatically scan the existing codebase against PRD requirements to identify implementation gaps. This is the second step of the prd2impl pipeline.
/gap-scan/prd-analyze has produced prd-structure.yaml{plans_dir}/*-prd-structure.yaml (output from skill-1 or skill-0)If prd-structure.yaml doesn't exist, prompt the user to run /prd-analyze or /ingest-docs first.
Path resolution: Before constructing any output path, resolve
{plans_dir}perlib/plans-dir-resolver.md. Alldocs/plans/references below (exceptdocs/plans/project.yaml, which stays at repo root) are relative to that resolved directory.
{plans_dir}/*-prd-structure.yaml1a. Check for existing gap analysis:
{plans_dir}/*-gap-analysis.yaml. If found, load it into memory as existing_gap_analysis.For each module in the PRD structure:
File Discovery: Use Glob to find files matching the module's expected location
Feature Coverage: For each user story in the module:
Classify Coverage:
coverage:
- story_id: US-001
status: implemented # implemented | partial | missing
evidence:
- file: "autoservice/conversation_engine.py"
line: 42
match: "class ConversationEngine"
- file: "tests/test_engine.py"
line: 10
match: "def test_conversation_flow"
missing_criteria:
- "AC-003: Sentiment display not found"
confidence: high # high | medium | low
NFR Check: For each NFR:
Check external dependencies status:
Check internal module dependencies:
Subagents writing new code should follow project-wide patterns
rather than reinventing them. Extract recurring patterns into a
cheat-sheet that skill-3-task-gen inlines into every task's context
block. Without this step, subagents in skill-8 dispatch produce
code that re-invents what's already in the project — see AutoService
PV2 pipeline_v2/kb_mcp/ (commit f82c22e deleted it as duplicate
of cc_pool.py:691).
Patterns to grep:
datetime.utcnow() vs time.time() vs
ISO string. Capture the dominant pattern + 2 example file:line.uuid.uuid4(), secrets.token_urlsafe(N),
custom prefix scheme. Capture pattern + N + example.class FooError(BaseError)). List top 5 by
reference count._reset_*_db_for_tests patterns,
conftest.py scope conventions.logger = logging.getLogger(__name__)),
structured log helper if any.httpx.Client() vs project-
scoped wrapper; auth header injection convention.cc_pool.py:691-style build_kb_mcp_server). New MCP tasks
should reuse, not duplicate.Output: write to {plans_dir}/conventions.md:
# Project conventions (extracted by skill-2-gap-scan)
Generated: 2026-05-09
Inputs scanned: autoservice/, channels/, plugins/
## Timestamps
- Format: ISO 8601 strings (`datetime.utcnow().isoformat()`)
- Source: autoservice/customer_manager.py:42, autoservice/crm.py:118
- Avoid: epoch ints, naive datetimes
## ID generation
- Pattern: `secrets.token_urlsafe(36)`
- Source: autoservice/customer_manager.py:42
## Error types
- Base: `AutoServiceError` (autoservice/errors.py:5)
- Top inheritors: TenantError, ChannelError, ContractError
## MCP server registration
- Pattern: per-tenant auto-inject via `cc_pool.py:691` `build_kb_mcp_server(tenant_id) -> MCPServer`
- Reuse rule: any new MCP need should hook into this auto-inject path,
NOT duplicate the bootstrap. (PV2 kb_mcp/ duplicate-of-cc_pool
failure mode.)
(... continued for each pattern ...)
This file becomes a stable input to skill-3-task-gen Step 4 (which reads it and inlines relevant entries into each task's context block).
Produce structured output:
gap_analysis:
scan_date: "2026-04-17"
prd_source: "{plans_dir}/2026-04-17-prd-structure.yaml"
summary:
total_stories: 45
implemented: 28
partial: 10
missing: 7
coverage_pct: 62
by_module:
- module: MOD-01
stories_total: 12
implemented: 8
partial: 3
missing: 1
coverage_pct: 67
gaps:
- id: GAP-001
story_id: US-015
module: MOD-03
description: "Billing module not yet implemented"
gap_type: missing # missing | partial | outdated
missing_parts:
- "Tiered pricing calculation"
- "Invoice generation"
- "Payment gateway integration"
estimated_effort: medium # small | medium | large
depends_on_gaps: [] # Other gaps this depends on
- id: GAP-002
story_id: US-008
module: MOD-02
description: "SLA monitoring partially implemented — alerting missing"
gap_type: partial
existing_code:
- "autoservice/sla_aggregator.py"
missing_parts:
- "Alert dispatch to Feishu/Slack"
- "Escalation rules engine"
estimated_effort: small
nfr_gaps:
- nfr_id: NFR-03
status: unknown
note: "No performance tests found for API latency requirement"
dependency_gaps:
- dep_id: DEP-02
status: missing
note: "Payment gateway SDK not installed"
If existing_gap_analysis is loaded (merge mode):
For each gap in existing_gap_analysis.gaps:
coverage_evidence:
existing_code: [...] # Relevant files found
status: implemented|partial|missing
confidence: high|medium|low
source_id, description, priority, missing_parts, estimated_effort, depends_on_gapsgap_type from the fresh scan: if coverage_evidence.status is missing, set gap_type: missing; if partial, set gap_type: partial; if implemented, remove the gap or mark it gap_type: resolved. This prevents stale human classifications from contradicting fresh scan evidence.For any user stories in prd_structure NOT covered by existing gaps:
story_id == user_story.id. If a gap has no story_id field, fall back to matching gap.module == user_story.module AND the gap's description mentions the story's action keyword.Add a scan_summary section to the output YAML:
scan_summary:
scan_date: "2026-06-11"
coverage_pct: 62
by_module:
- module: MOD-01
stories_total: 12
implemented: 8
coverage_pct: 67
Set source_type: "ingested+scanned" in the output YAML
Write to {plans_dir}/{date}-gap-analysis.yaml
Print merge-mode summary to terminal:
Gap Analysis Complete (merge mode)
==================================
Existing gaps: 18 (enriched with coverage data)
New gaps found: 3
Coverage: 62% (28/45 stories implemented)
By Module:
MOD-01 Conversation Engine ████████░░ 67% (8/12)
MOD-02 SLA Monitoring ██████░░░░ 60% (6/10)
MOD-03 Billing ░░░░░░░░░░ 0% (0/8)
...
NFR Gaps: 3 items need verification
Dependency Gaps: 1 missing SDK
If NO existing gap analysis (full scan mode):
{plans_dir}/{date}-gap-analysis.yamlsource_type: "scanned" in the output YAMLGap Analysis Complete (full scan)
=================================
Coverage: 62% (28/45 stories implemented)
By Module:
MOD-01 Conversation Engine ████████░░ 67% (8/12)
MOD-02 SLA Monitoring ██████░░░░ 60% (6/10)
MOD-03 Billing ░░░░░░░░░░ 0% (0/8)
...
Gaps Found: 17
Missing: 7 (need full implementation)
Partial: 10 (need completion)
NFR Gaps: 3 items need verification
Dependency Gaps: 1 missing SDK
STOP here. Present the gap report and wait for user review.
Gap analysis complete. {N}% coverage, {M} gaps identified.
Review
{plans_dir}/{date}-gap-analysis.yamland confirm:
- Are there implemented features I missed? (false negatives)
- Are there gaps that should be descoped? (won't implement)
- Any gaps that are actually blocked on external dependencies?
See the chain hint below for next steps.
───────────────────────────────────────────────────── ⬆ /gap-scan complete ─────────────────────────────────────────────────────
📋 Next: /task-gen — Generate task list from gap analysis /plan-schedule — Create execution plan with batches (if tasks.yaml exists) ─────────────────────────────────────────────────────
Creates, edits, and verifies skills using a test-driven development approach with pressure scenarios and subagents.
npx claudepluginhub ezagent42/prd2impl --plugin prd2impl