Document the schema, value types, and render semantics so a Macroplan .toml can be produced and consumed outside this app's renderer. Ships a JSON Schema (served from public/ for editor use) and a reference file.
9.7 KiB
Macroplan TOML Format — v1
The portable, tool-independent definition of a Macroplan: a week-by-week delivery plan that records what a team promised, every time an estimate slipped, and when work actually shipped — judged against the first estimate, never a moved goalpost.
This document is the contract. Any tool can produce or consume a .toml file
that conforms to it and render the same plan. The macroplan app
is one such consumer; nothing here is specific to it.
- Machine-readable schema:
macroplan.schema.json, served athttps://macroplan.apoena.dev/macroplan.schema.json(JSON Schema 2020-12; validates the TOML-decoded structure). - Reference file:
macroplan.example.toml(exercises every field and state; a conformance sample). - Serialization: TOML v1.0.0. Values use TOML's native types — dates are bare date literals, not quoted strings (see Dates).
Versioning
A file MAY declare the format version at the top level:
macroplan_version = 1
- Optional. An absent marker means the current version (
1). Every existing file therefore stays valid. - Integer, monotonically increasing. This document defines version 1.
- A consumer that understands version N MUST reject a file declaring a version greater than N (rather than silently mis-rendering it), and SHOULD accept any version ≤ N it still supports.
- The version is bumped only for a breaking change to the schema or render semantics below — a new optional field does not require a bump.
Producers SHOULD emit macroplan_version so a file self-describes its target.
Top-level fields
| Key | Required | Type | Default | Meaning |
|---|---|---|---|---|
macroplan_version |
no | integer (1) |
1 |
Format version (see above). |
title |
no | string | "Untitled Macroplan" |
Display name of the plan. |
start |
no | date | auto-fit | Left edge of the plan's week span. Only extends the span; never clips a feature. |
end |
no | date | auto-fit | Right edge of the plan's week span. Only extends the span; never clips a feature. |
Zero or more [[feature]] blocks and zero or more [[milestone]] blocks follow.
[[feature]]
A unit of work, read left-to-right as a story: where it started, what was first promised, every slip, and when it shipped.
| Key | Required | Type | Default | Meaning |
|---|---|---|---|---|
name |
yes | non-empty string | — | Identifies the feature; the join key for a milestone's requires. |
start |
yes | date | — | The week work began. |
original |
yes | date | — | The Original Estimate — the immovable baseline all lateness is judged against (ADR-0001). |
reestimates |
no | array of dates | [] |
Each later week the estimate slipped to (a slip, △). Order-independent. |
delivered |
no | date | — | The week the feature actually shipped. Absent → still in flight. |
learning |
no | string | — | A post-delivery takeaway. |
status |
no | "on-track" | "at-risk" | "off-track" |
— | In-flight confidence. Meaningful only while undelivered. |
note |
no | string | — | A short note accompanying status. |
Constraint — unique names: feature name values MUST be unique within a
plan. Because milestone requires resolves by name, a duplicate would make a
requirement ambiguous. Conforming consumers reject duplicates.
[[milestone]]
A dated checkpoint that depends on a set of features being delivered by then.
| Key | Required | Type | Default | Meaning |
|---|---|---|---|---|
name |
yes | non-empty string | — | Display name of the milestone. |
week |
yes | date | — | When the milestone falls due. |
requires |
no | array of strings | [] |
Feature names that must be delivered on/before week to meet it. |
A requires entry that names no existing feature counts as unmet (it can
never be satisfied) — useful for catching typos.
Value types
Dates → weeks
Every date field is a calendar date, written as a TOML bare date literal:
original = 2026-06-15
reestimates = [2026-06-29, 2026-07-13]
- Canonical form is the bare date literal. A quoted
"2026-06-15"string is tolerated on input for convenience, but producers SHOULD emit bare literals so the same plan always serializes identically. - Any day snaps to its ISO-week Monday. A Macroplan's unit is the week, keyed
by the Monday (yyyy-mm-dd) of the ISO week containing the date.
2026-06-17(a Wednesday) and2026-06-15(that Monday) denote the same week. Every conforming renderer MUST apply this snapping, or dates land in the wrong column.
Status
The enum on-track | at-risk | off-track. No other value is valid. Lateness
is derived, never authored — there is deliberately no "late" status.
Render semantics (the contract a renderer must honor)
Two tools should draw the same plan from the same file. These rules are as much a part of the format as the fields:
- On-time vs. late is judged only against
original— never a re-estimate (ADR-0001).delivered ≤ original(by week) is on time;delivered > originalis late. - Marker vocabulary per feature:
◯original — the Original Estimate week, while undelivered.△re-estimate — one perreestimatesentry.◉delivered on time — a delivery on/beforeoriginal. It subsumes the◯(no separate original marker is drawn).▲delivered late — a delivery afteroriginal; the◯baseline is kept alongside it.
- Bar extent. A feature's bar runs from
startto its furthest marker. A delivered bar ends at its delivery. An overdue feature (undelivered, and already past its furthest estimate relative to "now") keeps running to the current week. - Plan span. The rendered week range runs from the earliest to the latest
week among all features' markers and all milestones. Optional
start/endonly widen this range with lead-in / trailing weeks; a marker outside them is never clipped. - Milestone met/unmet. A required feature is unmet at a milestone if it
is undelivered, delivered after the milestone
week, or names no existing feature. - "Now". The current week (Monday of today) drives overdue extension and the "now" line. It is contextual, not stored in the file.
Notes for implementers
- Unknown keys. The JSON Schema is strict (
additionalProperties: false) so editors flag typos liketitel. The reference parser is more lenient — it ignores unrecognized top-level keys. Producers SHOULD NOT emit unknown keys. - Empty plan. A file with no features and no milestones is valid; with an
authored
start/endit renders as an empty grid across that span. - Editor integration. Point Taplo-based editors
at the schema with a directive on the first line of a plan file:
#:schema https://macroplan.apoena.dev/macroplan.schema.json.
See also
- CONTEXT.md — the ubiquitous language (Feature, Original Estimate, Re-estimate, Delivery, Milestone, Week, Status, Learning).
- ADR-0001 — why lateness is judged against the Original Estimate.
- ADR-0002 — why the
.tomlfile is the portable source of truth.