ALWAYS invoke this skill when creating or organizing specs, capabilities, features, stories, or ADRs. NEVER create, read, or modify any files in the spx/ directory without this skill.
From spx-legacynpx claudepluginhub outcomeeng/claude --plugin spx-legacyThis skill uses the workspace's default tool permissions.
templates/decisions/architectural-decision.adr.mdtemplates/decisions/product-decision.pdr.mdtemplates/outcomes/capability-name.capability.mdtemplates/outcomes/feature-name.feature.mdtemplates/outcomes/story-name.story.mdtemplates/product/product.prd.mdGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Details PluginEval's skill quality evaluation: 3 layers (static, LLM judge), 10 dimensions, rubrics, formulas, anti-patterns, badges. Use to interpret scores, improve triggering, calibrate thresholds.
/understanding-durable-map - Specs are permanent product documentation, not work items/understanding-outcome-decomposition - What belongs at each level (capability/feature/story)If you find yourself wanting to "close" items or thinking in tasks, read these first. </prerequisite>
<quick_start> Different use cases read different sections:
<accessing_templates> FIRST to understand where templates are located<structure_definition> for spx/ directory hierarchy, BSP numbering, test co-location<adr_templates> for Architectural Decision Record patterns<pdr_templates> for Product Decision Record patterns<requirement_templates> for Product Requirements<work_item_templates> for capability, feature, and story patternsUse progressive disclosure - read only what you need. </quick_start>
<accessing_templates>
<how_to_access> All templates are stored within this skill's base directory.
When this skill is invoked, you are provided the base directory in the loading message:
Base directory for this skill: {skill_dir}
Use this exact path for all file access. Throughout this documentation, ${SKILL_DIR} is a placeholder—Claude must substitute it manually from the loading message.
IMPORTANT: Do NOT search the project directory for skill files. </how_to_access>
<template_organization>
All templates are under ${SKILL_DIR}/templates/:
${SKILL_DIR}/
├── SKILL.md # This file
└── templates/
├── product/
│ └── product.prd.md
├── decisions/
│ ├── architectural-decision.adr.md
│ └── product-decision.pdr.md
└── outcomes/
├── capability-name.capability.md
├── feature-name.feature.md
└── story-name.story.md
</template_organization>
<how_to_read_templates>
Always use the skill's base directory, not the user's project directory.
# Pattern
Read: ${SKILL_DIR}/templates/{category}/{template-name}
# Example: Read feature template
Read: ${SKILL_DIR}/templates/outcomes/feature-name.feature.md
</how_to_read_templates>
</accessing_templates>
<structure_definition>
<overview> The spx/ directory follows the Outcome Engineering framework structure. </overview><three_phase_transformation>
</three_phase_transformation>
<directory_structure>
spx/
├── {product-name}.prd.md # Product requirements
├── NN-{slug}.adr.md # Product-wide ADRs (interleaved)
├── NN-{slug}.pdr.md # Product-wide PDRs (interleaved)
└── NN-{slug}.capability/
├── {slug}.capability.md
├── tests/
├── NN-{slug}.adr.md # Capability-scoped ADRs (interleaved)
├── NN-{slug}.pdr.md # Capability-scoped PDRs (interleaved)
└── NN-{slug}.feature/
├── {slug}.feature.md
├── tests/
├── NN-{slug}.adr.md # Feature-scoped ADRs (interleaved)
├── NN-{slug}.pdr.md # Feature-scoped PDRs (interleaved)
└── NN-{slug}.story/
├── {slug}.story.md
└── tests/
</directory_structure>
<work_item_hierarchy>
Capability: Product-wide impact, contains features
spx/NN-{slug}.capability/tests/Feature: Specific functionality, contains stories
spx/.../NN-{slug}.feature/tests/Story: Atomic implementation unit, no children
spx/.../NN-{slug}.story/tests/Test level (unit, integration, e2e) is determined per-component by the evidence needed, not by hierarchy level. See /testing for the methodology.
</work_item_hierarchy>
<key_principles>
<bsp_full_paths> below)spx/.../tests/ permanently (no graduation)</key_principles>
<bsp_full_paths>
🚨 CRITICAL: BSP numbers repeat at different levels—always use full paths.
21-foo.capability/21-bar.feature/54-baz.story/ ← One story-54
21-foo.capability/37-qux.feature/54-baz.story/ ← DIFFERENT story-54
37-other.capability/21-bar.feature/54-baz.story/ ← DIFFERENT story-54
ALWAYS use the FULL PATH when referencing work items:
| ❌ WRONG (Ambiguous) | ✅ CORRECT (Unambiguous) |
|---|---|
| "story-54" | "21-foo.capability/21-bar.feature/54-baz.story/" |
| "implement feature-21" | "implement 21-foo.capability/21-bar.feature/" |
| "Continue with story-54" | "Continue 21-foo.capability/21-bar.feature/54-baz.story/" |
Why this matters:
When communicating about work items:
spx/</bsp_full_paths>
</structure_definition>
<workflow><reading_status>
<understanding_work_items>
<three_states> Status values:
| State | Meaning |
|---|---|
| OPEN | Work not started |
| IN_PROGRESS | Work underway |
| DONE | Complete |
</three_states>
<bsp_dependency_order>
Lower BSP = dependency. Higher-BSP items may rely on lower-BSP items.
Check dependencies before working on an item—lower-numbered items in the same scope may need to be done first.
This applies at every level:
| If you see... | It means... |
|---|---|
48-foo.feature/ before 87-bar.feature/ | 48-foo MUST be DONE before 87-bar starts |
21-foo.story/ before 32-bar.story/ | 21-foo MUST be DONE before 32-bar starts |
48-foo [OPEN], 87-bar [IN_PROGRESS] | BUG: Dependency violation |
</bsp_dependency_order>
<finding_next_work_item>
1. List all work items in BSP order (capability → feature → story)
2. Return the FIRST item where status ≠ DONE
3. That item blocks everything after it
Example:
48-test-harness.feature/ [OPEN] ← Was added after 87 but blocks it
87-e2e-workflow.feature/ [IN_PROGRESS] ← Was already started, then dependency discovered
Next work item: 48-test-harness.feature/ → its first OPEN story.
</finding_next_work_item>
</understanding_work_items>
</reading_status>
<managing_items>
<managing_work_items>
<numbering_work_items>
<bsp_numbering> Two-digit prefixes in range [10, 99] encode dependency order. </bsp_numbering>
<creating_new_items>
<case_1_first_item>
Use position 21 (leaves room for ~10 items before/after):
# First feature in a new capability
21-foo.capability/
└── 21-first-feature.feature/
</case_1_first_item>
<case_2_insert_between>
Use midpoint: new = floor((left + right) / 2)
# Insert between 21 and 54
new = floor((21 + 54) / 2) = 37
21-first.feature/
37-inserted.feature/ ← NEW
54-second.feature/
</case_2_insert_between>
<case_3_append_after>
Use midpoint to upper bound: new = floor((last + 99) / 2)
# Append after 54
new = floor((54 + 99) / 2) = 76
21-first.feature/
54-second.feature/
76-appended.feature/ ← NEW
</case_3_append_after>
</creating_new_items>
</numbering_work_items>
<creating_work_items> Every work item needs:
NN-{slug}.{type}/ (e.g., 21-auth.capability/){slug}.{type}.md (e.g., auth.capability.md)tests/ (create when starting work)Optional:
NN-{slug}.adr.md or NN-{slug}.pdr.md (interleaved with work items)</creating_work_items>
</managing_work_items>
</managing_items>
</workflow><adr_templates>
<overview> ADRs document technical choices with trade-offs and consequences. </overview><template_location>
${SKILL_DIR}/templates/decisions/architectural-decision.adr.md
</template_location>
<usage>Read the template and adapt:
# Read ADR template
Read: ${SKILL_DIR}/templates/decisions/architectural-decision.adr.md
# Adapt for your decision
- State the architectural concern this decision governs (atemporal voice — no history)
- Document the chosen option and rationale
- Specify consequences and trade-offs
- Define compliance criteria
</usage>
<scope_levels>
ADRs are interleaved with work items at any level:
spx/NN-{slug}.adr.mdspx/NN-{slug}.capability/NN-{slug}.adr.mdspx/.../NN-{slug}.feature/NN-{slug}.adr.mdStories inherit decisions from parent feature/capability.
</scope_levels>
<naming_convention>
Format: NN-{slug}.adr.md
use-postgresql-for-persistence)</naming_convention>
<bsp_numbering_for_adrs>
Lower BSP = dependency. Higher-BSP ADRs may rely on lower-BSP decisions.
ADRs follow the same BSP numbering as work items:
<creating_first_adr>
Use position 21 (leaves room for ~10 items before/after):
21-first-decision.adr.md
</creating_first_adr>
<inserting_between_adrs>
Use midpoint: new = floor((left + right) / 2)
# Insert between 21 and 54
new = floor((21 + 54) / 2) = 37
21-type-safety.adr.md
37-inserted-decision.adr.md ← NEW
54-cli-framework.adr.md
</inserting_between_adrs>
<appending_after_last>
Use midpoint to upper bound: new = floor((last + 99) / 2)
# Append after 54
new = floor((54 + 99) / 2) = 76
21-type-safety.adr.md
54-cli-framework.adr.md
76-appended-decision.adr.md ← NEW
</appending_after_last>
</bsp_numbering_for_adrs>
<dependency_order_within_scope>
Scope boundaries: ADRs are scoped to product/capability/feature.
Within scope: Lower BSP = dependency that higher-BSP items may rely on.
| If you see... | It means... |
|---|---|
21-type-safety.adr.md | Foundational decision, others may depend |
37-validation.adr.md | May depend on 21 |
54-cli-framework.adr.md | May depend on both 21 and 37 |
Cross-scope dependencies: Must be documented explicitly in the ADR content.
| Dependency | How to Express |
|---|---|
| Feature ADR depends on capability ADR | Reference in "Context" section with link |
| Capability ADR depends on product ADR | Reference in "Context" section with link |
</dependency_order_within_scope>
<why_bsp_numbering>
Problem: Sequential numbering (01, 02, 03) cannot accommodate discovered dependencies.
Example: You have decisions adr-01, adr-02, adr-03. You discover adr-02 needs a prior decision about type safety. With sequential numbering, you must renumber all subsequent ADRs.
Solution: BSP numbering allows insertion at any point using midpoint calculation.
</why_bsp_numbering>
<why_no_numbers_in_content>
Problem: If ADR file is renumbered (e.g., adr-23 → adr-37), content with embedded numbers becomes stale.
Examples:
# ADR 23: Foo - wrong after renumberingSolution:
# ADR: Foo (document type prefix, no number)[Foo](37-foo.adr.md) (markdown link with path)</why_no_numbers_in_content>
<why_markdown_links_only>
Problem: Plain text references like "ADR-23" or even `23-foo.adr.md` break when files are renumbered.
Solution: Markdown links [Decision Title](NN-slug.adr.md):
</why_markdown_links_only>
</adr_templates>
<pdr_templates>
<overview> PDRs document product behavior decisions with trade-offs and user impact. Unlike ADRs (which govern code architecture), PDRs govern observable product behavior. </overview><template_location>
${SKILL_DIR}/templates/decisions/product-decision.pdr.md
</template_location>
<usage>Read the template and adapt:
# Read PDR template
Read: ${SKILL_DIR}/templates/decisions/product-decision.pdr.md
# Adapt for your decision
- State the product behavior this decision governs (atemporal voice — no history)
- Describe the chosen product behavior
- List product invariants users can rely on
- Specify compliance criteria for product behavior
</usage>
<scope_levels>
PDRs are interleaved with work items at any level:
spx/NN-{slug}.pdr.mdspx/NN-{slug}.capability/NN-{slug}.pdr.mdspx/.../NN-{slug}.feature/NN-{slug}.pdr.mdStories inherit product decisions from parent feature/capability.
</scope_levels>
<naming_convention>
Format: NN-{slug}.pdr.md
simulation-lifecycle-phases)</naming_convention>
<adr_vs_pdr>
| Aspect | ADR | PDR |
|---|---|---|
| Governs | Code architecture | Product behavior |
| Invariants | Algebraic code properties | Observable user guarantees |
| Compliance | Code review criteria | Product behavior validation |
| Example | "Use PostgreSQL for persistence" | "Simulation has three phases" |
When to use which:
</adr_vs_pdr>
</pdr_templates>
<referencing_decisions>
<overview> **Always use markdown links with descriptive titles for both ADRs and PDRs.** </overview><in_markdown_documents>
<within_same_directory>
See [Type Safety](21-type-safety.adr.md) for validation approach.
</within_same_directory>
<from_child_to_parent_scope>
<!-- Feature ADR referencing capability ADR -->
This decision builds on [Config Loading](../21-config-loading.adr.md).
<!-- Story referencing feature ADR -->
Implementation follows [CLI Structure](../21-cli-structure.adr.md).
</from_child_to_parent_scope>
<from_work_item_to_adr>
<!-- From story to capability ADR -->
Architectural constraints: [Commander Pattern](../../21-commander-pattern.adr.md)
<!-- From feature to product ADR -->
Type system: [Type Safety](../../../21-type-safety.adr.md)
</from_work_item_to_adr>
</in_markdown_documents>
<never_use_these_formats>
❌ Plain text reference: "See ADR-21" or "See PDR-21"
❌ Code-only reference: `21-type-safety.adr.md` or `21-lifecycle.pdr.md`
❌ Number-only reference: "ADR 21 specifies..." or "PDR 21 specifies..."
</never_use_these_formats>
<why_markdown_links>
</why_markdown_links>
</referencing_decisions>
<requirement_templates>
<overview> Templates for Product Requirements (PRD). </overview><prd_template>
Location: ${SKILL_DIR}/templates/product/product.prd.md
Purpose: Product requirements - user value, customer journey, measurable outcomes
Usage:
# Read PRD template
Read: ${SKILL_DIR}/templates/product/product.prd.md
# Adapt for product change
- Define user value proposition
- Document measurable outcomes with targets
- Specify acceptance criteria
- Avoid implementation details
Placement:
spx/{product-name}.prd.mdspx/NN-{slug}.capability/{topic}.prd.md</prd_template>
<requirements_rules>
</requirements_rules>
</requirement_templates>
<work_item_templates>
<overview> Templates for capabilities, features, and stories. </overview><template_locations>
${SKILL_DIR}/templates/outcomes/capability-name.capability.md
${SKILL_DIR}/templates/outcomes/feature-name.feature.md
${SKILL_DIR}/templates/outcomes/story-name.story.md
</template_locations>
<usage_pattern>
# For capability
Read: ${SKILL_DIR}/templates/outcomes/capability-name.capability.md
Adapt: Replace {slug} with kebab-case name
Fill functional requirements
Add user value context
# For feature
Read: ${SKILL_DIR}/templates/outcomes/feature-name.feature.md
Adapt: Replace {slug} with kebab-case name
Specify integration scope
Define component interactions
# For story
Read: ${SKILL_DIR}/templates/outcomes/story-name.story.md
Adapt: Replace {slug} with kebab-case name
Detail atomic implementation
List specific functions/classes
</usage_pattern>
<file_placement>
Work items follow this pattern:
spx/{BSP}-{slug}.{type}/{slug}.{type}.md
Examples:
spx/21-core-cli.capability/core-cli.capability.mdspx/21-core-cli.capability/10-init.feature/init.feature.mdspx/21-core-cli.capability/15-init.feature/87-parse-flags.story/parse-flags.story.md</file_placement>
<test_verification>
Tests stay co-located with their specs permanently. Test level is indicated by filename suffix (.unit.test.*, .integration.test.*, .e2e.test.*) but is not tied to hierarchy level — any test level can appear at any node. See /testing for how to determine the right level.
</test_verification>
</work_item_templates>
<success_criteria> Skill is working correctly when:
templates/ subdirectories</success_criteria>