Skip to content

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.

ArgumentNotesWhat it is
idrequiredthe task to ship, e.g. RK5
--why WHYthe 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 PARTrecord only the half that landed and leave the line open, e.g. 'local half'; a later ship with no --part completes it
--remainder REMAINDERwhat is still left, with --part: it becomes the open line's why
--lines LINEShow 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_DESIGNwhat 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_INthe file the deleted design's durable half moved to; must resolve
--decides DECIDESthe 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 ANCHORwhere 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 LEADrepeatable; 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
--jsondefault falseevery 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.

ArgumentNotesWhat it is
--block BLOCKrequiredthe block label, e.g. B
--symptom SYMPTOMrequiredwhat did not work — a phrase, never the name of the patch that closed it
--why WHYrequiredone sentence, ending in a stop: the outcome; '-' reads stdin, which is how an apostrophe or a backtick survives a shell
--id TASK_IDthe 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 IDthe 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 LINESrefused, 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
--jsondefault falsethe 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.

ArgumentNotesWhat it is
idrequiredthe recorded id, e.g. RK41
--why WHYthe 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 PARTcorrect a partial's qualifier; refused where the entry carries none
--symptom SYMPTOMrespell 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 LINEShow 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
--jsondefault falsemachine-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.

ArgumentNotesWhat it is
idrequiredthe recorded id, e.g. RK41
--to-block TO_BLOCKrequiredthe block label to file it under, e.g. B; refused unless a heading declares it
--jsondefault falseboth 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.

ArgumentNotesWhat it is
idrequiredthe id the ledger carries twice, e.g. RK41
--line LINEwhich 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
--jsondefault falsewhich 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.

ArgumentNotesWhat it is
idrequiredthe id the ledger carries twice, e.g. RK41
--line LINEthe entry that moves; named, never defaulted
--to TOthe new id (default: derived, one past the highest in its family)
--jsondefault falsemachine-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.

ArgumentNotesWhat it is
blockrequiredthe block label, e.g. B
--near SYMPTOMthe 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
--jsondefault falsemachine-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.

ArgumentNotesWhat it is
--id TASK_IDask about one id: exits 1 where that id's decision was reversed
--jsondefault falsemachine-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.

ArgumentNotesWhat it is
idrequiredthe decision being replaced, e.g. RK5
--by IDrequiredthe decision that replaces it, already filed in the same file
--jsondefault falsemachine-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.

ArgumentNotesWhat it is
idrequiredthe decision being corrected, e.g. RK5
--decides DECIDESthe 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 SYMPTOMrespell the claim — accepted only where it folds to the one on record, so bytes that never arrived are correctable and a rewording is refused
--jsondefault falsemachine-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.

ArgumentNotesWhat it is
idrequiredthe task leaving, e.g. RK33
--superseded-by IDthe id that takes the work over, which is a replacement and not an abandonment; omitted, the line is recorded as abandoned
--reason, --why REASONrequiredone sentence, the author's own: the tool never writes it; '-' reads stdin, which is how an apostrophe or a backtick survives a shell
--jsondefault falseevery edit, as data