decision-matrix Specification
Purpose
TBD - created by archiving change add-decision-matrix. Update Purpose after archive.
Requirements
Requirement: Matrix location and identity
The decision matrix SHALL be a single directory tree per project at
.wai/projects/<project>/designs/matrix/. It SHALL contain problem.md
(the decision being deliberated), criteria/, approaches/, and
decision.md. The filesystem is the source of truth; the CLI is sugar over
plain file operations.
Scenario: Init scaffolds the matrix
- GIVEN a project without a matrix
- WHEN
wai matrix initruns with a problem statement - THEN
designs/matrix/containsproblem.md,criteria/,approaches/01-status-quo/with_description.md, and an emptydecision.md
Scenario: One matrix per project
- GIVEN a project that already has
designs/matrix/ - WHEN
wai matrix initruns - THEN the command fails with an error naming the existing matrix
Requirement: Cell encoding
Each cell SHALL be the directory
approaches/<approach>/<criterion>/ containing fact.md (the aspect: facts,
not judgment) and exactly one judgment marker file named neutral, green,
yellow, or red. A cell is incomplete if and only if fact.md is
missing or empty. neutral is a legitimate judgment, distinct from
incomplete.
Scenario: Neutral judgment is explicit
- GIVEN a cell with a non-empty
fact.mdand a marker file namedneutral - WHEN
wai matrix lintruns - THEN the cell passes validation
Scenario: Multiple markers are a structural error
- GIVEN a cell containing both
greenandredmarker files - WHEN
wai matrix lintruns - THEN lint exits non-zero and names the offending cell
Scenario: Missing fact means incomplete, not judged
- GIVEN a cell directory with a marker but no
fact.md - WHEN
wai matrix lintruns - THEN the cell is reported as incomplete
Requirement: Status quo first
wai matrix init SHALL create approaches/01-status-quo/ first, and lint
SHALL report an error if it is missing.
Scenario: Init creates status quo
- GIVEN a project without a matrix
- WHEN
wai matrix initruns - THEN
approaches/01-status-quo/_description.mdexists
Requirement: Multi-operation helpers
wai matrix criterion add <name> SHALL create the criterion definition file
and cell directories in every existing approach.
wai matrix approach add <name> SHALL create the approach directory with
_description.md and empty cell directories for every existing criterion.
These exist because one logical action spans multiple directories; no command
is provided for single-cell writes, which are direct file edits.
Scenario: Criterion add touches every approach
- GIVEN a matrix with two approaches
- WHEN
wai matrix criterion add "operational-cost"runs - THEN
criteria/NN-operational-cost.mdexists - AND
approaches/*/03-operational-cost/exists for every approach
Requirement: Deciding produces a current-answer marker and a design doc
wai matrix decide <approach> <rationale> SHALL validate the approach
directory exists, write decision.md (selected approach, rationale, date,
pointer to the design doc), and scaffold a design artifact in
designs/<date>-<slug>.md with standard frontmatter (tracks supported) and
a decision-time snapshot of the winning column’s cell texts.
Scenario: Decide writes both artifacts
- GIVEN a matrix with two approaches and filled cells
- WHEN
wai matrix decide "02-event-sourcing" "rationale text"runs - THEN
decision.mdnames approach02-event-sourcing - AND a new design artifact exists in
designs/containing the rationale and the winning column’s aspect texts
Scenario: Decide rejects unknown approach
- GIVEN no approach directory matches the argument
- WHEN
wai matrix decideruns - THEN the command fails, listing valid approach names
Requirement: Deterministic HTML render on demand
wai matrix render SHALL generate a self-contained matrix.html (inline
CSS, no JS) as a pure function of the directory state: problem.md banner,
criteria as rows, approaches as columns, marker files as judgment chips,
assessment key included. Output is deterministic (byte-identical for equal
input) and is a generated view — it SHALL NOT be committed or treated as a
source of truth. Empty cells render as a gray “not yet assessed” placeholder,
never a judgment color.
Scenario: Same state, same output
- GIVEN an unchanged matrix directory
- WHEN
wai matrix renderruns twice - THEN both runs produce byte-identical HTML
Scenario: Unfilled cell is not a judgment
- GIVEN an approach/criterion pair with no
fact.md - WHEN
wai matrix renderruns - THEN that cell renders with a neutral “not yet assessed” placeholder that is not colored green, yellow, or red
Requirement: Structural lints
wai matrix lint SHALL enforce, as errors (non-zero exit):
- Rectangularity: every approach directory contains a cell directory for every criterion
- Exactly one non-empty-named marker from {neutral, green, yellow, red} per filled cell
- No empty
fact.mdfiles 01-status-quopresent as first column
Scenario: Missing cell in one approach fails lint
- GIVEN an approach directory lacking a cell directory present in the other approaches
- WHEN
wai matrix lintruns - THEN exit code is non-zero and the missing path is named
Requirement: Methodology lints are warnings
wai matrix lint SHALL report, as warnings that never affect exit code:
- All-green column (possible rationalization)
- Undistinguished columns (identical cell texts across approaches for all criteria — likely a missing criterion)
- Subjective judgment words as the body of
fact.md - Link-only cells (bare URL, no summary text)
- Criteria definitions phrased as questions (trailing
?) - Status-quo column with no red cell (something important was missed — per Miller, “Design in Practice in Practice”)
- Decision recorded while the selected approach has unfilled cells
- Empty
problem.md - Matrix files newer than the decision timestamp in
decision.md(stale decision; inconclusive timestamp comparison after a fresh clone downgrades to this warning rather than a gate block)
Scenario: All-green column warns but passes
- GIVEN one approach whose filled cells all have
greenmarkers - WHEN
wai matrix lintruns - THEN a warning names the approach
- AND exit code is 0
Scenario: Undistinguished columns warn
- GIVEN two approaches whose cell texts are identical for every criterion
- WHEN
wai matrix lintruns - THEN a warning suggests a distinguishing criterion is missing
Requirement: Design-to-plan phase gate
The design → plan phase transition SHALL be blocked when a matrix exists
and any of the following hold: problem.md is empty, decision.md does not
record a selected approach that exists under approaches/, or any file under
approaches/ or criteria/ has an mtime strictly newer than the decision
UTC timestamp recorded inside decision.md. Staleness checks whose
comparison is inconclusive (equal or missing timestamps, e.g. after a fresh
clone) SHALL downgrade to a warning instead of blocking. The failure message
SHALL be self-healing: it names the offending files and points at
wai matrix decide. Projects without a matrix are never gated.
Scenario: Current decision passes the gate
- GIVEN a matrix whose
decision.mdnames an existing approach and no matrix file is newer than the recorded decision timestamp - WHEN
wai phase nextadvances from design - THEN the transition proceeds
Scenario: Scaffolded decision does not pass the gate
- GIVEN a freshly initialized matrix whose
decision.mdis still the template (no approach recorded) - WHEN the design → plan transition is attempted
- THEN the transition is blocked
- AND the message indicates no decision has been made
Scenario: Edited-after-decision blocks the gate
- GIVEN a cell file modified after
decision.mdwas written - WHEN the design → plan transition is attempted
- THEN the transition is blocked
- AND the message names the stale-decision condition and suggests
wai matrix decide
Scenario: Ambiguous timestamps after a fresh clone warn instead of blocking
- GIVEN a decided matrix checked out fresh from git so that all matrix files share the checkout timestamp
- WHEN the design → plan transition is attempted
- THEN the transition proceeds
- AND a stale-decision warning is reported with a pointer to
wai matrix lint
Scenario: No matrix means no gate
- GIVEN a project that never ran
wai matrix init - WHEN the design → plan transition is attempted
- THEN the transition proceeds as before this change
Requirement: Status and handoff matrix awareness
wai status in the design phase SHALL show the current problem statement,
cell completion count, and a suggestion for the next unfilled cell.
wai close handoffs SHALL include the problem statement, the selected
approach with rationale, and links to both the matrix directory and the
scaffolded design doc.
Scenario: Status shows completion
- GIVEN a matrix with 5 of 6 cells filled
- WHEN
wai statusruns during the design phase - THEN output includes the problem statement,
5/6 cells filled, and a pointer to the unfilled cell