---
title: "Frontmatter Conventions"
category: conventions
tags: [frontmatter, docs, tasks, yaml, governance]
updated: 2026-05-05
owner: rjj
status: stable
related:
  - governance.md
  - architecture/cluster-layout.md
---

# Frontmatter Conventions

Every `.md` under `.meshkore/docs/` and `.meshkore/roadmap/{tasks,log}/`
carries a YAML frontmatter block. The build script parses it; the portal
uses it to filter, sort, and group.

## Format

```yaml
---
key: value
key: "value with: colons"
list_key: [item1, item2]
nested_list:
  - item1
  - item2
---

# Body of the document...
```

The block must be at the **very start of the file** (no blank lines
before it), bounded by `---` lines, written as YAML.

## Docs frontmatter

```yaml
---
title: "API Architecture"
category: architecture            # = first-level subfolder under docs/
tags: [api, rest, protocols]
updated: 2026-05-05               # YYYY-MM-DD
owner: rjj                        # cluster identity
status: stable                    # draft | stable | deprecated
related:                          # paths relative to docs/
  - architecture/protocols/compatibility.md
  - conventions/url-namespace.md
---
```

| Field | Required | Notes |
|---|---|---|
| `title` | yes | Quoted string. Used as page header in the portal |
| `category` | yes | Must match the folder name in `docs/` |
| `tags` | no | Inline list. Used for filtering and search |
| `updated` | yes | YYYY-MM-DD; auto-populated from `git log` if absent |
| `owner` | yes | Identity string (`rjj`, `claude-cli-mac`, …) |
| `status` | yes | `draft`, `stable` (default), or `deprecated` |
| `related` | no | Cross-references shown in the doc footer |

## Tasks frontmatter

```yaml
---
id: T042
title: "Migrate webapp to Cloudflare Pages"
status: in_progress              # backlog | next | in_progress | done | blocked | cancelled
priority: high                   # low | medium | high | critical
owner: rjj
category: webapp
milestone: "v1.0 launch"
created: 2026-04-15
updated: 2026-05-04
depends_on: [T038]
tags: [webapp, infra]
effort: "2d"
---
```

| Field | Required | Notes |
|---|---|---|
| `id` | yes | Unique within the cluster (`T042`, `D17`, `N5`, …) |
| `title` | yes | Short imperative — what gets done |
| `status` | yes | One of the 6 values above |
| `priority` | no | Default `medium` |
| `owner` | yes | Who's responsible |
| `category` | **yes** | **MUST equal a module `id` declared in `cluster.yaml`.** Also matches the folder under `tasks/<category>/`. If nothing fits, use `general` — never `uncategorized`. See [`architecture/cluster-layout.md`](../architecture/cluster-layout.md#modules). |
| `milestone` | no | Group multiple tasks under a release |
| `created` / `updated` | yes | YYYY-MM-DD |
| `depends_on` | no | List of task IDs |
| `tags` | no | Free tags; merged with category in search |
| `effort` | no | Free text (`2d`, `1w`, `~30min`) |

## Status lifecycle

```
backlog ─────► next ─────► in_progress ─────► done
   │              │              │
   │              │              ▼
   │              │           blocked  ────► (resolved → next)
   │              │
   ▼              ▼
cancelled    cancelled
```

When status moves to `done`, the daemon (or the user manually) **moves
the file** from `roadmap/tasks/<category>/` to `roadmap/log/<YYYY-MM>/`.
This keeps `tasks/` clean and `log/` historical.

## Auto-populating frontmatter

Two scripts help bootstrap and maintain frontmatter:

- `roadmap-build.py` — only reads frontmatter, doesn't modify. Reports
  warnings for files missing required fields.
- `enrich-frontmatter.py` — one-shot enricher for files missing the
  block. Extracts title from first `H1`, infers category from path,
  reads `updated` from `git log`, sets defaults for the rest.

Both live in `.meshkore/scripts/` (downloaded from
`meshkore.com/reference/scripts/`).

## Validation

`roadmap-build.py --validate` walks all docs/tasks and exits non-zero if
required fields are missing or values are invalid (unknown status, bad
date format, dangling `related:` paths). Useful as a pre-commit hook.

## See also

- [`governance.md`](../governance.md) — the R1-R6 rules
- [`architecture/cluster-layout.md`](../architecture/cluster-layout.md)
