Changes touching this path

  • loot log gets a machine shape, and the seam it needed turns out to have existed all along: every verb already renders through Emit, so nothing had to be plumbed - what was missing is that the prose-only verbs return Message, which collapses their structure into a String at the cmd_ site, before the format is known. So adding machine output is not teaching the renderer a second format, it is stopping a verb destroying its own data on the way out, which is why it cannot be done to forty-seven verbs mechanically and why this ticket does one. Log, LogChange and LogWorking hold the structure and render all three formats from it, consuming topology.rs by making the same two calls --graph makes and reading row, edges, elided and merge straight off the nodes - no second walk, no ancestry query, and the module never sees a Workspace, so the manifests d6be741 stopped materializing stay unmaterialized. The load-bearing subtlety is that edges are indices into the shipped array, so --reverse has to happen before Topology::of rather than after, and the pin reads edges back as version-byte pairs so a wrong index cannot pass as a right one. The empty head is why head rows exist at all: b0cffc66 records no changes of its own, so it has an H row and no change row anywhere, and without the head rows a two-head repo would reach a machine reader looking unforked. What stops the other verbs being forgotten is a census that names rather than counts, two set-equal lists over derived vectors plus a sum, reusing the existing machine_output_verbs so it cannot disagree with the USAGE census - and the debt list may only shrink. Two ADRs are amended rather than edited past: 0023 quotes its own sentence that nothing needs machine output from log or manifest and says log graduates while manifest does not, and narrows its porcelain-first framing as written for a homogeneous per-path verdict rather than a shape with nested arrays; 0066's three counts had to move in place because a test asserts them against the roster. And both numbers in this ticket's scoping were wrong the same way source_walk was wrong in 9559f0a, a grep for one spelling of a thing with two: the table holds 66 verbs and not 54 because twelve rows are verb_of, sixteen took a machine selector and not seven, and ADR 0066 had recorded the right figures three weeks earlier. Criterion four had nothing to satisfy, because the SDK never calls loot log at all (#1540) 915db92c · dbf3dbe6…
  • loot evolog --porcelain no longer prints a whole recorded message in its E row: the last column was the message as recorded and a porcelain row is one line, so a message with a body printed that body at column zero as a line which is not a row, and a consumer reading a row per line read it as one and was then wrong about the rows after it by position, while an empty message left the field empty where ADR 0088 V3 puts the dash. each was reproduced by hand through the spawned binary first. the column is the message first line now, through the new render::subject_line, which is the rule the log terminal column already followed and is now one home for both frozen shapes, and col gives it the dash when the message is empty; a tab stays inside it, since V5 puts the free-text column last so a consumer splits the leading fields with a limit and takes the tail whole. the human subject column takes the same first line, so a version with a body renders on one line there too. evolog --json gains a trailing message field carrying the whole message and its subject becomes the first line, the pair log --json already spells: that re-means a shipped value, and the amendment records it rather than leaving two shapes disagreeing about the word. the new spawned pins for a multi-line, a tab-bearing and an empty message went red before the change (1 passed, 3 failed) and are green after (4 passed), with a single-line row as the control that stayed green throughout; they redden with the whole message put back in the column (1 passed, 3 failed; the unit pins 6 passed, 2 failed), with the dash dropped (3 passed, 1 failed; unit 7 passed, 1 failed) and with the json message field removed (3 passed, 1 failed; unit 6 passed, 2 failed). the pre-change release binary and this one print byte-identical porcelain and human rows for a single-line message over one repo. ADR 0023 carries the dated amendment with the shape and what the fix moved, ADR 0088 section 4 no longer lists evolog and says an item leaves when its fix lands, CONTEXT.md names both, and the workspace suite is green (3830 passed) (#1973) c9a99b16 · dbf3dbe6…diff
  • a superseded head is listed, not counted: loot log and loot heads stop counting a version superseded under ADR 0032 as a head, so a clean loot move --before no longer prints 2 heads - diverged; finalize then converge for a divergence that does not exist. the rule is spelled once as Liveness::is_superseded, which the head partition drops stale by, loot heads prints its superseded annotation by, and the counts now read: history() routes, counts and sections over the heads that predicate rejects, through a new LogGraph::retain_heads that re-indexes reachability into the kept heads, and the heads header counts the rows whose superseded flag is false and says how many superseded versions follow, still listed under the annotation. the head set itself is untouched - the stale head stays in .loot/heads until a converge retires it. reproduced first through the spawned binary on the lane tree at #1837 exactly as the ticket describes, and measured on move --onto too, where the stale head is not empty (B stays reachable only through it), which is why the rule is superseded and not own == 0. status never counted heads and never marks this with !, pinned rather than assumed. every machine shape is byte-identical modulo ids except the rows that were wrong: log --porcelain loses its two H rows and the working-change * row the fork view printed, log --json goes heads null, and heads --porcelain, heads --json and all three status shapes do not move. red first, four ways: the count rule undone reddens the workspace pin and the spawned reorder pin (0 passed, 1 failed; 1 passed, 1 failed), the header count undone reddens the heads pin and the spawned pin (6 passed, 1 failed; 1 passed, 1 failed), every head uncounted reddens the positive controls while the negative pin stays green (5 passed, 3 failed; 1 passed, 1 failed), and the predicate blinded reddens the partition, the annotation and the count together (6 passed, 1 failed; 0 passed, 2 failed). the #1477 production-shape pin moves to the new header, and ADR 0032 and CONTEXT.md record the amendment. no migration, no wire or format byte moves, and no forge or relay behaviour moves, so this owes no deploy. the workspace suite is green (3887 passed over 122 binaries, 7 ignored) (#1839) 8e6c0841 · dbf3dbe6…diff
  • sweep 1 fix-up over #1826, #1837 and #1839: a live change only a superseded head reaches is listed in the fork view, in a third section of its own, rather than in no section at all. LogGraph::retain_heads leaves such a change with an empty reachable_from, and history() partitioned the fork on exactly one head and more than one, so after a move --onto the ancestor the old tip alone reaches was printed nowhere - reproduced first through the spawned binary with two live lines (0 passed, 1 failed), the fork and the non-empty superseded head both holding as controls. GraphHistory gains unreached, the renderer prints it under behind a superseded tip after the shared ancestry, drawn_rows leads with it because such a change can only be a child of a lane or shared row, the path filter, retain_versions and all_rows walk it, and both machine shapes carry the row with no new column. HEAD on an untracked position with no working change now counts the heads Liveness::is_superseded rejects and answers the sole counted head by name, because Position::anchor answers the first graph head, which can be the superseded one; measured at the other two sites the ticket named, propose already reads is_live and IntegrationPreview deliberately counts the whole partition with retire for the superseded ones, so the liveness doc now points at the callers of the predicate rather than listing two readers. the move --onto usage line gets its space back; refit_shape spells its path columns through treepath::store_key with a backslash pin, and the #2033 census records the tree-path axis it is blind to by design; the shallow clause has one spelling, workspace::parents_not_held, read by the notice and the push refusal, with the pin the suite lacked; carried is carried_count, Reanchored.change is change_id, the squash and absorb op-log lines say re-anchored, frontier_beyond_the_host is private, the one-flag-member sentences drop one, ADR 0089 names both readers of .loot/shallow and both frontier spellings, and the one raw exit ADR 0089 rests on is held to one by a census in tutorial.rs. own > 0 for the move --onto stale head is pinned off the loot heads row. red first, six mutations in one round over disjoint pins: the unreached filter blinded, drawn_rows reordered, the HEAD filter blinded, store_key undone and a second raw exit added redden five pins with the sync shallow control green (1 passed, 5 failed) and the spawned fork pin (2 passed, 1 failed); the noun-verb swap survived tests/shallow (10 passed, 0 failed), which is why the clause has a pin now (0 passed, 1 failed under the swap). ADR 0066 keeps its gated 28 and points at the gate instead of at tickets. no migration, no wire or format byte moves, and no forge or relay byte moves, so this owes no deploy. the workspace suite is green (3895 passed over 122 binaries, 7 ignored) (#2046) 0b55a20f · dbf3dbe6…diff
  • the two shapes that graduated without a record get their amendments, telemetry status and off carry the contract field, and the comma-joined column gets one home: #1971 carries the ADR 0088 section 4 follow-ups and asks for each premise to be re-verified first, so each was read against the tree — ADR 0023 held no amendment for count-objects (#1523) or telemetry (#1658), telemetry status and off printed no contract field and the string dash where V3 says null, and the Verdict entry in CONTEXT.md still typed 17 of the 68 beside a roster where the dispatch table derives 32 emitting verbs and 51 prose-only ones; the ticket comment correcting item 2 is the later word and is taken as such, telemetry on printing report JSON for the same deliberate reason as show. ADR 0023 gains two dated amendments describing what shipped: the one-metric-per-mark census rows, and the name-keyed telemetry rows with the divergences frozen beside them. status and off lead their JSON with contract now and spell an unresolvable spool null, rendered by status_shape and off_shape, which take values rather than reading the config so all three renderings are assertable; show and on stay exempt because what they print is the report the sender posts, and the exemption is pinned over Report::to_json rather than over a verb, that string being what the endpoint receives. The shared flag column item 3 asks for is verdict::joined_col, the comma join with the dash when empty, and what defines membership is that spelling rather than a roster, so the columns spelled that way are its callers: blame, delta_shape, explain, heads, log, evolog, attestation_shape, refit_shape, seek, tag, both pipeline listings and lanes route through it and no frozen shape pin moved. The cross-shape census is declined with its cost recorded in ADR 0088 section 4, since a census over values needs a pub on each shape that #1553 refuses, one over a spawned binary reads nothing for a verb whose arguments it cannot supply, and its exemption table would be a hand-maintained list asserted as complete. Red under mutation, counts read each time: joined_col joining with a tab (loot-cli 1335 passed and 8 failed), the empty set printing an empty field instead of the dash (1324 passed and 19 failed, and loot-core 647 passed and 1 failed naming lanes_porcelain_rows_are_the_frozen_contract), the contract field taken off status and off (5 passed and 3 failed), the spool null spelled as the string dash again (7 passed and 1 failed), and a contract field added to the report the sender posts (6 passed and 2 failed), each restored. No migration, no wire or format byte moves and no host behaviour moves, but two leaves of client JSON move, so this rides the next release and owes no deploy. The workspace suite is green (4107 passed over 132 binaries, 8 ignored) (#1971) 4ef9c62b · dbf3dbe6…diff

Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.