roadkeep.toml is the whole of the sixth law: configuration, not convention. The prefix,
the id shape, which files hold which role, the markers, the limits, the budgets, the claims and
the reference scheme are all decided per project, because a tool that hard-coded any of them
would be one that only fits the repository it was written in.
The table below is generated from roadkeep config, which is the command that answers this
question from inside a checkout. It is here because the reader who most needs it is the one who
has not got a checkout yet: deciding whether to adopt comes before there is anything to
configure, and the description of the keys was behind the adoption it would decide.
Two tables hold judgements rather than settings, and the difference matters more than any
individual value.
[limits] bounds what a line may say and [budgets] bounds what a file may cost. Both are
measured against a corpus — the lines that already read well — and not chosen because they
sound reasonable. govern is the verb that writes one, and it refuses a limit this corpus
already breaks, because a number whose first act is a finding is one somebody lowers, reads
the report and quietly raises again.
govern --because "…" is where the argument goes: your sentence, wrapped into comments above
the key and stacked on whatever argued it before. That is the half worth keeping. A number
without its reasoning is one the next person changes on instinct, and the reasoning is the
expensive part.
So this page does not recommend a value, and nothing here should be copied as a default. Run
roadkeep adopt against the file you already have; it measures how many of your lines a given
limit would refuse, which turns the decision into a number rather than a hope.
The interesting case is not an empty repository. It is one with a ROADMAP.md somebody has
been keeping by hand for two years, which is exactly the repository worth adopting and the one
init is wrong for.
The order that works:
Terminal window
uvxroadkeepadoptdocs/ROADMAP.md# measure it: how many lines would a limit refuse?
uvxroadkeepdeclareroadmapdocs/ROADMAP.md
uvxroadkeeplint# every finding, each naming the command that closes it
uvxroadkeeplint--fix# the derived half, repaired mechanically
declare retrofits one role onto a file that already exists, rather than scaffolding a new
one. What lint then reports is a work list, and the findings that remain after --fix are
the ones needing a judgement — each carrying the command that closes it, and each with
a page here explaining the class.
Nothing forces you to declare every role at once. An absent role is absent, not empty: a
project can govern its roadmap for a month before it declares a changelog.
This repository’s own roadkeep.toml
is the one configuration that is provably valid — its docs/ are the format’s conformance
fixture, and lint passing on them is a gate on every push. It is one fetch away rather than
transcribed here, so it cannot go stale.
The This repository column below is that same file, read back: what roadkeep declares for
itself, beside what it would use if it declared nothing.
Read from roadkeep 0.2.516 against roadkeep.toml. What is listed is what that build accepts — which is how a key your copy does not have is told from a typo.
the top level
Key
Type
Default
This repository
blocks
array
[]
—
budgets
—
no default
declared
claims
—
no default
declared
criteria
—
no default
declared
files
—
no default
declared
grammar
—
no default
—
headings
—
no default
declared
history
—
no default
declared
id_sources
array
[]
["agents.md"]
ids
—
no default
—
install
—
no default
—
ledger
—
no default
—
limits
—
no default
declared
markers
—
no default
declared
non_goals
—
no default
declared
prefix
string
"RK"
"RK"
priority
array
[]
—
project
—
no default
declared
reads
—
no default
declared
ref_scheme
string
"id"
"id"
refs
—
no default
—
report
—
no default
declared
requirements
—
no default
declared
reserved_ids
array
[]
—
rules
—
no default
—
tools
—
no default
declared
validation
—
no default
declared
[files]
Key
Type
Default
This repository
changelog
—
no default
"docs/CHANGELOG.md"
decisions
—
no default
"docs/DECISIONS.md"
deferred
—
no default
—
dismissed
—
no default
—
improvements
—
no default
"docs/IMPROVEMENTS.md"
roadmap
—
no default
"docs/ROADMAP.md"
strategy
—
no default
—
[refs]
Key
Type
Default
This repository
decisions
—
no default
—
improvements
—
no default
—
strategy
—
no default
—
[ids]
Key
Type
Default
This repository
pad
integer
1
—
suffix
boolean
false
—
[headings]
Key
Type
Default
This repository
permanent
boolean
false
true
word
string
"Block"
—
[install]
Key
Type
Default
This repository
enforced
boolean
false
—
pinned
boolean
false
—
wired
string
""
—
[markers]
Key
Type
Default
This repository
deferred
string
"⏸"
—
dismissed
string
"🚫"
—
open
array
["📋", "💭", "⏳", "🛠"]
["📋", "💭", "⏳", "🛠"]
partial
string
"⏳"
—
retired
string
"🗑"
"🗑"
shipped
string
"✅"
"✅"
undesigned
array
["💭"]
["💭"]
working
string
"🛠"
—
[ledger]
Key
Type
Default
This repository
marker
boolean
true
—
symptom
boolean
true
—
[limits]
Key
Type
Default
This repository
description
integer
200
—
icon
integer
16
—
line
integer
320
320
name
integer
60
—
part
integer
40
—
prose
integer
88
88
section
integer
250
at 2 addresses
symptom
integer
120
120
why
integer
200
200
[rules.<role>]
Key
Type
Default
This repository
one_sentence
boolean
true
—
ref
boolean
true
—
terminator
boolean
true
—
[project]
Key
Type
Default
This repository
description
—
no default
"Owns the writes to a project's roadmap and changelog, so the format is a schema."
icon
—
no default
"🛣️"
logo
—
no default
—
name
—
no default
"roadkeep"
[non_goals]
Key
Type
Default
This repository
lead
integer
80
60
why
integer
320
200
[criteria]
Key
Type
Default
This repository
lead
integer
80
60
why
integer
320
200
[claims]
Key
Type
Default
This repository
held
integer
60
60
[requirements]
Key
Type
Default
This repository
declared
array
[]
{'decision': 'a choice a person makes between written designs; no code in this tree settles it'}
The boundary of the question above. These are numbers this build measures from a corpus rather than accepts from a file, so there is no key for them.
chars/word at 6.6 — the first round number above this corpus's percentile, so a word aim clears the character gate about nineteen times in twenty (read at 6.5 over 2422 samples, 95th percentile).