pm-feature-design
Skill2 starsChanged 4 months agoMITView on GitHub
JIT Design by Feature - Phase 6 skill. Just-In-Time technical design for a single feature before it enters build. Enriches the 4 live registers with guard conditions and finalized rules, generates a Mermaid.js sequence diagram, writes Acceptance Criteria, and completes Feature Card Sections 1-3. Replaces upfront Feature-Set design documents with JIT per-feature design. Run once per feature, triggered by pm-stripe when the feature is next in its Stripe.
In this repository51 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- design-thinkingSkill
- jtbd-buildingSkill
- pm-auditSkill
- pm-business-caseSkill
- pm-business-modelSkill
- pm-business-rule-coreSkill
- pm-business-rule-criticalSkill
- pm-business-rule-governanceSkill
- pm-business-rules-librarySkill
- pm-comms-charterSkill
- pm-decision-modelSkill
- pm-diagramsSkill
- pm-discovery-interviewSkill
- pm-discovery-reportSkill
- pm-domain-analysisSkill
- pm-domain-modelSkill
- pm-entity-registrySkill
- pm-feature-cardSkill
- pm-features-listSkill
- pm-feature-viabilitySkill
- pm-glossarySkill
- pm-hypothesesSkill
- pm-kotlerSkill
- pm-kpisSkill
- pm-lean-canvasSkill
- pm-market-analysisSkill
- pm-meetingSkill
- pm-mvp-scopeSkill
- pm-onboardingSkill
- pm-open-questionsSkill
- pm-personasSkill
- pm-pitch-deckSkill
- pm-prdSkill
- pm-prioritizeSkill
- pm-privacy-requirementsSkill
- pm-problem-validationSkill
- pm-process-flowsSkill
- pm-product-roadmapSkill
- pm-project-charterSkill
- pm-prototypeSkill
- pm-reconcileSkill
- pm-reconcile-statusSkill
- pm-reverse-extractSkill
- pm-root-causeSkill
- pm-scope-briefSkill
- pm-stakeholder-mapSkill
- pm-stress-testSkill
- pm-stripeSkill
- pm-team-rosterSkill
- pm-tech-feasibilitySkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
32 rules. About 0 are common, 15 are distinctive, and 17 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈15
Distinctive · estimate
This author's own choices. Worth a look.
17
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 33
If set to a non-English language: write prose content (descriptions, rationale, rule text) in that language.
- Distinctive: line 34
Never translate: IDs, frontmatter keys and enum values, section headers other skills parse, file names - these stay English always, …
- Very specific: line 38
No workspace, or inputs missing: name which are missing and what each one unlocks, then offer the PREREQ paths - proceed on stated …
- Very specific: line 40
Read pureinn-variables.md / state.json where a value is actually used, not at the top of the run.
- Distinctive: line 68
All register updates (steps 2-3) are committed BEFORE any code generation begins.
- Distinctive: line 82
If the project has an existing codebase, Claude Code MUST scan the relevant service files before generating the sequence diagram.
- Distinctive: line 119
No register yet → say so in one line.
- Very specific: line 175
Read the Feature Card at /features/cards/[FEAT-ID].md.
- Very specific: line 191
If Feature Card status is already 3_Ready_to_Build or later: stop.
- Distinctive: line 294
Edge Case Taxonomy - the 6 fixed categories: Every Feature Card must account for all six.
- Very specific: line 325
Surface assumptions inline: when proceeding without explicit input: Assumption: [X].
- Distinctive: line 342
If playbook mode = Feature Implementation:
- Distinctive: line 345
Read those files to extract real class names, method signatures, and dependency injection patterns
- Distinctive: line 367
Add the exact guard condition (business logic expression, not code)
- Distinctive: line 380
Add the exact formula/condition (if still TBD)
- Very specific: line 381
Update status: Draft → Final
- Distinctive: line 382
Add this FEAT-ID to the "Applies to features" field
- Very specific: line 384
If this feature surfaces a brand-new rule not yet in the register, add it with the focused single-rule helper by priority class - …
- Distinctive: line 391
Add this FEAT-ID to "Used in features"
- Very specific: line 474
Write the lightweight nuance helpers captured during the Step 1.5 interrogation (and any the user/team added).
- Very specific: line 518
If the card carries promoted_from: or a prototype reference, close Section 3 with the ### Prototype carry-over subsection (template and …
- Very specific: line 536
If a process-flows/[domain]_user_flows.md exists for this feature's module, draw the UX context (placement, user action, screen, …
- Very specific: line 538
If no Figma URL was provided and Figma MCP is connected: check figma_project_url in pureinn-variables.md and read the relevant screen if …
- Distinctive: line 540
If feature is backend/API-only: omit Section 3b entirely.
- Very specific: line 544
Write the security_review verdict decided in Step 1.5 to the frontmatter (none / build / review / both).
- Very specific: line 605
If an open BLK- is listed, do not offer "start build" - the feature stays at 2_Spec_Done until the blocker is resolved in the register.
- Distinctive: line 744
After local files are saved, push spec content to Notion so the team can review it there.
- Very specific: line 747
Read pureinn-variables.md key "Feature Backlog" → get DB URL
- Very specific: line 748
Check state.json notion_ids.feature_backlog → use cached data source ID or fetch
- Distinctive: line 751
If Feature Backlog URL is blank or feature entry not found: skip Notion push, continue.
- Very specific: line 755
Call mcp__claude_ai_Notion__notion-update-page with command: "replace_content" and the full Feature Card content:
- Very specific: line 794
Call mcp__claude_ai_Notion__notion-update-page with command: "update_properties":
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
PM - Feature Design (JIT)
Agent mode (--agent)
Supports --agent: runs autonomously in a subagent, drafts the artifact from existing inputs, and returns a short summary + coverage note.
- No flag → interactive (default); if inputs are heavy, offer agent mode.
--agent→ obey. First check inputs are complete. Anything missing: do NOT invent it - mark[ASSUMED - what/why]in the output and summary. Never hallucinate to fill a gap.- Review required: the artifact contains commitments - after drafting, require the user's review before finalizing; do not close decisions autonomously.
Artifact language
Checks state.json → artifact_language. Default (unset or "English"): no change in behavior.
- If set to a non-English language: write prose content (descriptions, rationale, rule text) in that language.
- Never translate: IDs, frontmatter keys and enum values, section headers other skills parse, file names - these stay English always, regardless of the setting.
Standalone run
Needs the artifacts listed under Dependencies - it synthesizes them, so without them there is nothing to synthesize.
- No workspace, or inputs missing: name which are missing and what each one unlocks, then offer the PREREQ paths - proceed on stated assumptions marked
[ASSUMED - what/why], or route to the skill that produces the missing input. Never hard-block, and never invent the input. - Writing never depends on
/pureinnhaving run: with no workspace, create just the folder this skill writes into, or write to a path the user names, and say where the file went. - Read
pureinn-variables.md/state.jsonwhere a value is actually used, not at the top of the run. Missing value: continue and name the capability it costs.
What this skill does
Produces the Just-In-Time technical design for a single feature immediately before it enters build. This is the FDD Phase 4 (Design by Feature) executed in SDD mode.
JIT vs. upfront design:
| Upfront approach (not used) | This skill (JIT) |
| Feature-Set-level design, written upfront | Feature-level design, written just-in-time |
| Standalone design document | Register updates + sequence diagram embedded in Feature Card |
| Written for an entire Feature Set before the Stripe | Written for one Feature just before build |
What this skill does in one run:
- Reads the Feature Card (Section 1 is stub at this point)
- Discovery Interrogation (Step 1.5) - actively interrogates to surface unknowns and reach precision, calibrated to feature criticality; sorts findings into rules / ACs / subtasks
- 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 surfaced in discovery via the single-rule helpers - Populates Feature Card Section 1 (Biznis Mantinely) - links entities, BR-IDs, TBL-IDs
- Writes Feature Card Section 2 (Acceptance Criteria) - derived from register state + business rules, closed by an Edge Case Coverage table over 6 fixed categories
- Writes Feature Card Subtasks - lightweight nuance helpers captured in discovery
- Generates Mermaid.js sequence diagram + files to modify - writes to Feature Card Section 3
- Pushes description + Sections 1-3 + Subtasks to Notion; sets Feature Card status to
2_Spec_Done(or2b_In_Designif it is a frontend feature whose Figma design still has to be produced - see Step 4d)
Atomic commit protocol (parallel Stripe safety): All register updates (steps 2-3) are committed BEFORE any code generation begins. This prevents merge conflicts when multiple Stripes run in parallel.
Commit 1: "spec([FEAT-ID]): guard conditions + rule finalization"
→ entities.md updated
→ business_rules.md updated (rules status: Final)
→ decision_models.md updated
Commit 2: "spec([FEAT-ID]): feature design complete"
→ Feature Card Sections 1-3 populated
→ status: 2_Spec_DoneExisting codebase mode (Feature Implementation playbook): If the project has an existing codebase, Claude Code MUST scan the relevant service files before generating the sequence diagram. The diagram must use only real existing classes and methods - it must not invent interfaces that don't exist.
Dependencies
Required before running:
- Feature Card for this FEAT-ID (created by pm-features-list, stub state)
pm-entity-registry- entities.md must existpm-business-rules-library- business_rules.md and decision_models.md must exist (at least Draft)
Recommended before running:
pm-stripe- confirms this feature is next in its Stripe and dependencies are metpm-prototype- only when the card carriespromoted_from:or a prototype reference: the prototype's findings and itsPRT-card are read first (see Prototype carry-over)
Produces artifacts used by:
- Feature Card (Sections 1-3 populated)
- Build phase - Claude Code reads the completed Feature Card as implementation spec
test-master/playwright-expert- ACs in Section 2 are the direct test basis
Open questions
Open questions and decisions have exactly one home in the whole project: domain/open_questions.md (Live Register 5, owned by pm-open-questions). If the Discovery Interrogation surfaces a genuine judgment call (not just a new rule/guard condition to add, which goes into business_rules.md/entities.md directly), a legacy-vs-code divergence, or a concrete blocker to build - do not park it as a Subtask or a comment in the Feature Card. Append an entry to the register (Type: Question / Divergence / Blocker, OQ-/DIV-/BLK-{DOMAIN}-NN ID; run pm-open-questions to initialize it first if it doesn't exist). A Subtask is a nuance for the developer to handle during build; an open question is something nobody has decided yet - keep the two separate.
Open-items lookup (read-only, mandatory at Step 0 and Step 5). The register is the single home, so the card never lists its open items - they are pulled into view instead. Read the ## Open section of domain/open_questions.md and collect every entry that names this FEAT-ID (in Impact, Target or Context) or whose ID appears in the card (e.g. an Edge Case Coverage cell). Show them as a block - ID, heading, Type, Priority - never copy their text into the card:
Open register items for [FEAT-ID]:
BLK-ORD-02 Payment sandbox credentials missing Blocker Critical
OQ-ORD-05 Refund on partial restaurant rejection? Question High
(none) - if nothing matches- Open
BLK-→ the feature cannot reach3_Ready_to_Builduntil it is resolved in the register. - Open
OQ-/DIV-→ does not block, but must be shown; at Step 0 try to resolve it during the interrogation (resolution is recorded in the register bypm-open-questions, never in the card). - No register yet → say so in one line; nothing to look up.
Prototype carry-over
Applies only when the Feature Card carries promoted_from: PRT-[NAME]-NNN in its frontmatter, or a prototype reference block (Prototype: / Prototype URL: / Audience: / Expected outcome: / Result:). Both are written by /pm-prototype; this skill reads them and never edits them. No such field or block on the card → skip this section entirely.
A prototype that came before the design already settled some questions and deliberately faked others. Designing without reading it does two kinds of damage: the interrogation reopens what was already decided, and the production spec drifts from the prototype without anyone writing down where.
Read first, at Step 0, before the interrogation - in full:
| Source | Where | What it gives |
meta.md | prototypes/[prototype-name]/ | Purpose (test / workbench), Classification (Disposable / Reference / Evolutionary), Decision, what is deliberately simulated |
findings.md | same folder | what was observed, what was not tested, known distortions |
the PRT- card | feature-cards/ in that folder | how the feature behaves in the prototype, what is simulated in it, what the production version is and costs |
domain.md / rules.md | same folder, only if they exist | where the prototype deliberately diverged from the global registers |
Locate the folder from the Prototype: path, or by finding the promoted_from ID in a prototypes/*/feature-plan-prt.md - do not derive the folder name from the ID. An external-tool prototype has a spec file instead of a folder: read the spec and its ## Result section. State coverage ("Read meta.md, findings.md, PRT-ONB-003 in prototypes/onboarding-flow/"). If the folder, the PRT- card or findings.md cannot be found, say so and continue without carry-over - never reconstruct what the prototype "probably" showed; the dangling reference is pm-audit's finding.
Check Result: before designing:
Result: / state | What to do |
pending | Surface it before anything else. The card says a result is expected before build proceeds. AskUserQuestion: record the result first via /pm-prototype (Recommended when the prototype has been shown to anyone) / design now and treat nothing in the prototype as resolved. Under --agent: do not choose - design with nothing treated as resolved and flag it in the summary |
Supported within scope | resolved for the scope stated - the population and the dimension the prototype represented, nothing wider |
Refuted within scope | flag before designing: the evidence went against this feature as prototyped. Confirm what changed since, or stop |
Prototype or study failure / Inconclusive | nothing was learned about the feature. Treat nothing as resolved |
| workbench prototype (no verdict) | its decisions are stakeholder alignment, not user evidence. Flow and scope decisions made over it are settled; a belief about users it rested on is not |
Record two things in the design output - a subsection of Section 3, written in Step 4c:
### Prototype carry-over
**Prototype:** [/prototypes/[prototype-name]/](/prototypes/[prototype-name]/) · [PRT-[NAME]-NNN] · Classification: [Disposable / Reference / Evolutionary] · Result: [state]
**Resolved by the prototype (not reopened in this design):**
- [decision or behaviour] - [where it is recorded: findings.md / PRT card section]
**Changed against the prototype:**
- [what the production spec does differently] - [why: simulated in the prototype / rule from the register / feasibility / decided since]
- none - if the production spec follows the prototype as built- What the prototype resolved. Each item must trace to
findings.mdor thePRT-card. In Step 1.5, carry these in as settled - propose them back for a one-line confirmation, do not re-interrogate them. Whatfindings.mdlists under "what we did not test" and everything the card marks as simulated is not resolved and gets the normal interrogation. The 6 edge case categories are always walked: a prototype rarely exercises them. - What changed against it. Every point where Sections 1-3 depart from the prototype's flow, states or measurement, with the reason. For a Reference prototype this list is mandatory even when empty (
none): Reference is binding for flow, states and measurement (not architecture), and an undocumented divergence is how it quietly stops being binding. Disposable: record divergences from the findings only. Evolutionary: the code is on a branch in the real repo - treat it as existing code in the Step 2 scan. - A local
rules.md/domain.mdentry that was promoted into the global registers is referenced by itsBR-/ entity link in Section 1 as usual, not from here. - The prototype folder is history (or, for a workbench, owned by
/pm-prototype): never edit it from this skill. A change belongs in the Feature Card. - Under a non-English
artifact_languagethe subsection header and the three bold labels stay English.
Step 0: Current state check
Read the Feature Card at /features/cards/[FEAT-ID].md.
| Item | Status | Detail |
| Feature Card | [status from frontmatter] | [title] |
| entities.md | [exists / not found] | |
| business_rules.md | [exists / not found] | |
| decision_models.md | [exists / not found] | |
| Dependencies met | [yes / no] | [list unmet deps] |
| Open register items | [N open / none / no register] | [IDs - see Open-items lookup] |
| Prototype | [promoted_from: PRT-... / reference block / none] | [Classification · Result - see Prototype carry-over] |
Show the Open-items lookup block under the table. If the Prototype row is not none, run the Prototype carry-over reads now and surface a pending or Refuted within scope result before going further.
Verdict: [One sentence - ready to design or what is blocking]
If Feature Card status is already 3_Ready_to_Build or later: stop. Design is already approved. Do not overwrite. Exception: invoked with --edge-cases → skip the rest of this flow and run Edge case backfill mode (below), which has its own per-status rules.
Interaction: Group related questions (2-4 per round) and confirm before moving on. For any A/B/C/D choice, use the AskUserQuestion tool with one option marked (Recommended) - never print options as plain text. Keep open-ended questions free-text (don't fake options). If the user is unsure, propose 3-4 concrete options plus "Other". Surface an assumption the moment you make one; never fabricate to fill a gap. (Full standard: CLAUDE.md.)
Step 1: Detect mode from state.json, then gather feature-specific inputs
Playbook mode and team mode come from state.json - do NOT ask them cold. By the time a feature reaches design, the workspace already knows its playbook and team_structure (both set at Phase 1 setup). Asking again is redundant and makes the skill look like it forgot its own state - which violates the situation-aware standard (CLAUDE.md → Adaptive execution). Read them and state the detected mode; only fall back to a question if the value is genuinely absent.
Read state.json:
playbook→ Greenfield (design from scratch, diagram defines new classes/methods) or Feature Implementation (diagram must match existing code - triggers the Step 2 code scan).team_structure→ Solo Builder (AI drafts the full design, you confirm before build) or Delivery Team (design goes to a Design Inspection step after this).
State it, don't ask:
Detected from state.json: [Greenfield | Feature Implementation] · [Solo Builder | Delivery Team].
→ Designing [from scratch | against the existing codebase]; [you confirm before build | this routes to Design Inspection].
Say "switch mode" if that's wrong.Only if playbook or team_structure is missing from state.json (e.g. a hand-created workspace, or a fast-track that skipped setup), fall back to AskUserQuestion for the missing field(s) - one question, only the one that's unknown:
- Playbook (if unknown): "Greenfield - design from scratch (Recommended for new projects)" / "Feature Implementation - match existing code (Recommended for an existing codebase)"
- Team (if unknown): "Solo Builder - you confirm before build (Recommended)" / "Delivery Team - goes to Design Inspection"
Then ask as plain text:
JIT Design for: [FEAT-ID]: [Feature title]
PRD CONTEXT
The feature references: [prd_ref from frontmatter]
Is this PRD section in context, or should I read it?
[confirm or paste relevant section]
BUSINESS RULES SCOPE
Which business rules from business_rules.md apply to this feature?
List BR-IDs, or I will identify them from the feature scope.
[list or "identify automatically"]
[If Feature Implementation mode: which service files are relevant? I will scan them before designing.]
OPEN QUESTIONS
Any known edge cases or constraints specific to this feature not yet in the registers?
[list or "none"]Then use AskUserQuestion tool for UX context (skip if backend/API-only feature):
- Question: "Does this feature have a user interface component? If yes, how will you provide the UX context?"
- Option A: "Text description - I'll describe where this feature lives and what the user sees/does"
- Option B: "Attach a screenshot or mockup directly in this message"
- Option C: "Figma URL - I'll paste the screen URL (requires Figma MCP connected)"
- Option D: "Backend/API-only - no UI component, skip UX context"
Step 1.5: Discovery Interrogation
This is the core of JIT design. A Feature is a detailed view of functionality - at design time the user often does not yet know every detail they implied when writing the business logic, and is unaware of some entirely. Do not passively ask "any edge cases?" and accept "none." Actively interrogate to surface the unknowns and reach precision - this is what the deep-dive is for. The AI drives; the user (and optionally the team) answers, or the AI proceeds on flagged assumptions. No class-owner machinery - roles stay flat.
Calibrate depth to feature criticality - do NOT run a fixed 30-question checklist (that just trains people to click "none"):
Criticality = f(KANO, priority, touches money?, touches PII?, number of state transitions)
Low (CRUD, P3, no money/PII) → 2-3 targeted questions + one scenario per applicable edge case category
Medium (P2) → happy path + guard conditions + flag-OFF + one scenario per applicable edge case category
High (money / PII / P1 / critical) → full interrogation across all axes belowEdge Case Coverage is mandatory at every criticality level. Criticality decides depth (how many scenarios per category, how hard you probe), never whether a category is considered. Low/Medium still walk all 6 categories below - one scenario per applicable category is enough; High probes each category exhaustively.
Security dimension - set the security_review flag here. The same signals that drive criticality also decide whether this feature needs a security specialist in build/review. Think in security areas, not feature types: the trigger is whether the feature creates, crosses, or modifies a vulnerability area, not whether it is a specific feature (an invite code is an instance of the Abuse/enumeration + Identity areas, not its own trigger). Assess it now (you have the most context during interrogation) and write the verdict to the Feature Card frontmatter in Step 4d. Set security_review above none when the feature touches at least one area:
| # | Security area | Example (illustrative) |
| 1 | Access control & tenant isolation | RLS, org/tenant scoping, service-role bypass, privilege escalation, impersonation, bulk/admin ops |
| 2 | Authentication & identity | login, session, token lifecycle, SSO/OAuth, new role/permission flag |
| 3 | Cryptography & secrets | key/API-key storage, token generation, hashing, encryption |
| 4 | Sensitive / regulated data | PII/regulated data crossing a boundary (the regime GDPR/HIPAA/PCI is a per-vertical example, not the trigger) |
| 5 | Input & injection surface | untrusted input parsing, injection, deserialization, file upload |
| 6 | External / server-side integration | outbound → LLM/3rd-party API, inbound webhooks, SSRF |
| 7 | Abuse & enumeration surface | guessable identifiers (invite/coupon codes, reset tokens), brute force, rate-limiting, resource exhaustion |
| 8 | Financial integrity | money movement, accounting, transactional integrity |
Pre-auth / cross-tenant reachability escalates whatever area it touches - treat borderline pre-auth surfaces as triggering.
Value: build if the feature creates a new mechanism in an area (a new security BR going Draft→Final for the first time) → secure-code-guardian threat-models before writing it. review if it only crosses a sensitive area but reuses an existing Final security pattern (the primitive is already proven) → security-reviewer audit only. both if new AND sensitive. none if no area touched (plain CRUD behind proven auth). (Full authoritative table + reuse rule: pm-stripe → Security Review Trigger Criteria.) State the verdict inline: security_review: [value] - because [area touched / no area touched].
Test type dimension - set the test_types field here. test-master's scope is a black box unless this is decided explicitly. Assess against feature characteristics, not feature names - the same discipline as the security dimension above:
| Characteristic | Test type | Why |
| Business logic / guard conditions (baseline - every feature) | unit | Cheapest, fastest signal; covers the BR-IDs from Section 1 |
| Calls another internal service, DB, or API endpoint | integration | Verifies real interaction, not a mock |
| Consumed by an external client (mobile app, partner integration, public API) | contract | Prevents a breaking change the caller can't see coming |
| UI feature reusing a design-system component whose visual stability matters | visual_regression | Catches unintended visual drift that logic tests can't see |
| Feature on the money path or a high-traffic endpoint | performance | Correctness in a unit test says nothing about behavior under load |
E2E is decided separately (the playwright-expert trigger in pm-stripe - multi-step UI journey) and is not part of this field. Write the assessed list to the Feature Card frontmatter in Step 4d, e.g. test_types: [unit, integration] - unit is the baseline on virtually every feature; add the others only when their trigger condition is genuinely met, don't pad the list for thoroughness. State the verdict inline: test_types: [...] - because [characteristic(s) matched].
Edge Case Taxonomy - the 6 fixed categories. Every Feature Card must account for all six. Do not invent new category codes per feature; if something does not fit, it belongs to the closest category.
| Code | Category | Probe for |
EC-INPUT | Invalid input | missing/wrong fields, wrong types, boundary values, unknown or protected keys |
EC-AUTH | Authorization / ownership | unauthenticated, wrong role, acting on another user's record (IDOR) |
EC-STATE | Entity state | entity in the wrong state for the action, entity missing or deleted |
EC-CONC | Concurrency / idempotency | double submit, two actors racing on the same entity, retried request |
EC-EXT | Dependency failure | 3rd-party/provider down or slow, DB failure, timeout, failure of another internal feature this one calls |
EC-CLIENT | Client states | offline, OS permission denied, empty state, flow interrupted mid-way (only when layer includes frontend; otherwise N/A) |
Feature flag OFF is NOT an edge case category - it stays its own mandatory AC. Security depth stays with security_review and load behavior with test_types - neither is a seventh category.
For each category, the outcome is exactly one of:
- covered by one or more ACs (
AC-NN) N/A - <one-line reason>- the reason must be specific to this feature ("backend-only feature", "read-only, no shared mutable state"), never "not relevant"OQ-[DOMAIN]-NN- the correct behavior is undecided; log it indomain/open_questions.md(Type: Question) instead of inventing behavior
Axes to probe (use the grouped question pattern from CLAUDE.md - batch 2-4 related questions per AskUserQuestion round, confirm, continue):
| Axis | What to actively probe | Feeds |
| Happy path | Propose the step-by-step flow yourself; the user corrects | → sequence diagram (§3) |
| State transitions | Which entity states does this touch (from entities.md)? What triggers each? | → guard conditions |
| Guard conditions | Under what conditions is each action allowed / blocked? | → BR-IDs or new rules |
| Edge cases | Walk all 6 categories of the Edge Case Taxonomy (EC-INPUT, EC-AUTH, EC-STATE, EC-CONC, EC-EXT, EC-CLIENT) - propose the concrete scenario yourself, the user confirms or corrects | → ACs (§2) + Edge Case Coverage table |
| Hidden concerns | Permissions, idempotency, notifications, audit, data retention - the things the user "has no clue about" | → rules / subtasks |
| Rule gaps | At every decision point: "is there a rule governing this? what is the value?" | → register enrichment |
When the user says "I don't know" (per CLAUDE.md): never leave a vacuum. Based on the domain, registers, and similar features, propose 3-4 concrete options via AskUserQuestion and let them choose, plus an "Other / I'll describe" option.
Surface assumptions inline when proceeding without explicit input: Assumption: [X]. If wrong, tell me - it affects [Y].
Outputs of the interrogation - sort every finding into the right layer:
| Finding | Goes to |
| Non-negotiable, reusable logic | Business rule → add via /pm-business-rule-core / -critical / -governance (Step 3), or finalize an existing BR-ID |
| Multi-condition logic | Decision table (TBL) → add via /pm-decision-model, or finalize an existing TBL-ID |
| Testable condition for this feature | Acceptance Criterion (§2) |
| Lightweight nuance / dev helper | Subtask (§Subtasks) - not a rule, not an AC |
Produce a short interrogation summary (new rules to add, ACs identified, subtasks captured, open assumptions, the resolution of each of the 6 edge case categories, and the security_review verdict with its reason) before moving to register updates.
Step 2: Pre-design scan (Feature Implementation mode only)
If playbook mode = Feature Implementation:
- Identify service files, models, and handlers relevant to this feature (from feature scope + files listed in Feature Card Section 3 stub)
- Read those files to extract real class names, method signatures, and dependency injection patterns
- Build a map of real interfaces before drawing any diagram
Output:
Existing code scan for [FEAT-ID]:
- OrderService: [real methods found]
- PaymentProvider: [real interface]
- [Entity]: [real model fields relevant to this feature]
Diagram will use only these existing interfaces.Skip this step if Greenfield mode.
Step 3: Update registers (Atomic Commit 1)
3a. Update entities.md - add guard conditions
For each state transition this feature triggers:
- Add the exact guard condition (business logic expression, not code)
- Replace
TBD - added JITwith the actual condition
Example:
| Draft | Confirmed | payment.success | order.confirmed | card.luhn_valid == true AND BR-PAY-001 == pass |Regression check before tightening a shared guard: if the transition already has a finalized guard (not TBD) because an earlier, already-6_Shipped feature set it, adding a new condition to that same guard can silently break the shipped feature's behavior. Before finalizing, grep /features/cards/ for other Feature Cards referencing this same entity transition. If any are 6_Shipped, surface it explicitly: "This guard is already used by [FEAT-ID] (shipped). Tightening it to add [new condition] may change its behavior - confirm this is intended, or scope the new condition to this feature only (e.g. an additional guard on a different transition/branch)." Never silently narrow a guard that another shipped feature depends on.
3b. Finalize rules in business_rules.md
For each BR-ID this feature enforces:
- Add the exact formula/condition (if still TBD)
- Update status:
Draft→Final - Add this FEAT-ID to the "Applies to features" field
If this feature surfaces a brand-new rule not yet in the register, add it with the focused single-rule helper by priority class - /pm-business-rule-core (operational), /pm-business-rule-critical (hard invariant), or /pm-business-rule-governance (compliance/policy) - rather than re-running the full library skill.
3c. Finalize decision tables in decision_models.md
For each TBL-ID this feature uses:
- Complete any TBD cells
- Update status:
Draft→Final - Add this FEAT-ID to "Used in features"
3d. Commit
git add domain/entities.md domain/business_rules.md domain/decision_models.md
git commit -m "spec([FEAT-ID]): guard conditions + rule finalization"Step 4: Generate Feature Card Sections 1-3 (Atomic Commit 2)
4a. Section 1 - Biznis Mantinely
Populate using table format for rules and entity transitions. Tables are scannable and show enforcement points explicitly - critical for code review and build.
## 1. Biznis Mantinely (SDD Input)
**Rules enforced in this feature:**
| Rule ID | Rule | Priority | Enforcement point |
|---|---|---|---|
| [BR-XXX-001](/domain/business_rules.md#br-xxx-001) | [Rule name: one-line summary] | [Critical/High/Medium] | [Service method / webhook handler / DB constraint] |
| [BR-XXX-002](/domain/business_rules.md#br-xxx-002) | [Rule name: one-line summary] | [Critical/High/Medium] | [Service method / middleware] |
**Entity guard conditions (from entities.md):**
| Entity | Transition | Guard condition |
|---|---|---|
| [Entity Name](/domain/entities.md#entity-name) | [State before] → [State after] | [exact guard expression (finalized: FEAT-ID)] |
**Decision model:** [TBL-XXX-01](/domain/decision_models.md#tbl-xxx-01) - [Table name, if applicable]
**What this feature does NOT do:**
- [explicit scope exclusion - what adjacent feature handles, or what is out of scope in v1]
- [explicit scope exclusion]4b. Section 2 - Acceptance Criteria
Derived from: entity state transitions (entities.md) + business rules (business_rules.md) + decision table edge cases (decision_models.md).
Minimum: happy path AC + feature flag OFF AC + an Edge Case Coverage table where each of the 6 categories is resolved (AC / N/A with reason / OQ). Every AC uses Given/When/Then - no checkbox lists. Edge case ACs carry their category code in the title.
## 2. Acceptance Criteria
### AC-01: [Happy Path Name]
- **Given** [precondition: entity in state X, actor context]
- **When** [action taken]
- **Then** [observable outcome: entity state change, event emitted, user feedback]
- **And** [secondary outcome]
### AC-02: [EC-XXX] [Edge Case Name] (enforces [BR-ID] if applicable)
- **Given** [precondition]
- **When** [invalid or failing condition]
- **Then** [system blocks, entity state unchanged, error signal]
### AC-03: Feature Flag OFF
- **Given** flag `[feature_flag from frontmatter]` is OFF
- **When** [same trigger as AC-01]
- **Then** [existing behavior unchanged / feature hidden / graceful degradation]
### AC-0N: [EC-XXX] [Edge Case Name] (from [TBL-ID] if derived from a decision table)
[Cover key rows from the decision table]
### Edge Case Coverage
| Category | Coverage |
|---|---|
| EC-INPUT | AC-NN |
| EC-AUTH | AC-NN |
| EC-STATE | AC-NN |
| EC-CONC | AC-NN / N/A - reason / OQ-[DOMAIN]-NN |
| EC-EXT | AC-NN / N/A - reason / OQ-[DOMAIN]-NN |
| EC-CLIENT | AC-NN / N/A - reason |The table is an index, not a description - never restate the scenario in it. Multiple ACs per cell are fine (AC-03, AC-05). No empty cells.
4b-Subtasks. Subtasks (helper notes)
Write the lightweight nuance helpers captured during the Step 1.5 interrogation (and any the user/team added). These are dev aids, not deliverables - never sub-features. If none surfaced, leave the section with - none.
## Subtasks (helper notes)
- [ ] [nuance / spec detail - e.g. "reset link expires in 15 min", "reuse existing EmailService"]
- [ ] [implementation hint or UX nuance the developer should know]4c. Section 3 - JIT Technical Design
Generate sequence diagram using Mermaid.js. Greenfield: can define new classes. Feature Implementation: use only real existing classes from Step 2 scan.
## 3. JIT Technical Design (FDD Design)
### Data flow and object interaction
```mermaid
sequenceDiagram
actor User
participant [ServiceName]
participant [EntityName]
participant [ExternalProvider]
User->>[ServiceName]: [action]
[ServiceName]->>[EntityName]: [validate / fetch]
alt [guard condition from BR-XXX-001 passes]
[ServiceName]->>[ExternalProvider]: [call]
[ExternalProvider]-->>[ServiceName]: [response]
[ServiceName]->>[EntityName]: [state transition: X -> Y]
[ServiceName]->>User: [success response + emits: entity.event]
else [guard condition fails]
[ServiceName]->>User: [error: rule violated]
endFiles to modify
[src/services/ServiceName.ts]- [brief description of change][src/entities/EntityName.ts]- [state transition logic][src/validators/ValidatorName.ts]- [guard condition implementation]
If the card carries `promoted_from:` or a prototype reference, close Section 3 with the `### Prototype carry-over` subsection (template and rules in the Prototype carry-over section above). Leave the card's `promoted_from:` field and prototype reference block exactly as they are.
**4c-UX. Section 3b - UX/UI Context** (include only if feature has a UI component)
```markdown
## 3b. UX/UI Context
**Placement:** [Where in the app - screen name, route, component location]
**User-facing intent:** [What the user sees and what action they take - 1-2 sentences]
**Design system reference:** [Component or pattern from your design system (e.g. the external Impeccable skill, or your own) / "new pattern - see Figma"]
**Figma reference:** [URL to specific screen / frame / component - or "N/A"]
**Visual notes:** [Any specific behavior: empty states, loading state, error state, responsive breakpoints]If a process-flows/[domain]_user_flows.md exists for this feature's module, draw the UX context (placement, user action, screen, loading/empty/error states) from the relevant user flow there rather than re-deriving it - the flow is the E2E source, this section is its per-feature slice.
If no Figma URL was provided and Figma MCP is connected: check figma_project_url in pureinn-variables.md and read the relevant screen if identifiable. If not identifiable, ask the user for the Figma frame URL or accept a screenshot.
If feature is backend/API-only: omit Section 3b entirely.
4d. Update Feature Card frontmatter status + security_review + mutex_tags
Write the security_review verdict decided in Step 1.5 to the frontmatter (none / build / review / both). pm-stripe reads this to route secure-code-guardian (build) and security-reviewer (review), and to run its Build Skills Coverage check. If the stub was created with security_review: none, overwrite it with the assessed value.
security_review: build # none | build | review | both - from Step 1.5 security dimensionWrite test_types assessed in Step 1.5 to the frontmatter - pm-stripe reads it to specialize the test-master routing (Reference: Test Type Matrix) and the Build Skills Coverage check. If the stub carries no value yet, set it here; unit is always present.
test_types: [unit, integration] # from Step 1.5 test type dimension - unit is baseline; integration/contract/visual_regression/performance added only when their trigger is metPopulate mutex_tags from Section 3's "Files to modify" - this is the exact moment the code-contention footprint is known. List the shared modules/classes/files this feature touches that other features might also touch (the delivery-plan uses this to prevent two features editing the same code in parallel - critical when AI agents build on separate branches). Prefer the shared/reusable surfaces (services, schemas, shared components, middleware), not leaf files unique to this feature. In Feature Implementation mode, take them from the Step 2 code scan (real modules); in Greenfield, from the classes the diagram introduces. Annotate with a reason where the risk is non-obvious.
mutex_tags:
- {tag: "InviteService", reason: "new invite-code methods"}
- "auth/middleware.ts"Then set status. Spec (Sections 1-3) is complete → 2_Spec_Done. Then branch on layer:
- Feature has a UI (
layerincludesfrontend) and the Figma design is not yet done (no Figma URL in Section 3b, design still to be produced): set2b_In_Design- the feature is spec'd but waiting on / in visual design. It advances to3_Ready_to_Buildonce the design is approved. - Backend / system feature, or the UI design is already provided/approved: set
2_Spec_Done(goes straight to3_Ready_to_Buildat Design Inspection - nothing to design).
# frontend feature, design still to be produced:
status: 2b_In_Design
# backend/system feature, or design already in hand:
status: 2_Spec_Done4e. Commit
git add features/cards/[FEAT-ID].md
git commit -m "spec([FEAT-ID]): feature design complete"Step 5: Design Inspection handoff
Solo Builder mode:
Show summary:
Design complete for [FEAT-ID]: [title]
Summary:
- Register updates: [entities.md] guard condition for [transition], [N] rules finalized
- Sequence diagram: [N] actors, [N] steps, [N] alt paths
- Acceptance Criteria: [N] ACs covering happy path + [N] edge cases + flag OFF
- Edge Case Coverage: [6/6 resolved] - [N] by AC, [N] N/A, [N] OQ
- Prototype carry-over: [N] resolved by the prototype, [N] changed against it (only if the card came from / references a prototype)
[Open-items lookup block - re-run now, not reused from Step 0]
Review the sequence diagram in Section 3 of the Feature Card.If an open BLK- is listed, do not offer "start build" - the feature stays at 2_Spec_Done until the blocker is resolved in the register.
Then use AskUserQuestion tool with:
- Question: "Any corrections before build starts?"
- Option A: "Looks good - start build (Recommended)"
- Option B: "Correction needed - I'll describe what to fix"
Delivery Team mode:
Design package ready for Design Inspection - [FEAT-ID]: [title]
Feature Card is at status: 2_Spec_Done
Location: /features/cards/[FEAT-ID].md
Design Inspection checklist:
[ ] Sequence diagram reflects real system flow (no invented methods)
[ ] Guard conditions in entities.md are accurate
[ ] Business rules (BR-IDs) correctly referenced
[ ] All ACs are testable without knowledge of internals
[ ] Edge Case Coverage table present, all 6 categories resolved, no empty cell
[ ] Every N/A has a feature-specific reason; every OQ-ID exists in open_questions.md
[ ] Every AC-ID in the table exists in Section 2 and carries the matching [EC-XXX] tag
[ ] Every BR-ID in Section 1 is enforced by at least one AC marked (enforces BR-ID)
[ ] Open register items reviewed (lookup block below); no open BLK- for this feature
[ ] If promoted from / referencing a prototype: carry-over subsection present, every divergence from the prototype has a reason, Result is not pending
[Open-items lookup block]
[ ] Edge cases from decision table are covered
After inspection: update Feature Card status to 3_Ready_to_Build
Then run /pm-stripe to proceed to build.Edge case backfill mode (--edge-cases)
For Feature Cards designed before Pureinn 5.62.0, which have no Edge Case Coverage table. Run as /pm-feature-design [FEAT-ID] --edge-cases. pm-audit and pm-stripe route here - neither may write edge case ACs itself, because an AC is a behavioral commitment, not a mechanical fix.
Scope. Runs only the edge case part of Step 1.5. Reads the existing ACs, the registers and - in Feature Implementation mode - the code the card's Section 3 names, then fills the table, adds the missing ACs and converts checkbox-list ACs to Given/When/Then. Existing ACs keep their numbers; new ACs take the next free number.
- Section 1 changes only when a new edge case needs a new guard or BR - then the normal Step 3 register update and Commit 1 apply.
- Section 3 changes only when a new guard adds an alt branch to the sequence diagram.
- An undecided behavior becomes an
OQ-[DOMAIN]-NNin the table, never an invented AC.
Behavior by card status:
| Status | Action |
1_Backlog stub | Nothing - the table is produced by the normal design run |
2_Spec_Done / 2b_In_Design / 3_Ready_to_Build | Full backfill + conversion to Given/When/Then. Status does not change. New ACs go through a short Design Inspection that reviews only the new ACs |
4_In_Build | Full backfill. Tell the owner the new ACs are a scope extension of the running build |
5_In_Review | Fill the table. Gaps become ACs marked (follow-up) in the title, verified inside the running review |
6_Shipped | The card is immutable history: only append the table under ### Edge Case Coverage (retro, [date]). Do not add or change ACs. Every gap goes to domain/open_questions.md as a Question stating its impact, and the table cell carries that OQ-ID |
Commit: spec([FEAT-ID]): edge case coverage backfill
Internal completeness checklist
<!-- Claude reference only - not shown to user -->Delivery-plan inputs:
mutex_tagspopulated in Step 4d from Section 3 "Files to modify" (shared surfaces, not leaf files); reason where non-obvious
Open items:
- Open-items lookup shown at Step 0 and re-run at Step 5; register text never copied into the card
- Open
BLK-for this feature → not advanced toward3_Ready_to_Build
Prototype carry-over (only when the card has promoted_from: or a prototype reference):
meta.md,findings.mdand thePRT-card read in full before the interrogation; coverage stated; a missing source named, never reconstructedResult: pending/Refuted within scopesurfaced before designing- Section 3 carries
### Prototype carry-overwith both lists; resolved items trace to findings or the PRT card; Reference prototype → "Changed against the prototype" present even ifnone promoted_from:, the prototype reference block and the prototype folder left untouched
Security dimension:
security_reviewassessed in Step 1.5 against the 8 security areas, verdict stated with the area(s) touchedbuildonly when a NEW security mechanism is introduced (new security BR Draft→Final); reuse of an existing Final security BR → notbuildsecurity_reviewwritten to Feature Card frontmatter in Step 4d (overwrites thenonestub default)
Test type dimension:
test_typesassessed in Step 1.5 against the characteristics table (unit baseline + integration/contract/visual_regression/performance only where triggered)test_typeswritten to Feature Card frontmatter in Step 4d
Register updates:
- Guard conditions added to entities.md (not left as TBD)
- Rules status updated Draft → Final for all rules used
- Decision table rows completed (no TBD cells for rules used)
- Atomic commit 1 made before Section 1-3 work
Feature Card Section 1:
- All relevant entities linked with markdown links
- State before and after specified
- All BR-IDs linked with one-line description
- Decision model linked (if applicable)
Feature Card Section 2:
- Happy path + flag OFF ACs present
- All 6 edge case categories walked in Step 1.5 regardless of criticality
- Edge Case Coverage table complete (AC / N/A with reason / OQ), no empty cell
- Each edge case AC has an [EC-XXX] tag and a test level in test_types scope
- Every BR-ID in Section 1 is enforced by at least one AC marked
(enforces BR-ID)- an N/A category never leaves a rule untested - Each AC uses Given/When/Then format (no checkbox lists)
- "Then" is observable without knowledge of internals
- Edge cases from decision table covered as ACs
Feature Card Section 3:
- Mermaid.js sequenceDiagram syntax used
- Feature Implementation mode: only real existing classes used
- Alt/else paths cover the guard failure scenarios
- Files to modify listed
Atomic commit protocol:
- Commit 1: register updates only (before Section 1-3)
- Commit 2: Feature Card sections (after register commit)
Save to
Feature Card updated in place:
pureinn-workspace/[project-slug]/features/cards/[FEAT-ID].mdRegister updates in place:
pureinn-workspace/[project-slug]/domain/entities.md
pureinn-workspace/[project-slug]/domain/business_rules.md
pureinn-workspace/[project-slug]/domain/decision_models.mdState update → pureinn-workspace/[project-slug]/state.json: update feature status to 2_Spec_Done.
Notion push
After local files are saved, push spec content to Notion so the team can review it there.
Step 1 - Find the Notion page for this feature:
- Read
pureinn-variables.mdkey "Feature Backlog" → get DB URL - Check
state.json notion_ids.feature_backlog→ use cached data source ID or fetch - Query the DB for the entry where
FEAT-ID=[FEAT-ID]→ get the Notion page URL
If Feature Backlog URL is blank or feature entry not found: skip Notion push, continue.
Step 2 - Update the Notion page:
Call mcp__claude_ai_Notion__notion-update-page with command: "replace_content" and the full Feature Card content:
[Description from stub - keep as-is]
[Current state from stub - keep as-is]
---
## 1. Biznis Mantinely (SDD Input)
[Full Section 1 content generated by this skill]
---
## 2. Acceptance Criteria
[Full Section 2 content generated by this skill]
---
## Subtasks (helper notes)
[Subtask helper notes captured during discovery - or "none"]
---
## 3. JIT Technical Design (FDD Design)
[Full Section 3 content generated by this skill]
---
## 4. Realizacny Protokol (Build Verification)
*TBD - populated after build and Code Inspection*Step 3 - Update Status property:
Call mcp__claude_ai_Notion__notion-update-page with command: "update_properties":
Status:"2_Spec_Done"
Handoff
Čo si teraz má: Feature Card Sections 1-3 kompletné + domain registers finalizované. Feature [FEAT-ID] je ready na Design Inspection. Status: 2_Spec_Done.
Ďalší krok: Design Inspection
- Tím: reviewni Sections 1-3, potvrď že ACs sú testovateľné a sequence diagram pokrýva happy path + guard failures.
- Solo: prejdi Sections 1-3, potvrď alebo oprav, potom nastav status na 3_Ready_to_Build.
Použite
/pm-stripepre tracking.
Po Design Inspection: /pm-stripe → routuje na build skills pre [FEAT-ID].
Spec gate - nezačínaj build kým: Status nie je 3_Ready_to_Build.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

