Skip to content

vt-c-pd-capture-decisions

Capture product decisions from a completed pd-* iteration as structured records in docs/decisions/. Preserves the mapping between source evidence, findings, and artifact changes.

Plugin: core-standards
Category: Product Design Workflow
Command: /vt-c-pd-capture-decisions


Product Design: Capture Decisions

Capture the decisions made during a pd-* iteration loop as a structured, persistent record.

Workflow Position

ITERATIVE DESIGN LOOP:

   New Input → /pd-inbox-scan → /pd-analyze-changes → /pd-route-decision → [TARGET PHASE] → [ /pd-capture-decisions ]
                                                                                              ▲ YOU ARE HERE

   After the target phase completes, run this skill to persist decisions before the next inbox scan.

Invocation

/vt-c-pd-capture-decisions              # Capture decisions from current iteration
/vt-c-pd-capture-decisions --dry-run    # Preview record without writing to disk

What This Skill Does

  1. Reads iteration context from .design-state.yaml
  2. Extracts findings from the conversation context (auto-extraction)
  3. Generates a structured decision record with source evidence
  4. Writes to docs/decisions/NNN-YYYY-MM-DD-slug.md
  5. Links the record back to .design-state.yaml

Execution Instructions

Step 0: Read Iteration Context

Read .design-state.yaml and extract: - current_state.phase — the phase that just completed - current_state.iteration — current iteration number - Latest entry in iterations[] — trigger, trigger_details, source items - Latest entry in decisions[] — the routing decision that led here

If no iteration context found:

No iteration context found in .design-state.yaml.
This skill runs after a pd-* iteration loop completes.
Ensure /pd-route-decision was run before the target phase.

Step 1: Extract Findings from Conversation Context

Scan the current conversation for findings produced by /pd-analyze-changes. Extract each finding as:

Field Source
Finding ID F1, F2, F3... from analyze-changes output
Finding Title Summary line from the finding
Source Evidence Speaker name, date, document path, verbatim quote
Interpreted Decision What was decided based on this finding
Artifact Changes Which documents were modified, which sections, what changed
Alternatives Considered Other options discussed (if any)

Auto-extraction rules: - Look for finding blocks (F1, F2, etc.) in the conversation - Extract quoted material as source evidence - Match artifact changes to files modified during the target phase - If no findings are present in context, check if the iteration was a deferral (Option 4 from route-decision) — still create a record documenting the deferral

Edge case EC1: If no findings AND no routing decision exists in context (e.g., inbox scan found nothing), skip capture:

No findings or routing decisions found in this session.
Decision capture skipped — nothing to record.

Step 2: Ensure Output Directory

# Create docs/decisions/ if it doesn't exist
mkdir -p docs/decisions/

Step 3: Determine Record Number

Scan existing files in docs/decisions/ for the highest DEC-NNN number:

# Find existing records
ls docs/decisions/*.md 2>/dev/null
  • Parse filenames matching pattern NNN-*.md
  • Next number = max(existing NNN) + 1
  • If no existing records, start at 001

Edge case EC4: If a file with the computed number already exists (race condition), increment until a free number is found.

Step 4: Generate Decision Record

Construct the record using the following format:

---
id: DEC-NNN
date: YYYY-MM-DD
phase: {phase that was executed, e.g., pd-2-prd}
iteration: {iteration number}
trigger: {trigger type from iteration entry, e.g., stakeholder_feedback}
source_items:
  - "{path to source document}"
findings: [F1, F2, ...]
artifacts_changed:
  - "{path to changed artifact}"
tags: [{relevant domain tags}]
---

# DEC-NNN: {Descriptive Title}

## Source Evidence

### F1: {Finding Title}
**Source**: {Speaker}, {Date}, {Document}
> Verbatim quote from source material

### F2: {Finding Title}
**Source**: {Speaker}, {Date}, {Document}
> Verbatim quote from source material

## Decisions Made

| Finding | Decision | Rationale | Alternative Considered |
|---------|----------|-----------|----------------------|
| F1 | {what was decided} | {why} | {other option, or "None"} |
| F2 | {what was decided} | {why} | {other option, or "None"} |

## Artifact Changes

| Artifact | Section | Change Type | Description |
|----------|---------|-------------|-------------|
| {file path} | {section name} | Added/Modified/Removed | {what changed} |

## Open Questions

- {Any unresolved questions from the iteration, or "None"}

Edge case EC3: If a finding references a file that was routed by /pd-inbox-scan (moved from inbox to another location), use the original path in source evidence and add a note: (routed to {destination}).

Step 5: Dry-Run Check

If --dry-run was passed:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DRY RUN: Decision Record Preview
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

{full record content}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
File would be written to: docs/decisions/NNN-YYYY-MM-DD-slug.md
To write, run again without --dry-run.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Stop here. Do not write the file or update state.

Step 6: Write Decision Record

Write the record to docs/decisions/NNN-YYYY-MM-DD-slug.md where: - NNN — zero-padded record number from Step 3 - YYYY-MM-DD — today's date - slug — kebab-case summary of the decision topic (max 5 words)

Step 7: Update Design State

Update .design-state.yaml to link the record to the current iteration:

  1. Find the latest iterations[] entry
  2. Add decision_record field:
iterations:
  - number: {n}
    # ... existing fields ...
    decision_record: "docs/decisions/NNN-YYYY-MM-DD-slug.md"

If the iteration already has a decision_record (edge case EC2 — multiple captures in one session), convert to decision_records array:

    decision_records:
      - "docs/decisions/NNN-YYYY-MM-DD-first.md"
      - "docs/decisions/NNN-YYYY-MM-DD-second.md"

Step 8: Display Confirmation

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Decision Record Captured
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Record: docs/decisions/NNN-YYYY-MM-DD-slug.md
ID: DEC-NNN
Phase: {phase}
Iteration: {n}
Findings: {count} captured
Artifacts: {count} changed

State updated: .design-state.yaml iteration entry linked

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  • /vt-c-pd-analyze-changes — Produces findings consumed by this skill
  • /vt-c-pd-route-decision — Triggers the target phase before this skill runs
  • /vt-c-pd-6-handoff — Reads decision records for design journey enrichment
  • /vt-c-pd-inbox-scan — Starts the next iteration after decisions are captured

Open Brain Capture (Optional)

After writing the decision record, if the capture_thought MCP tool is available, capture the decision to Open Brain.

When to capture: After every finalized decision record.

How: 1. Check if capture_thought tool is available. If not: skip silently. 2. If the decision content is empty: skip capture. 3. Call capture_thought with:

thought: "Product Decision: {decision title}. Rationale: {why this was chosen}. Alternatives considered: {list}. Source: {spec or iteration that triggered this}."
4. On timeout or error: log debug message and continue. Never fail the skill.

This step is always last — it never interrupts the pd-capture-decisions workflow.