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
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.
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.
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 |
Time to Market · TCO · Flexibility · Vendor Lock-In · Maintenance Burden |
| Choose an architecture or platform |
assets/templates/technical-architecture.json |
Performance · Scalability · Team Fit · Operational Cost · Ecosystem Maturity · Security |
| Prioritize a backlog (RICE) |
assets/templates/product-prioritization.json |
Reach · Impact · Confidence · Effort |
| Select among candidates or vendors |
assets/templates/hiring-candidate.json |
Technical Skill · Communication · Culture Fit · Domain Experience · Growth Potential |
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.
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. 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.
Run — serialize to a decision spec JSON and run the engine:
python3 -m scripts.score --spec <spec.json> --record.
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 |
| Compare against an incumbent/baseline |
Pugh matrix |
references/pugh-matrix.md |
| Prioritize a backlog |
RICE / WSJF / ICE |
references/product-frameworks.md |
| Feature satisfaction tiers |
Kano |
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 |
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.
1---2name: decision-matrix3description: 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).4license: Apache 2.05---67# Decision Matrix — quantitative weighted-decision engine89Turn a choice into a deterministic, recorded decision. The agent elicits and frames; **the script does10all math** (scoring, sensitivity, ties, aggregation). Never compute scores by hand — if the script11errors, surface it and stop; do not guess.1213**Decide, do not ask.** A fork that reaches this skill is the agent's to resolve. Score it, record the14DEC, report the winner and the deciding reason in one line, and keep working. Handing the user a menu15of options is the failure this skill exists to prevent (`.claude/rules/common/decision-authority.md`).1617## Workflow18191. **Frame** — restate the decision goal in one line, and its reversibility (`two-way` / `one-way`).20 A one-way door with a non-low-confidence winner gets promoted to an ADR at the end.212. **Options** — 2+ real alternatives. "Do nothing" is a legitimate option and usually belongs in the22 set. If you cannot state what distinguishes two options, they are one option.233. **Criteria + weights** — propose criteria with default weights (0–100); flag if one criterion24 dominates (>60% of weight). Mark each `higher-is-better` or `lower-is-better`.25 **Start from a template when one fits** — a complete worked spec, criteria and weights included,26 is a better starting point than re-deriving the set from scratch. Adapt it; never ship it27 unedited, and never keep a criterion the decision does not actually turn on.2829 | Decision shape | Template | Criteria it starts you with |30 |---|---|---|31 | 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 |32 | Choose an architecture or platform | [`assets/templates/technical-architecture.json`](assets/templates/technical-architecture.json) | Performance · Scalability · Team Fit · Operational Cost · Ecosystem Maturity · Security |33 | Prioritize a backlog (RICE) | [`assets/templates/product-prioritization.json`](assets/templates/product-prioritization.json) | Reach · Impact · Confidence · Effort |34 | Select among candidates or vendors | [`assets/templates/hiring-candidate.json`](assets/templates/hiring-candidate.json) | Technical Skill · Communication · Culture Fit · Domain Experience · Growth Potential |354. **Constraints** — hard disqualifiers, captured *before* scoring. A vetoed option is eliminated36 regardless of how well it scores; that is the point of a constraint rather than a heavy weight.375. **Score** — 0–100 per option × criterion, per scorer. Elicit them the way `grilling` elicits38 anything: **one at a time, always with a recommended value and its reasoning, and by reading the39 codebase instead of asking whenever the answer is on disk.** See40 [references/elicitation.md](references/elicitation.md). **More than one scorer** — a group41 decision, or one person scoring in two roles — changes how the numbers combine and adds a42 `multi_scorer_analysis` block reporting conflicts and outliers:43 [references/multi-scorer.md](references/multi-scorer.md).446. **Run** — serialize to a decision spec JSON and run the engine:45 `python3 -m scripts.score --spec <spec.json> --record`.467. **Present** — the scored matrix, the ranked recommendation, disagreement/fragility, the HTML47 artifact, and the recorded `DEC-####`. Say plainly that the decision is reversible by re-running48 with different weights.4950## Engine interface5152- Input: decision-spec JSON (`references/decision-spec-schema.md`).53- Run: `python3 -m scripts.score [--spec <path>] [--record]` from this skill directory; JSON spec on54 stdin if `--spec` omitted. Result JSON to stdout; errors to stderr with exit 1.55- `--record` writes `DEC-####-<slug>.md` into the ledger and upserts its index. Without it, nothing56 is written — a decision worth making is worth recording, so default to recording.57- **Which ledger: the one that owns the decision.** A decision about a project is recorded in that58 project's `docs/decisions/`; only harness decisions go to `.claude/docs/decisions/`. Declare it in59 the spec — `"decisions_dir": "projects/<name>/docs/decisions"` — or pass `--decisions-dir <path>`.60 Precedence: flag > spec key > harness ledger. Relative paths resolve against the repository root,61 not the working directory, because the engine is run from this skill's directory.62 **Recording a project's decision in the harness ledger inflates the harness DEC sequence and hides63 the decision from the project that owns it.** When the workspace contains any64 `projects/*/docs/decisions/` and the spec declares no `decisions_dir`, `--record` prints a warning65 naming every candidate ledger before it writes — the destination was defaulted, not chosen66 (DEC-0023). Declaring the key silences it, including for a genuine harness decision:67 `"decisions_dir": ".claude/docs/decisions"` is a statement, the default is an assumption.68- Visual: `node scripts/visual.mjs <result.json>` → self-contained HTML to stdout.6970**The engine refuses an incomplete spec on purpose.** A missing score is a question nobody answered;71filling it with a plausible number launders a guess as arithmetic.7273## Method selection7475The engine runs every applicable method and compares them; **method disagreement is a headline76signal**, not an error. Default winner = weighted-sum rank 1, cross-checked against the others.7778| Decision shape | Methods emphasized | Reference |79|---|---|---|80| Few options, clear weighted criteria | weighted-sum, TOPSIS | [references/topsis.md](references/topsis.md) |81| Compare against an incumbent/baseline | Pugh matrix | [references/pugh-matrix.md](references/pugh-matrix.md) |82| Prioritize a backlog | RICE / WSJF / ICE | [references/product-frameworks.md](references/product-frameworks.md) |83| Feature satisfaction tiers | Kano | [references/product-frameworks.md](references/product-frameworks.md) |8485Read the method's reference before overriding the default winner — each one states what its numbers86mean and where it misleads.8788## Reading the result8990| Signal | What it means | What to do |91|---|---|---|92| Methods disagree on rank 1 | The winner depends on the aggregation, not the evidence | Report both; pick the reversible option |93| `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) |94| `criteria_quality.warnings` → `overweight` | One criterion is the decision | Either accept that explicitly, or rebalance and re-run |95| `non-discriminating` criterion | It scores every option alike | Drop it — it adds arithmetic, not information |96| All options vetoed | The constraints are the real decision | Quote `veto_reasons` — the engine names the binding constraint; do not relax one silently |97| `promote_to_adr_hint` true | One-way door, decided with confidence | Write the ADR (`architecture-decision-records`) |9899## Hand-offs100101| Situation | Next |102|---|---|103| Options and criteria are still fuzzy | `decision-mapping` first, then come back to score |104| Prioritizing roadmap items | `roadmap prioritize --export` → score → `roadmap prioritize --from` |105| Criteria need an interview to pin down | `grilling` / `grill-with-docs` |106| Winner is irreversible | `architecture-decision-records` — promote the DEC to an ADR |107| The chosen option is a multi-PR effort | `blueprint`, then register its steps in `roadmap` |108| Problem needs rollout search, not scoring | `recursive-decision-ledger` |109110A DEC produced while prioritizing lands on each roadmap item as `priority.dec`, so the ordering in111`roadmap next` carries the audit trail of why it is ordered that way.112113## Failure modes114115- **Scoring to a predetermined winner.** If you already know the answer, say so and skip the theatre;116 a rigged matrix is worse than an opinion, because it looks like evidence.117- **Criteria that are really one criterion.** Three flavours of "developer experience" triple that118 concern's weight silently. The `redundant` warning catches labels, not synonyms — you catch synonyms.119- **Constraints entered as heavy weights.** A must-have is a veto. A 90-weight criterion still lets a120 strong option win without it.121- **Stopping to ask which option to take.** See the top of this file.122- **Not recording.** An unrecorded decision gets re-litigated in three weeks with none of the reasoning.123124## Related skills125126- `decision-mapping` — qualitative trade-off framing (use first to surface criteria; this skill scores them).127- `recursive-decision-ledger` — stochastic rollout search; this skill reuses its numbered-ledger notion (`DEC-####`).128- `architecture-decision-records` — promote an irreversible DEC to a full ADR.129- `roadmap` — owns the prioritization hand-off in both directions.