Plan Authoring Guide

SkillAI & models

Reference material for writing implementation plans (technical context, architecture decisions, data models, API contracts, project-instructions alignment). Loaded on demand by `plan-feature`; not directly invokable.

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Plan Authoring Guide skill

What this skill tells your AI

The instructions your AI receives, as published by attilaszasz/sdd-pilot in .github/skills/plan-authoring/SKILL.md and read by ahel’s review.

Agent-First Format Rule

Every plan.md section MUST use tables, key-value pairs, or tagged lists as primary format. Prose is limited to the Summary section (max 3 key-value lines). The primary consumer is an AI agent — optimize for parseability over readability.

Plan Writing Process

Phase 0: Research

  1. HAS_TECH_CONTEXT_DOC = true → read as baseline; pre-fill Technical Context values, require only confirmation.
  2. Extract unknowns (anything marked NEEDS CLARIFICATION) → research task per unknown.
  3. Consolidate in research.md using structured format below. Merge by topic, rewrite full file.
  4. Budget: ≤4KB. Existing >3KB → consolidate before adding.
research.md Format

Prohibited: code blocks, implementation snippets, comparison tables, narrative paragraphs, duplicate summary sections.

Per-topic: 4 structured fields, max 2 sources. Global budget: ≤4KB.

Consolidation: merge overlapping topics, normalize names, remove stale details.

Structure:

# Research: [Feature Name]
> Feature | Date | Purpose

## [Topic N]
- **Decision**: [what was chosen]
- **Rationale**: [why — max 1 sentence]
- **Rejected**: [alternatives and why — max 1 sentence]
- **Pitfalls**: [anti-patterns to avoid — max 1 sentence]
- **Sources**: [URL1], [URL2]

## Summary
| Topic | Decision | Rationale |
|-------|----------|-----------|

## Sources Index
| URL | Topic | Fetched |
|-----|-------|---------|

Phase 1: Design & Contracts

Prerequisites: research.md complete

Items 1–2 are conditional — auto-detect signals from spec; fall back to interactive prompt when ambiguous.

  1. Data Model → data-model.md (conditional):

    • Generate when: non-empty "Key Entities", terms database/storage/persist/CRUD/entity/etc., or Storage ≠ N/A
    • Skip → replace Data Model Summary table with N/A — no persistent data
    • Include: entity names, fields, relationships, validation rules, state transitions
    • Populate ## Data Model Summary table in plan.md with entity overview
  2. API Contracts → contracts/ (conditional):

    • Generate when: terms API/endpoint/route/REST/GraphQL/HTTP/webhook/etc., or Project Type = web/mobile
    • Skip → replace API Surface Summary table with N/A — no API surface
    • Map user actions → endpoints; use REST/GraphQL patterns; output OpenAPI/GraphQL schemas
    • Populate ## API Surface Summary table in plan.md with endpoint overview

Instructions Check

  • Read project-instructions.md
  • Validate every plan decision against project instructions principles
  • If violations exist that must be justified, add a "## Complexity Tracking" section to plan.md with a table: | Violation | Why Needed | Simpler Alternative Rejected Because |. If no violations exist, omit the section entirely.
  • GATE: Must pass before research. Re-check after design.
  • Auditor outputs are transient gate checks; report status/decisions in plan.md without pasting full Auditor reports.

Artifact Conventions

Runtime rules: AGENTS.md §Artifact Conventions. Consult the expanded reference only for exceptions or remediation details not covered by the primer.

  • plan.md ≤ 10KB — Architecture: target 8-12 nodes, hard cap 15
  • Conditional sections: populate table OR replace with N/A — [reason]. Never leave template placeholders.
  • Mermaid: C4 syntax, Container/Component views, <br> for breaks (never \n)
  • Default to Container view; use Component view only if internals matter
  • C4 labels: names 1-3 words; short type fields; descriptions optional, max 4 words
  • Relationship labels: short verbs only; omit obvious labels
  • Exclude helpers and commodity infrastructure from the main view
  • Do NOT remove Instructions Check, Technical Context, or Requirement Coverage Map sections
  • Do NOT change Architecture Decision IDs (AD-###) — they may be referenced by tasks
  • [NEEDS CLARIFICATION] → resolve only with user-approved answers
  • Preserve all cross-referenced IDs (AD-###, HINT-###)

Technical Context Fields

The plan template captures these metadata fields:

FieldExampleNotes
Language/VersionPython 3.11Or "NEEDS CLARIFICATION"
Primary DependenciesFastAPIFrameworks, libraries
StoragePostgreSQLOr "N/A" if no persistence
TestingpytestTest framework
Target PlatformLinux serverOr iOS 15+, WASM, etc.
Project Typesingle/web/mobileDetermines source structure
Project Modegreenfield/brownfield/mixedDetermines structure approach
Performance Goals1000 req/sDomain-specific
Constraints<200ms p95Domain-specific
Scale/Scope10k usersDomain-specific

These same fields should also appear in the project-level Technical Context Document when one is maintained.

Testing Strategy Configuration

Populate ## Testing Strategy table in plan.md. Each row maps a testing tier to its tool, scope, mock boundary, and install command.

Tiers to cover

TierPurpose
UnitIsolated logic tests
IntegrationCross-component / API tests
SecurityVulnerability scanning (code + dependencies)
CoverageCode coverage measurement

Rules

  1. Delegate to Technical Researcher during planning Step 4.5 for detected tech stack.
  2. Consider: language/version, framework, dependency manager, existing tool configs.
  3. Prefer: widely adopted, actively maintained, single-command install.
  4. Existing config → Install column = configured.
  5. N/A tier → include row with rationale in Scope column (e.g., N/A — no external dependencies).
  6. Include ready-to-run install commands for tools not yet present.

Acceptance Test Stubs

Populate ## Acceptance Test Stubs in plan.md when at least one P1 requirement exists. This gives every P1 requirement a runnable RED→GREEN acceptance target so the Developer gets a per-requirement pass/fail signal during /sddp-implement instead of relying on lint/compilation alone. Replace the section body with N/A — no P1 requirements when the spec has no P1 work items.

Rules

  1. One row per P1 requirement (FR-###/TR-###/OR-###/RR-###). P2/P3 requirements are not stubbed (the size budget and the issue scope are P1-only).
  2. Req ID MUST match a requirement from spec.md that is tagged P1.
  3. Test File follows the project's Testing Strategy Unit tier convention — co-located with the implementation file (e.g. src/foo.test.ts) or in a sibling tests/ directory (e.g. tests/test_foo.py). Choose one convention per project and keep it consistent across rows.
  4. Stub Blocks (framework-native) uses the syntax of the Unit tier tool from ## Testing Strategy (e.g. describe('FR-001 user registration') / it('rejects duplicate emails') for Jest/Vitest, func TestFR001_RejectsDuplicateEmails(t *testing.T) for Go, def test_FR001_rejects_duplicate_emails(): for pytest). Each block name embeds the reqID so the Developer and the Story Verifier can trace failures back to a requirement.
  5. RED Status records how the stub fails before any implementation exists: pending (skip/todo marker), failing-assertion (an assertion that cannot pass until the requirement is implemented), or skip (framework skip marker). Pick the idiomatic one for the Unit tier tool.
  6. Do NOT include test bodies that pin specific implementation details — stubs are acceptance targets (behavior-level), not unit-test mandates. The Developer fills in assertions as part of implementation; the stub only fixes the names and the failing state.
  7. Source the requirement set from the same P1 work items that will be tagged 🎯 MVP in tasks.md; the Requirement Coverage Map File Path(s) column informs the Test File path for each row.
  8. Do NOT remove the ## Acceptance Test Stubs section once present — it is consumed by /sddp-tasks (emits a stub-creation task per row) and /sddp-implement (parses it into STUB_MAP to feed the Developer). reqID links are stable and subject to the cross-referenced ID preservation rules.

Error Handling Strategy

Populate ## Error Handling Strategy table when the feature has API endpoints, external service calls, or user-facing error states. Skip (replace with N/A) for pure libraries, CLI tools with simple exit codes, or infrastructure-only features.

Columns

ColumnContent
Error CategoryDomain grouping (Validation, Auth, Downstream, Internal)
PatternStrategy (fail-fast, circuit breaker, retry, fallback)
ResponseWhat the caller sees (status code + body shape, log level, alert)
Retryyes/no + policy (exponential, fixed, none)

Architecture Decisions

Populate ## Architecture Decisions table during Phase 0 (Research) and Phase 1 (Design). One row per non-trivial feature-local technical choice.

Rules

  1. ID format: AD-### (sequential, zero-padded 3 digits).
  2. Every row: question asked, options evaluated, choice made, rationale.
  3. Tasks may reference decisions via {AD-###} tag (optional, not required).
  4. Do NOT duplicate decisions already captured in the Technical Context Document or standalone ADRs under specs/adrs/ — reference them instead (e.g., "See ADR-0001").
  5. AD-### rows are for feature-local tradeoffs only. Decisions with project-wide architectural impact must become standalone ADRs created through the ADR Author subagent (.github/agents/_adr-author.md), not AD rows.
  6. When referencing a global ADR from a feature plan, cite the canonical ADR ID (e.g., ADR-0001) in the rationale column — do not copy the decision into an AD row.

Requirement Coverage Map

Populate ## Requirement Coverage Map table after design. Every FR-###, TR-###, OR-###, and RR-### from spec.md must have a row.

Rules

  1. Map each requirement to the component(s), file path(s), and the exported function(s)/symbol(s) with key signature hints that will implement it. Example: UserModel(id,email,role), Checkout.run(), validateJwt(token).
  2. Source the Function(s)/Symbol(s) column from data-model.md entities, contracts/ schemas, architecture decisions, or named API/service surfaces when no design artifact exists. Avoid generic placeholders like "TBD" — if a symbol cannot be named yet, the design is incomplete; resolve before writing the row.
  3. The full row — Req ID → Component(s) → File Path(s) → Function(s)/Symbol(s) — is the traceability matrix. It is the primary input for /sddp-tasks (task generation derives → exports: annotations from the symbol column) and for the Developer's per-task self-verification during /sddp-implement.
  4. Missing requirement, empty File Path(s), or empty Function(s)/Symbol(s) → flag as gap during Plan Readiness Check.
  5. The Story Verifier at QC reads this matrix as its starting traceability map but re-verifies authoritatively against the implemented code; the matrix is a hint, not a substitute for QC.
  6. The Plan gate reads these columns by header name. Existing four-column maps using Requirement, File Path(s), Function(s)/Symbol(s), and Decision remain supported.

Risk Mitigation

Populate ## Risk Mitigation table by mapping each risk from spec.md Assumptions & Risks to a concrete technical mitigation.

Rules

  1. One row per risk from spec. Preserve spec wording in Risk column.
  2. Mitigation = specific technical action (not "monitor" or "be careful").
  3. Owner = component or team responsible for the mitigation.

Implementation Hints

Populate ## Implementation Hints with max 5 tagged items. Each captures a non-obvious constraint, gotcha, or order-sensitive operation that the implementing agent needs.

Format

- **[HINT-###]** Category: detail

Categories: Order, Gotcha, Constraint, Compatibility, Performance.

Project Structure Options

By Project Type (greenfield)

  • Single project (default): src/, tests/ at root
  • Web application (frontend + backend detected): backend/, frontend/
  • Mobile + API (iOS/Android detected): api/, ios/ or android/

Brownfield / Mixed Mode

When Project Mode = brownfield or mixed:

  1. Scan existing project layout — do NOT impose a template structure.
  2. Show only new/modified paths: prefix + (new file) or ~ (modified file).
  3. Include Brownfield Notes block in template:
    • Patterns to reuse: existing patterns relevant to this feature
    • Tests to extend: existing test files/suites to add cases to
    • Naming conventions: observed conventions to follow
  4. Omit generic project initialization tasks.

Delete unused options from the template. The delivered plan must not include "Option" labels.

Template

Use the template at assets/plan-template.md.

Signals

GitHub stars
97
Forks
9
Last commit
Sep 2026
Advanced
Item type
skill
Key
plan-authoring
Source
github.com/attilaszasz/sdd-pilot