# quiz@0.1

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

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/quiz.skill.md) (non-normative).

## 1. Purpose

`quiz@0.1` describes a self-study assessment and one current attempt: level-2 headings are questions, keyed choices carry alternatives, and explicit answer keys determine reproducible grading.
The file stays readable, diffable, and authoritative in any Markdown viewer.

---

## 2. Grammar

### 2.1 Envelope

```yaml
---
markdownto: quiz@0.1
title: Check your understanding
---
```

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

### 2.2 Questions and one portable attempt

One optional leading `#` is the title. Each nonempty, case-insensitively unique `##` is a question. A first all-field paragraph holds direction, with duplicate keys invalid and unknown keys inert. `type` is `select` (default) or `multiselect`. Choices are at least two plain bullets `- key: Label`; keys are unique and case-sensitive ASCII letters/digits/underscore/hyphen beginning with a letter or digit. They are not task items.

`[correct:: key]` is mandatory; multiselect lists correct keys separated by commas. Correct keys must be distinct and name existing choices. Select has exactly one correct key. `[points:: 2]` defaults to 1 and is finite, positive, and at most 100. `required` is true by default and may be false. A `### Explanation` heading begins feedback for the remainder of that question.

One optional `response` fence stores a JSON string key (select), array of distinct keys (multiselect), or null (unanswered). Invalid JSON, wrong types, unknown keys, or duplicate response blocks are errors. Missing responses are permitted in the source.

Grading compares sets exactly; no partial credit or order dependence. Unanswered questions receive zero; total score includes every question’s points. Percentage is earned / possible * 100; `pass` is a frontmatter number 0–100, default 70. The report separates completion from passing so an incomplete attempt never masquerades as complete. The UI reveals authored explanations on grading, and any subsequent answer change invalidates the displayed result.

The file carries one current attempt; clear or copy it to begin another. This is self-study, not a secure examination: answer keys are readable in the source and exported HTML. No AI grades, guesses, or rewrites answers. `grade` returns exit 0 for a valid report even when the score is below the pass threshold.

### 2.3 Canonical IR

The IR sits at `result.quiz`, 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 |
| --- | --- | --- |
| `MDTO1800` | error | No sections. |
| `MDTO1801` | error | Invalid heading or content before a section. |
| `MDTO1802` | error | Invalid settings or direction. |
| `MDTO1803` | error | Invalid required content structure. |
| `MDTO1804` | error | Invalid saved answer or score. |
| `MDTO1805` | error | Duplicate section or option identity. |

## 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: quiz@0.1
title: Check your understanding
---

## Which value is even?

[correct:: two]

- one: 1
- two: 2
````

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

`quiz@0.1` owns the vocabulary **answer, clear, grade**.

| Verb | Signature | Source edit |
| --- | --- | --- |
| `answer` | `mdto quiz answer <question> <json-value>` | Insert or replace that question’s response fence. |
| `clear` | `mdto quiz clear <question>` | Remove that question’s response fence. |
| `grade` | `mdto quiz grade ` | Report deterministic grading; 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.
