Shipping, and the doors out
ship is one write, not two. It moves the line out of the backlog, writes the ledger entry
under the right block, drops the rationale section the design lived in, and re-derives the
dependency annotations of everything that was waiting on it — so the docs never describe a
state that did not ship.
The rationale section is deleted on purpose. It exists to argue for work that has not happened; once it has, the argument is spent and what remains is the outcome, which is the ledger sentence. A file that kept both grows without bound and is read by nobody, which is the state this tool was written after measuring.
Not every line ends that way. retire closes one that will not be done, and --decides
files the constraint the deleted design leaves behind into the decisions role — the thing
that outlives the code, and the reason a later reader does not re-propose what was already
rejected. supersede marks one such decision replaced by another, in the file that holds
both, so the two records of one reversal name each other.
reversals is the read that makes those pairs findable, and it exists because a revert is
recorded as a delivery like any other. A duplicate check that asks “did something already
ship this?” answers yes about the revert and misses that the new line is asking to undo it
again — which wastes an id and the argument the revert already had.
record add writes a ledger entry directly, for shipped work no open line can carry.
ship
Writes. Served to an agent as ship.
Ship one task in three edits across three files. Everything is validated before anything is written, because whichever of the three is done by hand last is the one that gets forgotten. `--why` is the outcome and is required: the roadmap's sentence states the problem, and inheriting it files a defect report under a heading that means done.
| Argument | Notes | What it is |
|---|---|---|
id | required | the task to ship, e.g. RK5 |
--why WHY | — | the outcome this shipped — required where an entry is written, because the roadmap's sentence states a problem and is not inherited; refused where the ledger already holds the id and this call only closes the line. Completing a wrapped partial with --lines above one, it is the whole span: the first line is the outcome and the rest is written back as the tail; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--part PART | — | record only the half that landed and leave the line open, e.g. 'local half'; a later ship with no --part completes it |
--remainder REMAINDER | — | what is still left, with --part: it becomes the open line's why |
--lines LINES | — | how many lines the completion replaces; required where the partial entry it completes wraps, and refused where this call replaces no entry — above one it is also what lets --why carry that span back instead of collapsing it |
--superseded-design SUPERSEDED_DESIGN | — | what the design this deletes turned out to be wrong about, e.g. 'the resize endpoint it called a new subsystem had shipped two blocks earlier'; appended to the ledger's sentence with the section's address, since the entry is the one place both survive the deletion; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--recorded-in RECORDED_IN | — | the file the deleted design's durable half moved to; must resolve |
--decides DECIDES | — | the constraint the deleted design leaves behind, filed as one line in the decisions role; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--decides-ref ANCHOR | — | where the decision's body goes, as an outline anchor — required beside --decides where `ref_scheme = "outline"` and refused where the anchor is the id; `anchors --role decisions --next` names a free one |
--checked LEAD | repeatable; default [] | a criterion of this task that was verified, repeatable: its own sentence goes under the ledger entry, and one nobody names reads as unchecked |
--json | default false | every edit, as data |
record
A group of the verbs under it.
The ledger's own doors, the ones the roadmap's are not: every other command starts from a task line, and these start from the entry.
record add
Writes. Served to an agent as record_add.
The fourth door, and the only one that starts nowhere: `ship` and both retirements begin from an open roadmap line, so this is how the ledger records work that has none. Never planned is one case and not the definition — a task that was planned and shipped inside another's sentence needs its own entry too, and so does a revert (--supersedes). What it does is write the entry and touch nothing else; without it the only route in was a fictitious line shipped in the same breath, which teaches that the format can be gamed.
| Argument | Notes | What it is |
|---|---|---|
--block BLOCK | required | the block label, e.g. B |
--symptom SYMPTOM | required | what did not work — a phrase, never the name of the patch that closed it |
--why WHY | required | one sentence, ending in a stop: the outcome; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--id TASK_ID | — | the id (default: derived, one past the highest anywhere); refused where a line already holds it, allowed where only a sentence names it — which is how an id cited but never recorded gets the entry it is missing |
--supersedes ID | — | the entry this one reverts: its sentence gains `(superseded by <id>)` in the same write, so the ledger's two records of one decision know about each other |
--lines LINES | — | refused, and kept only to say so: the --supersedes pointer is appended to the sentence on the entry's first line and replaces no span, so a wrapped bullet needs no count and keeps the lines under it |
--json | default false | the entry, with the file and line it landed on |
record amend
Writes. Served to an agent as record_amend.
Rewrite one entry's `why`, or a partial's qualifier, without moving the line. `drop` and `add` are not equivalent to this: they would remove the entry and append a new one under its block, so a ledger read in the order work landed stops being one and a reviewer sees a deletion where a word changed. The `symptom` is the claim, so it is respellable and never rewordable; the id is not a field here and is `renumber`'s; and the block is not offered because filing an entry elsewhere is a move.
| Argument | Notes | What it is |
|---|---|---|
id | required | the recorded id, e.g. RK41 |
--why WHY | — | the corrected sentence, one stop — or, with --lines above one, the whole span: the first line is the sentence and the rest is written back as the tail; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--part PART | — | correct a partial's qualifier; refused where the entry carries none |
--symptom SYMPTOM | — | respell the claim — accepted only where it folds to the one on record, so bytes that never arrived are correctable and a rewording is refused |
--lines LINES | — | how many lines this correction replaces; required where the entry wraps, because there the sentence runs past the line the parse holds — and above one it is also what lets --why carry that span back |
--json | default false | machine-readable form |
record move
Writes. Served to an agent as record_move.
The move `amend` deliberately does not pretend is a correction. `ship` files an entry under the block its roadmap line sat in, so a line filed under the wrong one ships to the wrong one — and no other verb reaches it: `record add` refuses an id that exists, `drop` wants the id stated twice, `renumber` changes the address and not the heading. This removes the line and re-places it under the named heading, reporting both positions, and refuses a heading the ledger does not declare — `block add` is what writes one.
| Argument | Notes | What it is |
|---|---|---|
id | required | the recorded id, e.g. RK41 |
--to-block TO_BLOCK | required | the block label to file it under, e.g. B; refused unless a heading declares it |
--json | default false | both positions, and the blocks they are under |
record drop
Writes. Served to an agent as record_drop.
Delete a duplicate entry, and only a duplicate: refused unless the ledger states the id twice, because removing the only record of a decision is deleting history rather than de-duplicating it. The first entry stays, since that is where a reader already found the decision, and no other file is opened.
| Argument | Notes | What it is |
|---|---|---|
id | required | the id the ledger carries twice, e.g. RK41 |
--line LINE | — | which of the two entries goes; required when they do not say the same thing, because then they are two deliveries and not one recorded twice |
--json | default false | which line went, and which one answers now |
record renumber
Writes. Served to an agent as record_renumber.
The counterpart of `renumber` for the file that verb never opens. Renumbering a record is normally how a `git log -S` starts returning two unrelated designs — and that argument inverts on a collision, where the shared id is already what makes the history unreadable. Refused on anything but an id the ledger states twice, and which of the entries moves is yours to name: the one that earned the id from a roadmap line is the one to leave alone.
| Argument | Notes | What it is |
|---|---|---|
id | required | the id the ledger carries twice, e.g. RK41 |
--line LINE | — | the entry that moves; named, never defaulted |
--to TO | — | the new id (default: derived, one past the highest in its family) |
--json | default false | machine-readable form |
delivered
Reads. Served to an agent as delivered.
The other list to consult before proposing work, beside `non-goal list` (RK69). A duplicate is not refused and could not be: RK378 restated RK340 the day after it shipped and RK382 restated RK178 a day later, and a lexical match cannot be gated: measured over this ledger it ranks the true pair in the top three and still scores below what an entry with no duplicate scores against its own nearest neighbour, so no threshold separates them. Two people describing one problem use disjoint words, and recognising that takes meaning this tool has none of (L4). So it states what the block delivered and you read it. Symptoms alone: the claim is what a duplicate collides with, and the outcome sentence doubles the length. A letter no heading declares is refused rather than answered as empty — that answer is read as evidence — and where the label is declared the reply says which of live, paused, finished or empty the block is. `--near` is the same read bounded by the question (RK442): the 5 entries nearest the sentence you are about to propose, in order, instead of the whole block. The order is the answer and there is no score — RK441 measured that the absolute one separates nothing, so publishing it would invite a threshold that cannot exist.
| Argument | Notes | What it is |
|---|---|---|
block | required | the block label, e.g. B |
--near SYMPTOM | — | the symptom about to be proposed: print the 5 entries nearest it rather than the block, ranked by word overlap and never refused or warned about |
--json | default false | machine-readable form |
reversals
Reads. Served to an agent as reversals.
A revert is filed as a delivery, so a duplicate check answers `yes, shipped` about the entry that says the work did not hold. This reads the forward pointer back: every id the ledger marks superseded, the entry that superseded it, and that entry's sentence — which is the argument a fresh proposal is against. Read it before an `add`, not after. It refuses nothing: re-proposing reverted work is sometimes right, and which is a judgement the tool never makes.
| Argument | Notes | What it is |
|---|---|---|
--id TASK_ID | — | ask about one id: exits 1 where that id's decision was reversed |
--json | default false | machine-readable form |
supersede
Writes. Served to an agent as supersede, on a project that declares decisions.
The decisions role's one departure. A roadmap line leaves by three doors and a decision leaves by being replaced, so nothing in that file is ever deleted: this appends the forward pointer to the entry that is now stale and moves its marker, in one write. Both ids have to be decisions this file already records — the replacement is written by `ship --decides` before it can replace anything — and there is no reason field, because why one decision replaced another is the argument in the entry that replaced it, one line away.
| Argument | Notes | What it is |
|---|---|---|
id | required | the decision being replaced, e.g. RK5 |
--by ID | required | the decision that replaces it, already filed in the same file |
--json | default false | machine-readable form |
revise
Writes. Served to an agent as revise, on a project that declares decisions.
The correction door every other governed sentence has: a roadmap line has `amend` and `restate`, a ledger entry has `record amend`, and what `ship --decides` filed had neither. `supersede` is not it — that is for a decision replaced by another, and inventing a second decision to fix a spelling corrupts the record worse than the typo did. Nothing is deleted here: the entry keeps its line, its id and its marker, and a `(superseded by <id>)` clause is carried through rather than retyped, being derived and not yours.
| Argument | Notes | What it is |
|---|---|---|
id | required | the decision being corrected, e.g. RK5 |
--decides DECIDES | — | the corrected sentence, one stop — the constraint that outlives the code, under the decisions role's own limit and not the ledger's; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--symptom SYMPTOM | — | respell the claim — accepted only where it folds to the one on record, so bytes that never arrived are correctable and a rewording is refused |
--json | default false | machine-readable form |
retire
Writes. Served to an agent as retire.
The two departures that are not a ship: the work moved to another id (--superseded-by), or it is not being done. Both write one ledger line under the block it belonged to, with the forward pointer where there is one, and no design — which is what a gap here otherwise reads as, a botched hand-edit.
| Argument | Notes | What it is |
|---|---|---|
id | required | the task leaving, e.g. RK33 |
--superseded-by ID | — | the id that takes the work over, which is a replacement and not an abandonment; omitted, the line is recorded as abandoned |
--reason, --why REASON | required | one sentence, the author's own: the tool never writes it; '-' reads stdin, which is how an apostrophe or a backtick survives a shell |
--json | default false | every edit, as data |