# Decision Matrix

> Use when choosing between options or prioritizing — "decide", "choose between", "which should I pick", "compare options", "trade-off", "which library/framework/database/vendor", "build vs buy", "best option for", "prioritize", "rank these", "RICE/WSJF". A quantitative weighted-decision engine: scores options against weighted criteria with multiple methods (weighted-sum, Pugh, TOPSIS/AHP, RICE/WSJF/ICE/Kano), runs sensitivity analysis, flags when methods disagree, applies hard-constraint vetoes, aggregates multiple scorers, and records a numbered DEC decision. Fire this for ANY non-trivial multi-option choice or prioritization, even a mid-task internal fork — the math is deterministic and the decision is recorded. Not for qualitative-only trade-off framing (use decision-mapping) or stochastic rollout search (use recursive-decision-ledger).

- Skill: `rubyeyedreaper/decision-matrix` (Agent Skill, multi-file: 49 files)
- Install (CLI): `npx skillmds@latest add rubyeyedreaper/decision-matrix`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rubyeyedreaper/decision-matrix/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- License: Apache 2.0
- Author: RubyEyedReaper (https://skillmd.com/u/rubyeyedreaper)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/rubyeyedreaper/decision-matrix

---


# Decision Matrix — quantitative weighted-decision engine

Turn a choice into a deterministic, recorded decision. The agent elicits and frames; **the script does
all math** (scoring, sensitivity, ties, aggregation). Never compute scores by hand — if the script
errors, surface it and stop; do not guess.

**Decide, do not ask.** A fork that reaches this skill is the agent's to resolve. Score it, record the
DEC, report the winner and the deciding reason in one line, and keep working. Handing the user a menu
of options is the failure this skill exists to prevent (`.claude/rules/common/decision-authority.md`).

## Workflow

1. **Frame** — restate the decision goal in one line, and its reversibility (`two-way` / `one-way`).
   A one-way door with a non-low-confidence winner gets promoted to an ADR at the end.
2. **Options** — 2+ real alternatives. "Do nothing" is a legitimate option and usually belongs in the
   set. If you cannot state what distinguishes two options, they are one option.
3. **Criteria + weights** — propose criteria with default weights (0–100); flag if one criterion
   dominates (>60% of weight). Mark each `higher-is-better` or `lower-is-better`.
   **Start from a template when one fits** — a complete worked spec, criteria and weights included,
   is a better starting point than re-deriving the set from scratch. Adapt it; never ship it
   unedited, and never keep a criterion the decision does not actually turn on.

   | Decision shape | Template | Criteria it starts you with |
   |---|---|---|
   | Build in-house vs buy a vendor product | [`assets/templates/build-vs-buy.json`](assets/templates/build-vs-buy.json) | Time to Market · TCO · Flexibility · Vendor Lock-In · Maintenance Burden |
   | Choose an architecture or platform | [`assets/templates/technical-architecture.json`](assets/templates/technical-architecture.json) | Performance · Scalability · Team Fit · Operational Cost · Ecosystem Maturity · Security |
   | Prioritize a backlog (RICE) | [`assets/templates/product-prioritization.json`](assets/templates/product-prioritization.json) | Reach · Impact · Confidence · Effort |
   | Select among candidates or vendors | [`assets/templates/hiring-candidate.json`](assets/templates/hiring-candidate.json) | Technical Skill · Communication · Culture Fit · Domain Experience · Growth Potential |
4. **Constraints** — hard disqualifiers, captured *before* scoring. A vetoed option is eliminated
   regardless of how well it scores; that is the point of a constraint rather than a heavy weight.
5. **Score** — 0–100 per option × criterion, per scorer. Elicit them the way `grilling` elicits
   anything: **one at a time, always with a recommended value and its reasoning, and by reading the
   codebase instead of asking whenever the answer is on disk.** See
   [references/elicitation.md](references/elicitation.md). **More than one scorer** — a group
   decision, or one person scoring in two roles — changes how the numbers combine and adds a
   `multi_scorer_analysis` block reporting conflicts and outliers:
   [references/multi-scorer.md](references/multi-scorer.md).
6. **Run** — serialize to a decision spec JSON and run the engine:
   `python3 -m scripts.score --spec <spec.json> --record`.
7. **Present** — the scored matrix, the ranked recommendation, disagreement/fragility, the HTML
   artifact, and the recorded `DEC-####`. Say plainly that the decision is reversible by re-running
   with different weights.

## Engine interface

- Input: decision-spec JSON (`references/decision-spec-schema.md`).
- Run: `python3 -m scripts.score [--spec <path>] [--record]` from this skill directory; JSON spec on
  stdin if `--spec` omitted. Result JSON to stdout; errors to stderr with exit 1.
- `--record` writes `DEC-####-<slug>.md` into the ledger and upserts its index. Without it, nothing
  is written — a decision worth making is worth recording, so default to recording.
- **Which ledger: the one that owns the decision.** A decision about a project is recorded in that
  project's `docs/decisions/`; only harness decisions go to `.claude/docs/decisions/`. Declare it in
  the spec — `"decisions_dir": "projects/<name>/docs/decisions"` — or pass `--decisions-dir <path>`.
  Precedence: flag > spec key > harness ledger. Relative paths resolve against the repository root,
  not the working directory, because the engine is run from this skill's directory.
  **Recording a project's decision in the harness ledger inflates the harness DEC sequence and hides
  the decision from the project that owns it.** When the workspace contains any
  `projects/*/docs/decisions/` and the spec declares no `decisions_dir`, `--record` prints a warning
  naming every candidate ledger before it writes — the destination was defaulted, not chosen
  (DEC-0023). Declaring the key silences it, including for a genuine harness decision:
  `"decisions_dir": ".claude/docs/decisions"` is a statement, the default is an assumption.
- Visual: `node scripts/visual.mjs <result.json>` → self-contained HTML to stdout.

**The engine refuses an incomplete spec on purpose.** A missing score is a question nobody answered;
filling it with a plausible number launders a guess as arithmetic.

## Method selection

The engine runs every applicable method and compares them; **method disagreement is a headline
signal**, not an error. Default winner = weighted-sum rank 1, cross-checked against the others.

| Decision shape | Methods emphasized | Reference |
|---|---|---|
| Few options, clear weighted criteria | weighted-sum, TOPSIS | [references/topsis.md](references/topsis.md) |
| Compare against an incumbent/baseline | Pugh matrix | [references/pugh-matrix.md](references/pugh-matrix.md) |
| Prioritize a backlog | RICE / WSJF / ICE | [references/product-frameworks.md](references/product-frameworks.md) |
| Feature satisfaction tiers | Kano | [references/product-frameworks.md](references/product-frameworks.md) |

Read the method's reference before overriding the default winner — each one states what its numbers
mean and where it misleads.

## Reading the result

| Signal | What it means | What to do |
|---|---|---|
| Methods disagree on rank 1 | The winner depends on the aggregation, not the evidence | Report both; pick the reversible option |
| `near_tie_pairs` includes the winner | The lead is inside the noise | Say so; decide on a tiebreaker criterion and name it — [references/sensitivity-analysis.md](references/sensitivity-analysis.md) |
| `criteria_quality.warnings` → `overweight` | One criterion is the decision | Either accept that explicitly, or rebalance and re-run |
| `non-discriminating` criterion | It scores every option alike | Drop it — it adds arithmetic, not information |
| All options vetoed | The constraints are the real decision | Quote `veto_reasons` — the engine names the binding constraint; do not relax one silently |
| `promote_to_adr_hint` true | One-way door, decided with confidence | Write the ADR (`architecture-decision-records`) |

## Hand-offs

| Situation | Next |
|---|---|
| Options and criteria are still fuzzy | `decision-mapping` first, then come back to score |
| Prioritizing roadmap items | `roadmap prioritize --export` → score → `roadmap prioritize --from` |
| Criteria need an interview to pin down | `grilling` / `grill-with-docs` |
| Winner is irreversible | `architecture-decision-records` — promote the DEC to an ADR |
| The chosen option is a multi-PR effort | `blueprint`, then register its steps in `roadmap` |
| Problem needs rollout search, not scoring | `recursive-decision-ledger` |

A DEC produced while prioritizing lands on each roadmap item as `priority.dec`, so the ordering in
`roadmap next` carries the audit trail of why it is ordered that way.

## Failure modes

- **Scoring to a predetermined winner.** If you already know the answer, say so and skip the theatre;
  a rigged matrix is worse than an opinion, because it looks like evidence.
- **Criteria that are really one criterion.** Three flavours of "developer experience" triple that
  concern's weight silently. The `redundant` warning catches labels, not synonyms — you catch synonyms.
- **Constraints entered as heavy weights.** A must-have is a veto. A 90-weight criterion still lets a
  strong option win without it.
- **Stopping to ask which option to take.** See the top of this file.
- **Not recording.** An unrecorded decision gets re-litigated in three weeks with none of the reasoning.

## Related skills

- `decision-mapping` — qualitative trade-off framing (use first to surface criteria; this skill scores them).
- `recursive-decision-ledger` — stochastic rollout search; this skill reuses its numbered-ledger notion (`DEC-####`).
- `architecture-decision-records` — promote an irreversible DEC to a full ADR.
- `roadmap` — owns the prioritization hand-off in both directions.

