# form@0.1

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

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

## 1. Purpose

`form@0.1` describes a portable questionnaire and its current response: level-2 headings are fields, plain Markdown explains them, and response fences hold typed answers.
The file stays readable, diffable, and authoritative in any Markdown viewer.

---

## 2. Grammar

### 2.1 Envelope

```yaml
---
markdownto: form@0.1
title: A quick introduction
---
```

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

### 2.2 Questions, choices, and responses

One optional leading `#` is the title. Each nonempty, case-insensitively unique `##` names a question. Content must follow a question. A first paragraph made entirely of inline fields declares direction; unknown fields stay inert and duplicate keys are invalid.

`type` is `text` (default), `long-text`, `email`, `number`, `date`, `boolean`, `select`, or `multiselect`. `required` is `true` or `false` (default). Number fields alone may declare finite `[min:: 1]` and `[max:: 100]`, with min <= max. Remaining Markdown is help text.

Select and multiselect fields have at least two plain bullet choices, each `- key: Label`. Keys are unique, case-sensitive ASCII letters/digits/underscore/hyphen beginning with a letter or digit. They are content alternatives, not tasks; checkbox markers and ordered lists are invalid here.

A question may contain one fenced code block whose language is `response`, containing one JSON value. Text/email/date/select answers are strings; number is a finite JSON number; boolean is true or false; multiselect is an array of distinct choice keys. JSON null means unanswered. Email must contain a non-space local part and dotted domain; this is syntax validation, not deliverability. Dates are real `YYYY-MM-DD` dates. Empty text and empty multiselect are unanswered for completion. False and zero are valid answers.

A blank required question does not make the questionnaire malformed. `check` reports completion separately and exits 1 for missing required answers. A malformed or out-of-range saved answer does make it invalid. Files contain one current response; copy a blank questionnaire for each respondent. Collection, identity, network submission, and response history belong to an explicit host, not hidden browser state. The local UI saves via the same operations as the CLI and provides the complete updated Markdown.

### 2.3 Canonical IR

The IR sits at `result.form`, 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 |
| --- | --- | --- |
| `MDTO1500` | error | No sections. |
| `MDTO1501` | error | Invalid heading or content before a section. |
| `MDTO1502` | error | Invalid settings or direction. |
| `MDTO1503` | error | Invalid required content structure. |
| `MDTO1504` | error | Invalid saved answer or score. |
| `MDTO1505` | 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: form@0.1
title: A quick introduction
---

## Your name

[required:: true]

What should we call you?
````

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

`form@0.1` owns the vocabulary **answer, clear, check**.

| Verb | Signature | Source edit |
| --- | --- | --- |
| `answer` | `mdto form answer <question> <json-value>` | Insert or replace that question’s response fence. |
| `clear` | `mdto form clear <question>` | Remove that question’s response fence. |
| `check` | `mdto form check ` | Report missing required answers; 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.
