Skip to content

Frontmatter contracts

Doc type: Reference  ·  Applies to: POSE 7.x (current stable)

POSE frontmatter is flat by contract — inline comma-separated lists, never multi-line YAML lists. This keeps every artifact parseable by simple deterministic tooling (and by agents) without a YAML edge-case zoo.

Spec (.pose/specs/YYYY-MM-DD-<slug>.md)

pose new-spec writes the dated flat file by default; --folder writes .pose/specs/YYYY-MM-DD-<slug>/spec.md, and specs in the older .pose/specs/<slug>/spec.md layout stay readable.

---
slug: my-feature
status: draft        # draft | in-progress | done | superseded | abandoned; blocked = operational wait, not terminal
surface: minimal     # optional: minimal | standard | full (default)
created_at: 2026-01-15
completed_at:        # stamped on the transition to done
supersedes:          # slug of the superseded spec
depends_on: other-spec, milestone:my-roadmap/m1, roadmap:other-roadmap
priority: 1          # integer >= 0; lower = attack first; never blocks
components:          # optional, inline comma-separated: affected modules/components
task_type: feature   # optional; a key of taskTypes in .pose/policy/dor.json (default: defaultTaskType)
delivers:            # optional typed refs: surface:id, contract:id, capability:id, infrastructure:id, governance:id
---

Rules enforced by pose check / pose lint-spec:

  • depends_on refs must exist; the graph must be acyclic.
  • status: done requires completed_at + a disposition on every follow-up. An open follow-up ends with its ownership group, (owner:@alias crit:low|medium|high review:YYYY-MM-DD) — the only format read.
  • completed_at may not precede created_at. POSE stamps both in UTC, and a date you fill in by hand is usually your local one, so between two bare dates one day of difference is accepted as that skew; two days, or any regression between full timestamps, is an error.
  • Entering in-progress requires the Definition of Ready (--ready-check) once the project sets adopted_at in .pose/policy/dor.json; task_type selects which sections it requires.
  • A review bundle is sealed only for a spec with an attributed change set — commits carrying its POSE-Spec: trailer, or a range recorded with pose report --change-from/--change-to; pose doctor names specs that delivers: a target without one.
  • Acceptance criteria use stable IDs (- R<N>:); published IDs are never renumbered — a withdrawn criterion is marked as withdrawn.
  • components is free-form (no enforced vocabulary) — tag a spec with the module/component names it touches (e.g. mcp-server, cli) to make it findable with pose_list_specs' components filter (comma-separated, case-insensitive, matches if any tag is shared) without fragmenting specs into a separate .pose/ per component. A cross-cutting spec lists every component it touches; a spec with no tag never matches a non-empty filter.

Design basis belongs in the spec body

Recent contracts also read structured requirements, assumptions and decisions (R/A/D) from the Markdown body. They are not additional frontmatter keys. Under adopted contract nodes, their content, state and relations participate in amendment history; under adopted atomic start, their baseline is recorded before managed execution.

  • A material assumption can declare Valid scope: and pinned Stale trigger: references. A changed pin creates an advisory premise-stale obligation.
  • A decision can declare Expected effect: and Falsifier check: check:<module>/<check>. An observed failure creates an advisory reconsideration candidate; it does not establish causation.
  • A decision can be active or withdrawn. Under causal closeout, a withdrawn decision or invalidated assumption cannot justify an active structural mapping.

Use the installed spec template and pose amend <slug> --nodes --json to inspect parsed nodes. Use review and trust for mappings and instance operation for effective adoption.

Roadmap (.pose/roadmaps/<slug>.md)

---
slug: my-roadmap
status: draft        # draft | active | done | abandoned
created_at: 2026-01-15
depends_on:          # other roadmaps, inline list
---

Milestones are sections, not frontmatter:

## Milestone: m1
- after:              # milestone ids and/or spec:<slug>, inline list
- target_start: 2026-02-01
- target_due: 2026-02-15
- specs: spec-a, spec-b

Enforced: unique spec membership across active roadmaps, milestone/roadmap DAGs, date sanity, resolvable refs.

Knowledge (.pose/knowledge/*.md)

---
type: handoff        # handoff | decision-log | note
owner: "@team-or-person"
sensitivity: normal  # normal | restricted
created_at: 2026-01-15
last_reviewed_at: 2026-01-15
expires_at: 2026-02-14   # TTL <= 90 days, default 30
---

Changelog fragment (.pose/changelogs/unreleased/<spec>.md)

---
spec: my-feature
category: added      # added | changed | fixed | removed | deprecated | security
breaking: false
refs: PR#123
---

The body is 1–3 user-facing sentences. Preview the pending cut with pose release plan --version vX.Y.Z; pose release prepare --version vX.Y.Z --apply freezes the selected fragments, notes and manifest. Then pose release notes --version vX.Y.Z reads the immutable snapshot; it does not reconsolidate the current pending directory. pose release-notes --version vX.Y.Z is a supported compatibility alias. See command compatibility.

Schema version (.pose/schema-version)

A single integer line. The engine's POSE_SCHEMA_VERSION must be ≥ the instance's; pose update migrates forward, never backward.