> For the complete documentation index, see [llms.txt](https://ascribed-dev.com/docs/llms.txt). This documentation describes Ascribe 0.4.4. Anything marked in main, not yet released isn't in that release yet.

# `ascribe.toml` format contract: how content varies

> Reference · The normative contract for the content model's dimensions, versions and releases, lifecycle states, and features.

Part of the [`ascribe.toml` format contract](https://ascribed-dev.com/docs/contracts/content-model.md), whose [contents](https://ascribed-dev.com/docs/contracts/content-model.md#contents) list every section. What these keys are for, with examples, is in the reference's [how content varies](https://ascribed-dev.com/docs/content-model/variation.md).

## 11\. `[dimensions.<name>]`

A **[dimension](https://ascribed-dev.com/docs/glossary.md#dimension)** is an axis content varies along ([SPEC §4.3](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#43-variant)), and whose values are [availability](https://ascribed-dev.com/docs/glossary.md#availability) targets ([SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available)).

```toml
[dimensions.deployment]
label = "Deployment"
values = ["cloud", "self-managed"]
versionless = ["cloud"]
labels = { cloud = "Quill Cloud", self-managed = "Self-managed" }
```

Tested with ascribe 0.4.4 on Linux.

`<name>` is the dimension's name (`key` rule, §1.2). It's written as an attribute key in `@variant`, as a key in `variant` frontmatter and build selections, and as a target in availability specs, where it stands for all its values.

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `values` | array of strings | **required** | The dimension's values (`name-word`), in display order. At least one; no duplicates. |
| `labels` | table of strings | `{}` | Display labels for values, keyed by value ([SPEC §9.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#94-outputs): "Labels for dimension values come from the [content model](https://ascribed-dev.com/docs/glossary.md#content-model)'s display labels"). A value without a label is displayed as the value itself. Every key MUST be a declared value. |
| `label` | string | the dimension's name | The display label for the dimension itself, used where a dimension name appears as an availability target or names a tab group. |
| `versionless` | array of strings | `[]` | Values that are versionless ([SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available)): availability for them takes a single state and no versions. Every entry MUST be a declared value. Values not listed are versioned. |

**Rules** (§25.4): a value MUST NOT belong to two dimensions (`model-dimension-value-shared`), and dimension names and values are subject to the one-role rule (`model-name-multiple-roles`).

---

## 12\. `[versions]`

How versions in availability specs are compared ([SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available)). Which release is current is a target's own, in `[releases.<target>]` (§12.1).

```toml
[versions]
scheme = "numeric"
```

Tested with ascribe 0.4.4 on Linux.

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `scheme` | string | `"numeric"` | The version scheme. Spec 0.1 defines one: `"numeric"`. |

**The `numeric` scheme.** A version is any string matching SPEC Appendix A's `version` rule: numbers separated by dots (`3`, `3.4`, `3.4.1`). Versions compare component by component, numerically, from the left, with missing trailing components treated as `0`: `3.4` equals `3.4.0`, `3.10` is later than `3.9`, and `4` is later than `3.99.1`. Leading zeros don't matter (`3.04` equals `3.4`). This is semantic versioning's `major.minor.patch` ordering. It has no pre-release or build suffixes, because the spec's grammar doesn't allow them; express a pre-release with a lifecycle state (`preview 3.4`) instead.

**Rules** (§25.5): `scheme` MUST be `"numeric"` (`model-invalid-value`). `current` MUST NOT be set (`model-versions-current`): a target's current release is its newest live line in `[releases.<target>]`.

### 12\.1 `[releases.<target>]`

The [release lines](https://ascribed-dev.com/docs/glossary.md#release-line) of a versioned target, by the target's name. A **line** is a version as the list writes it, and holds every version that starts with its parts: `3.4` holds `3.4`, `3.4.2`, and `3.4.2.1`. A project chooses how fine its lines are by how it writes them: `["3.4", "3.5"]` for a line for each minor release, `["0.2.0"]` for one for each patch release. The newest live line is the target's **current line**; it isn't written down, so it can't disagree with the list.

```toml
[releases]
planned-label = "planned"

[releases.self-managed]
live = ["3.4", "3.5"]
planned = ["3.6"]

[releases.self-managed.ends]
"3.4" = 2027-01-31

[releases.self-managed.archived]
"3.3" = { url = "https://docs.example.com/archive/3.3/", ended = 2026-06-30 }
"3.2" = {}
```

Tested with ascribe 0.4.4 on Linux.

The target is a versioned value of a declared dimension, such as `self-managed`, or a name no dimension has. `[releases.<target>]` declares a name no dimension has as a value of the **implicit dimension** `release`, which exists only while it has a value. `[releases] label` is the dimension's label, `Release` unless set, and `[releases.<target>] label` is the target's, its name unless set:

```toml
[releases.ascribe]
label = "Ascribe"
live = ["0.4.1"]
```

Everything that names a dimension names `release` as it names a declared one: `@variant {release=ascribe}`, a switcher's `sync`, a build's `variants`, `dimension:` targets in `ascribe refs`, and the elements' `dimension` attribute. It comes after the declared dimensions in their order.

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `live` | array of strings (versions) | `[]` | The lines a reader can be on, in any order. A build [versioned](https://ascribed-dev.com/docs/content-model/output.md#16-buildsname) by the target gives one output for each. |
| `planned` | array of strings (versions) | `[]` | Lines that haven't shipped, each newer than every live line. A version in one is **planned**: its availability reads `Self-managed (planned, 3.6)` in every output, and stops being planned when its line moves to `live`, with no other edit. |
| `ends` | table of dates | none | The last day each live line is supported, by line: `"3.4" = 2027-01-31`, a TOML date, unquoted. |
| `archived` | table of tables | none | Lines that have left the window, each older than every live line, by line. Each takes `url`, where the line can still be read, and `ended`, the day its support ended, both optional: `"3.2" = {}` declares a line that's readable nowhere. |
| `label` | string | the target's name | The target's display label, as `[dimensions.<name>] labels` gives a value's, when the target is a value of the implicit `release` dimension: `label = "Ascribe"`. A target a declared dimension has takes its label from that dimension's `labels` instead. |

`[releases]` takes two keys of its own, beside the targets' tables:

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | string | `"Release"` | The display label of the implicit `release` dimension, as `[dimensions.<name>] label` gives a declared dimension's. The implicit dimension holds each target no declared dimension has, so `[releases.ascribe]` alone makes `ascribe` a value of `release`. |
| `planned-label` | string | `"planned"` | The word a reader sees for a planned version, in place of its state: `Self-managed (planned, 3.6)`. |

**Rules.** `<target>` MUST be a declared dimension value that isn't versionless, or a name (`name-word`) that's no declared dimension's value or name, which declares it a value of the implicit dimension `release`. A loader MUST add the implicit dimension, after the declared ones, when at least one target is left to it, and only then. While one is, a declared dimension MUST NOT be named `release`, and each such target is the error (`model-releases-target`). `[releases.<target>] label` MUST NOT be set for a target a declared dimension has (`model-releases-target`). The implicit dimension's name and values are subject to the one-role rule (`model-name-multiple-roles`). Each line MUST be a version (SPEC Appendix A rule `version`), listed once, and every line of one target, in every list, MUST have the same number of parts (`model-releases-line`). A line MUST be in one list, every planned line MUST be newer than every live line, and every archived line older (`model-releases-order`). A key of `ends` MUST be a live line, as written (`model-releases-ends`), and its value a TOML local date (`model-wrong-type`). A key of `archived` is a line as written, and its table MAY have `url`, a non-empty string, and `ended`, a TOML local date, and no other key. `planned-label` MUST NOT be empty. The order of a list carries no meaning.

---

## 13\. `[lifecycle.<state>]`

Lifecycle states ([SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available)). Five are built in:

| State | Counts as available | Default label |
| --- | --- | --- |
| `preview` | yes | `preview` |
| `beta` | yes | `beta` |
| `ga` | yes | `GA` |
| `deprecated` | yes | `deprecated` |
| `removed` | no | `removed` |

A project adds states by declaring them, and can change the `available` flag or `label` of a built-in state. Built-in states can't be removed.

```toml
[lifecycle.sunset]
available = false
label = "sunset"

[lifecycle.beta]
label = "Beta"
```

Tested with ascribe 0.4.4 on Linux.

`<state>` is the state's name (`name-word`).

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `available` | boolean | built-in states: as in the table above; new states: **required** | Whether content in this state counts as available ([SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available), §9.3). A new state must say so explicitly. |
| `label` | string | built-in states: as in the table above; new states: the state's name | The display label used in availability annotations, such as "Available: Quill Cloud (GA); self-managed (preview, 3.4+)" ([SPEC §9.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#94-outputs)). |

**Rules** (§25.4): `ga` MUST count as available (`model-lifecycle-ga-unavailable`). A new state MUST set `available` (`model-lifecycle-available-required`). Lifecycle states, built-in ones included, are subject to the one-role rule (`model-name-multiple-roles`).

---

## 14\. `[features.<key>]`

The features registry ([SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available)): named availability specs, so a feature going generally available takes one edit.

```toml
[features.streaming-sync]
name = "Streaming sync"
available = "cloud, self-managed preview 3.4"
```

Tested with ascribe 0.4.4 on Linux.

`<key>` is the feature key (`name-word`). Writing it as a whole `@available` primary, or as the whole `available` frontmatter value, stands for the spec.

| Key | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | string | **required** | The feature's display name, shown on hover and available to emitters. |
| `available` | string (availability spec) | **required** | The feature's availability, in [SPEC §4.4](https://github.com/ascribed-dev/ascribe/blob/main/SPEC.md#44-available)'s syntax. |

**Rules** (§25.4): a feature's spec MUST parse as an availability spec (`model-availability-syntax`); each of its targets MUST be a declared dimension value or dimension name, and each state a declared state (`model-availability-unknown-name`); a versionless target or a dimension name MUST NOT have versions (`model-availability-versionless`); a history MUST be in chronological order (`model-availability-history-order`); and the spec MUST NOT be a feature key (`model-feature-nested`). Feature keys are subject to the one-role rule (`model-name-multiple-roles`).
