roadkeep
A ROADMAP and a CHANGELOG are formats held together by convention, so they drift the moment someone is in a hurry — or the moment an agent writes to them. roadkeep owns the writes: an entry goes in through a command that checks its shape at the point of insertion, which makes the file a schema rather than a habit.

Public numbers
- GitHub stars
- 1
- Release downloads
- 0
Public numbers from GitHub and PyPI, as of 2026-10-20. The site is rebuilt daily.
Install
/plugin marketplace add alegauss/alegauss.github.io /plugin install roadkeep@alegauss
uvx roadkeep lint
pip install roadkeep
What comes next
From the product's own docs/ROADMAP.md at eec61c6.
The model (a task is data before it is a line)
- IdeaA dep on another repository's task is free text, so nothing can tell whether it shipped
Authoring (insert, never hand-edit)
- Designedblock add opens a label the ledger already declares under another title
Product sites on the package
- DesignedThe pitch and the roadkeep-gui landing each keep their own copy of the template eight product sites share
Recently shipped
All 1187 entries →- RK1713 · b09b009no writing verb can be asked what it would write, so an agent probes a replace with a real write
section amend --check runs every refusal and prints the prose as it would read, writing nothing, on the CLI and the served tool (design recorded in
plugin/src/roadkeep/sections.py). - RK1712 · 4cbaae4show refuses a deferred id and only names where it sits, so a paused line's section is read by grep
show joins a paused line from the deferred store with its reason and the resume door, alone or among other ids; brief still refuses one (design recorded in
plugin/src/roadkeep/showing.py). - RK1711 · 2860ae7section add --role strategy refuses every anchor on a fresh init --strategy scaffold, and its remedy is the refused call
An id project's prose takes a non-id top-level anchor before the first block, so a scaffolded strategy file opens (design recorded in
plugin/src/roadkeep/sections.py). - RK1710 · 52f6a01non-goal list elides entries past twelve, and neither --json nor any flag prints the rest
non-goal list --all prints every entry, --json always carries every lead and reason, and the elided count names the flag (design recorded in
plugin/src/roadkeep/briefing.py). - RK1709 · c4ffc54anchors --next names no free top-level when a family is not one numbering
anchors names each numbering's free top-level with its family count where they differ, and a trailing colon no longer reads as a namespace (design recorded in
plugin/src/roadkeep/history.py). - RK1708 · 6f3a41ca ledger entry whose id the grammar rejects has no verb that corrects it, and its finding names one that refuses
record amend --line <n> --body - rewrites a ledger line whose id the grammar refuses, and the finding on such a line now prints that door instead of one that refuses.
- RK1707 · b56da4ccode.renamed fires in an adopter that vendors the engine, so its gate reports renames that never happened
code.renamed runs only where the project's pyproject.toml names the engine's package, so a vendored .roadkeep/ no longer fails an adopter's gate on renames that never happened.
- RK1706 · 204b406a line's requires can be replaced but never cleared, so a need a person met stays on the line
amend --drop-requires takes a met need off a line, over the CLI and the tools alike, and dropping the last word clears the group so pick offers the line again.