Files
macroplan/docs/format.md
Julien Calixte d0a34ef28a docs(format): define the portable Macroplan TOML format v1
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.
2026-07-02 22:04:06 +02:00

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 at https://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) and 2026-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:

  1. On-time vs. late is judged only against original — never a re-estimate (ADR-0001). delivered ≤ original (by week) is on time; delivered > original is late.
  2. Marker vocabulary per feature:
    • original — the Original Estimate week, while undelivered.
    • re-estimate — one per reestimates entry.
    • delivered on time — a delivery on/before original. It subsumes the (no separate original marker is drawn).
    • delivered late — a delivery after original; the baseline is kept alongside it.
  3. Bar extent. A feature's bar runs from start to 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.
  4. Plan span. The rendered week range runs from the earliest to the latest week among all features' markers and all milestones. Optional start/end only widen this range with lead-in / trailing weeks; a marker outside them is never clipped.
  5. 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.
  6. "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 like titel. 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/end it 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 .toml file is the portable source of truth.