Tracking a roadmap with ctxgrd
Lint a Now-Next-Later product roadmap as one file per initiative, with the horizon, the owner, and cross-initiative blocking all enforced.
What ctxgrd checks – and what it does not
ctxgrd checks that every initiative carries the required headings and
metadata, that its status is one of the five allowed horizons, and that any
depends_on reference resolves and does not cycle. It does not check whether
an initiative belongs in now rather than later, whether the outcome is
realistic, or whether the idea is any good. Sequencing is a planning call, not
a structural one.
Prerequisites
ctxgrd0.56.0 or later.- A
ctxgrd.tomlin the repository root. If none exists, runctxgrd pack add project-docsto create a baseline.
1. Add the namespace
ctxgrd pack add project-docsThis writes [ROADMAP] into ctxgrd.toml alongside [ADR], [PRD],
[RFC], [BUG], [TODO], and [README], path-claimed at
docs/roadmap/**. To preview the block without touching your config:
ctxgrd pack add project-docs --dry-runRun the linter right after adding the pack and you get a diagnostic, not a clean run:
error[core.min-docs]: namespace `ROADMAP` requires at least one document but the run found noneThat is the pack telling you what to do next. ROADMAP is mandatory once
claimed – a repo that opts in but never writes an initiative is a worse
signal than a repo that never opted in at all. Write your first initiative
(step 2) and the diagnostic clears. If your project genuinely carries no
roadmap, drop the [ROADMAP] block instead of leaving it empty.
2. Write your first initiative
Each initiative is its own file under docs/roadmap/, id-claimed
ROADMAP-<n> – there is no single ROADMAP.md. It requires five
frontmatter fields (id, title, status, date, owner) and four H2
headings, in order: Problem, Outcome, Ideas, Success Metrics.
---
id: ROADMAP-1
title: Self-serve onboarding
status: now
date: 2026-07-09
owner: Growth
---
# Self-serve onboarding
## Problem
New teams need a human on the call to get their first config working.
## Outcome
A team goes from install to a clean first lint with no human involved.
## Ideas
- Guided `ctxgrd init` wizard.
- Starter pack recommendations by repo shape.
## Success Metrics
Time to first clean lint drops from a scheduled call to under 10 minutes.owner is required because an unowned roadmap item is the first one to rot.
date records when it was last triaged – a roadmap is a living document, not
a plan you write once.
3. Set the horizon with status
status carries the Now-Next-Later horizon directly – there is no separate
horizon field. The allowed set is now, next, later, plus two terminal
states, done and dropped, for closing an initiative out:
[ROADMAP."core.allowed-values"]
status = ["now", "next", "later", "done", "dropped"]An initiative with status: someday fails:
error[core.allowed-values]: metadata key 'status' has value 'someday' not in allowed set [now, next, later, done, dropped]The set is config, not hardcoded – retype it in ctxgrd.toml if your team
uses different horizon labels.
4. Chain initiatives with depends_on
An initiative that is blocked by another names it in depends_on. There is
deliberately no “Dependencies” heading – the blocking relationship rides the
same dependency graph your ADRs and PRDs already use.
---
id: ROADMAP-2
title: Multi-repo compliance dashboard
status: next
date: 2026-07-09
owner: Platform
depends_on: [ROADMAP-1]
---A depends_on entry that names an initiative that does not exist fails
core.dep-resolved:
error[core.dep-resolved]: depends_on entry 'ROADMAP-99' does not resolve to a document in the runTwo initiatives blocking each other fails core.dep-cycle the same way a
circular ADR dependency does. Neither check is specific to roadmaps – it is
the same machinery, reused.
5. View the board
ctxgrd list groups documents by namespace and prints each one’s status,
so filtering to ROADMAP gives you the Now-Next-Later board directly:
ctxgrd list --namespace ROADMAPnamespace id status title depends_on
ROADMAP ROADMAP-1 now Self-serve onboarding —
ROADMAP ROADMAP-2 next Multi-repo compliance dashboard ROADMAP-1ctxgrd list --format json gives the same data as an array, and --format markdown renders it as a pipe table you can paste into a status doc. ctxgrd status is a different report – it tracks the SPEC/PRD/ADR/TASK pipeline
position, not the roadmap board, so it will not show your initiatives.
6. Lint and iterate
ctxgrd # human-readable output
ctxgrd --format json | jq '.diagnostics[] | select(.code | startswith("core"))'Exit codes follow the standard contract: 0 clean, 1 diagnostics
reported, 2 kernel or config error.
A note on PRD
As of 0.56.0, [PRD] is mandatory when enabled the same way: a project that
claims the PRD namespace must carry at least one PRD, or core.min-docs
flags it. If a deployed repo’s ctxgrd.toml already had [PRD] before this
version, the new rule does not reach it automatically – packs apply by copy,
not by reference, so it only takes effect after that repo runs ctxgrd pack migrate.
Next steps
- Rule packs – the full built-in pack catalog.
- Configuring namespaces – path claims and allowed-values in depth.
- Keeping adopted packs current – migrating pack definitions after a ctxgrd upgrade.