# matrix@0.1

**Status:** normative. **Inherits:** [`../conventions.md`](../conventions.md). **Schema:** [`schema.json`](schema.json). **Fixtures:** [`fixtures/`](fixtures/). **Owns diagnostic codes:** `MDTO1700`–`MDTO1799`.

This is a content model, not the shared task item model. It does not reinterpret task checkbox state.

**Companion skill:** [Authoring and editorial guidance](https://markdownto.ai/specs/matrix.skill.md) (non-normative).

## 1. Purpose

`matrix@0.1` describes an explicit weighted decision: level-2 headings are criteria, tables hold comparable scores, and authored weights determine a transparent ranking.
The file stays readable, diffable, and authoritative in any Markdown viewer.

---

## 2. Grammar

### 2.1 Envelope

```yaml
---
markdownto: matrix@0.1
title: Choose a route
---
```

Shared envelope and preservation rules apply. Unknown keys are preserved and inert. Settings are validated without network access.

### 2.2 Criteria and explicit scoring

One optional leading `#` is the title. Each nonempty, case-insensitively unique `##` names a criterion. A first all-field paragraph may declare `[weight:: 3]`; weight defaults to 1, is finite, and lies between 0 and 100. At least one weight is positive. Unknown direction fields remain inert; duplicate fields are invalid.

Each criterion has exactly one GFM table with exactly two headers `Option | Score` (header comparison is case insensitive). It has at least two options. Names are plain text, nonempty, unique case-insensitively within a criterion, and match exactly across all criteria; row order may differ. Every score is a finite number from 0 to 10, with higher always better. Missing values are errors, never implicit zeroes. Explanatory Markdown describes the scale and assumptions.

The weighted score is `sum(weight * score) / sum(weight)`, on the same 0–10 scale. Ranking descends by the full-precision weighted score. Exact ties preserve first-criterion option order and are displayed as ties, not spurious wins. Display rounding must not change ranking. Zero-weight criteria remain visible and contribute nothing. No tool invents scores or turns raw costs into benefits implicitly.

`weight` changes only the named criterion’s direction. The rendered UI exposes identical weight edits, recalculates immediately, and offers updated Markdown plus undo/redo. A sensitivity view is a derived explanation, not extra stored state. Authored scores are judgments; rank is an aid to a decision, not an objective recommendation.

### 2.3 Canonical IR

The IR sits at `result.matrix`, beside `result.document`. It carries the envelope, ordered source-positioned content, parsed direction, effective settings, and domain data defined in `schema.json`. Source offsets address edits, never an independently parsed renderer copy. Parse and serialize reproduce the source byte for byte.

### 2.4 Diagnostics

| Code | Severity | Meaning |
| --- | --- | --- |
| `MDTO1700` | error | No sections. |
| `MDTO1701` | error | Invalid heading or content before a section. |
| `MDTO1702` | error | Invalid settings or direction. |
| `MDTO1703` | error | Invalid required content structure. |
| `MDTO1704` | error | Invalid saved answer or score. |
| `MDTO1705` | error | Duplicate section or option identity. |
| `MDTO1706` | error | Criterion option sets disagree. |
| `MDTO1707` | error | Every criterion has zero weight. |

## 3. Rationale

**One heading axis.** `##` has one domain meaning, so authoring, validation, rendering and operations agree. Familiar Markdown remains useful without this runtime.

**Explicit state.** Meaningful user input belongs in the file; selected views and transient controls do not. Renderers never invent missing facts. Shared safe rendering treats executable-looking content as data.

**Small portable surface.** This format chooses bounded semantics over arbitrary executable extensions. Its companion skill teaches editorial judgment without making taste a validation rule.

## 4. Examples

````markdown
---
markdownto: matrix@0.1
title: Choose a route
---

## Ease

[weight:: 1]

| Option | Score |
| --- | --- |
| Train | 8 |
| Car | 5 |
````

See the valid fixtures for a complete, realistic example and edge cases. Invalid fixtures define the exact errors, not examples to imitate.

## 5. Verb reference

`matrix@0.1` owns the vocabulary **weight, rank**.

| Verb | Signature | Source edit |
| --- | --- | --- |
| `weight` | `mdto matrix weight <criterion> <number>` | Set that criterion’s weight field. |
| `rank` | `mdto matrix rank ` | Report normalized scores and authored-order ties; no source edit. |

### Common flags and editing guarantees

`--file <path>` selects the source; `--json` uses the `mdtoJson: 1` envelope; `--help` describes the verb. Mutation verbs also accept `--expect <hash>` and `--dry-run`; they validate the complete batch and refuse stale or invalid results without writing. Question/criterion references are one-based numbers or exact case-insensitive titles. Updated fences use JSON escaping and preserve all untouched bytes. Repeating an already-satisfied mutation is a no-op. Builds accept `--out`; outputs never replace the source. Cross-spec conversion is refused when meaning would have to be invented; use explicit authoring instead.
