pm-feature-design
Just-In-Time technical design for a single feature, written immediately before build
/pm-feature-design FEAT-ORD-012▊When to use
Run once per feature, just before it enters build. Triggered by /pm-stripe when the feature is next in its Stripe and all dependencies are met (status: 1_Backlog → becomes 2_Spec_Done).
Do not run upfront for entire Feature Sets. This is JIT - one feature, right before build, not before.
What it produces
Enriches three Live Registers and populates three Feature Card sections in two atomic commits:
Commit 1 - register finalization:
domain/entities.md- exact guard conditions added to state transitions for this featuredomain/business_rules.md- rules this feature enforces moved from Draft → Finaldomain/decision_models.md- decision tables finalized
Commit 2 - feature design:
- Feature Card Section 1 (Business Constraints) - entity IDs, BR-IDs, TBL-IDs linked
- Feature Card Section 2 (Acceptance Criteria) - derived from register state + business rules
- Feature Card Section 3 (JIT Technical Design) - Mermaid.js sequence diagram + files to modify
- Feature Card Subtasks - nuance helpers captured during discovery
Sets status to 2_Spec_Done (or 2b_In_Design for frontend features awaiting Figma design).
How to invoke
/pm-feature-design FEAT-ORD-012 # standard run
/pm-feature-design FEAT-ORD-012 --agent # autonomous draft, requires review after
Dependencies
Required before running:
- Feature Card for this FEAT-ID (stub, created by
pm-features-list) pm-entity-registry-entities.mdmust existpm-business-rules-library-business_rules.mdanddecision_models.mdmust exist (at least Draft)
Produces for:
- Build skills (
/fullstack-guardian,/impeccable-craft, etc.) - Section 3 is the build spec they read pm-stripe- Impact Analysis reads BR-IDs from Section 1pm-feature-card- populates the card sections
Related skills: pm-feature-viability, pm-entity-registry, pm-business-rules-library, pm-decision-model, pm-process-flows, pm-feature-card, pm-stripe, pm-open-questions, pm-prototype
Open questions
A genuine judgment call, legacy-vs-code divergence, or concrete build blocker surfaced during Discovery Interrogation is logged directly in domain/open_questions.md (Live Register 5, pm-open-questions) - Type: Question / Divergence / Blocker. A Subtask is different: it's a nuance for the developer to handle during build, not something nobody has decided yet - keep the two separate.
Open items are pulled into view, not copied. At the start of the run (Step 0) and again at the design review (Step 5) the skill looks up every Open entry in the register that names this FEAT-ID and shows it as ID, heading, Type and Priority. An open BLK- keeps the feature from 3_Ready_to_Build; open OQ-/DIV- entries are shown, and the interrogation tries to resolve them. The card itself never lists them.
Prototype carry-over
Applies only when the Feature Card carries promoted_from: PRT-[NAME]-NNN or a prototype reference block - both written by pm-prototype, both left untouched here.
Read first, before the interrogation: the prototype's meta.md (purpose, classification, decision, what is simulated), its findings.md (what was observed, what was not tested, known distortions) and the PRT- card. If any of them cannot be found, the skill says so and continues without carry-over - it never reconstructs what the prototype "probably" showed.
Result: is checked before designing:
| Result | Effect on the design run |
|---|---|
pending | Surfaced before anything else - record the result via /pm-prototype first, or design with nothing treated as resolved |
Supported within scope | Resolved for the stated scope only |
Refuted within scope | Flagged before designing |
Prototype or study failure / Inconclusive | Nothing learned - nothing treated as resolved |
| Workbench prototype (no verdict) | Flow and scope decisions are settled; they are stakeholder alignment, not user evidence |
Two things are recorded in a ### Prototype carry-over subsection of Section 3:
- Resolved by the prototype - so the JIT design does not reopen a settled question. Each item traces to
findings.mdor thePRT-card. Anything the prototype simulated or did not test still gets the full interrogation, and the 6 edge case categories are always walked. - Changed against the prototype - every point where the production spec departs from the prototype's flow, states or measurement, with the reason. Mandatory for a Reference prototype even when the answer is
none: an undocumented divergence is how a Reference prototype quietly stops being binding.
The prototype folder is never edited from this skill - a change belongs in the Feature Card.
How it works
- Detects mode from
state.json- readsplaybook(Greenfield vs Feature Implementation) andteam_structure, set once at Phase 1 setup, and states the detected mode rather than re-asking. Only falls back to a question if a value is genuinely missing (e.g. a hand-created workspace). - Reads the Feature Card (stub at entry - frontmatter + empty sections)
- Discovery Interrogation - actively surfaces unknowns and ambiguities; calibrated to feature criticality; sorts findings into: new rules / new guard conditions / new ACs / subtasks. Criticality sets only the depth of probing - every feature, P3 CRUD included, walks all 6 edge case categories (
EC-INPUTinvalid input,EC-AUTHauthorization/ownership,EC-STATEentity state,EC-CONCconcurrency/idempotency,EC-EXTdependency failure,EC-CLIENTclient states for frontend features). Each category ends as an AC,N/Awith a feature-specific reason, or anOQ-entry when the right behavior is undecided. Also assesses the security dimension and sets thesecurity_reviewfrontmatter flag (none/build/review/both) by asking which security area the feature touches - 8 domain-neutral vulnerability areas (access control & tenant isolation, authentication & identity, cryptography & secrets, sensitive/regulated data, input & injection, external/server-side integration, abuse & enumeration, financial integrity), not a list of feature types. This is where pm-stripe later reads whether to routesecure-code-guardian/security-reviewer.buildonly when the feature creates a new mechanism in an area; merely reusing an existing Final security pattern does not warrant it. Also assesses the test type dimension and setstest_types(unit/integration/contract/visual_regression/performance) from the feature's characteristics (baselineunit, plus e.g.contractif consumed by an external client) - specializestest-masterrouting inpm-stripeinstead of leaving it a black box. - Enriches
entities.md- adds exact guard conditions to state transitions relevant to this feature - Enriches
business_rules.mdanddecision_models.md- finalizes rules this feature enforces (Draft → Final); adds brand-new rules via the single-rule helpers (pm-business-rule-core/critical/governance) - Populates Section 1 (Business Constraints) - links entity IDs, BR-IDs, TBL-IDs; defines explicit scope exclusions
- Writes Section 2 (Acceptance Criteria) - all in Given/When/Then: happy path, feature flag OFF, edge case ACs tagged
[EC-XXX]in the title, closed by an Edge Case Coverage table that resolves all 6 categories. The table is an index (AC-IDs / N/A reason / OQ-ID), never a restatement of the scenario - Writes Subtasks - nuance/spec details for the developer (these are helpers, not sub-features)
- Also sets
mutex_tagsin frontmatter from Section 3's "Files to modify" - the shared modules/classes this feature touches. The delivery plan (pm-stripe) uses these to stop two features editing the same code in parallel (critical with AI agents on separate branches). This is the moment the contention footprint is known.
- Also sets
- Generates Section 3 - Mermaid.js sequence diagram with real classes/methods from existing codebase; lists files to modify
- Pushes to Notion, sets status to
2_Spec_Done
Atomic commit protocol (registers committed before Feature Card - prevents merge conflicts in parallel Stripes):
Commit 1: "spec([FEAT-ID]): guard conditions + rule finalization"
Commit 2: "spec([FEAT-ID]): feature design complete"
Existing codebase mode: if the project has an existing codebase, Claude Code scans the relevant service files before generating the sequence diagram. The diagram must use only real existing classes and methods.
Feature Card status after this skill
| Feature type | Path |
|---|---|
| Backend / system feature | 1_Backlog → 2_Spec_Done → 3_Ready_to_Build |
| Frontend feature (Figma design needed) | 1_Backlog → 2_Spec_Done → 2b_In_Design → 3_Ready_to_Build |
Key rules
- Spec gate is hard. Sections 1-3 must be complete before any feature enters build. No exceptions.
- Register updates before code. Commit 1 (registers) always precedes Commit 2 (Feature Card). This prevents merge conflicts when multiple Stripes run in parallel.
- No invented interfaces. In existing codebase mode, the sequence diagram uses only real classes/methods. Never fabricate a service or method that doesn't exist.
- Flag OFF AC is mandatory. Every feature must have AC-03 verifying the feature flag OFF behavior. Flag OFF is not an edge case category - it stays its own AC.
- All 6 edge case categories, at every priority. Priority changes how many scenarios per category, never whether a category is considered. A missing category cannot be told apart from a deliberately excluded one - that is why each needs an explicit resolution.
- Every rule is tested. Each BR-ID in Section 1 is enforced by at least one AC marked
(enforces BR-ID), whatever the coverage table says.
Edge case backfill (--edge-cases)
/pm-feature-design [FEAT-ID] --edge-cases retrofits the Edge Case Coverage table onto a card designed before Pureinn 5.62.0. It runs only the edge case part of the Discovery Interrogation, and pm-audit and pm-stripe route to it. Section 1 and Section 3 change only when a new edge case needs a new guard or rule (and so a new diagram branch).
| Card status | What backfill does |
|---|---|
1_Backlog | Nothing - the normal design run produces the table |
2_Spec_Done / 2b_In_Design / 3_Ready_to_Build | Full backfill + Given/When/Then conversion; status unchanged; new ACs get a short Design Inspection |
4_In_Build | Full backfill; new ACs flagged to the owner as a scope extension |
5_In_Review | Table filled; gaps become ACs marked (follow-up), verified in the running review |
6_Shipped | Card stays immutable: only a ### Edge Case Coverage (retro, [date]) table is appended; each gap goes to open_questions.md |
Pitfalls
- Running pm-feature-design upfront for a whole Feature Set defeats the JIT principle - spec becomes stale before build.
- Skipping the Discovery Interrogation and going straight to the sequence diagram produces an incomplete spec that discovers edge cases during build instead of before it.
- Not committing register updates first creates merge conflicts when two Stripes are running simultaneously.