Add reopen edges and decision screen rendering - #41
Merged
Conversation
The principal ruled (2026-08-13) that a watched-not-grounding edge is a distinct edge type, not a basis: this claim's death reopens the decision; it is not the decision's ground. It is filed as its own edge with its own vocabulary, never inside based_on, so neither the basis-loss scan nor `why` reads it as ground — and a status movement on a revisit_if edge produces a reopen finding, not a basis-loss finding. The cross-repo basis-ref amendment has not landed and is not in flight (only open PRs are #40 and a stale #10), so this is its own amendment at the current version: ledger spec v1.5 / format 4, adopted by .ddd at its format 7 — one shape, specified in the ledger format first. The L6 signing revision renumbers a third time, to spec v1.6 / format 5. Format: revisit_if is an optional hashed list on a version, its own type (RevisitRef, never BasisRef), canonicalised under its own key. Absent on every prior version, so no digest moves, no acceptance is invalidated, CANONICAL_FORM stays v1, and the file gate's ten classes are unchanged — resolution is a consumer's business at L0, as it is for every discharge scheme. Guarded by a canon test: one token as ground and the same token as a reopen edge are different content. Reporting: `ddd report escapes` gains a fourth section with its own heading and its own message; the ledger pin scan retires the `watched:` marker outright, so a stray one can never surface as basis loss again, and reads revisit_if into a separate Reopened list. `ddd why` renders the edges under their own heading, below the ground and visibly apart. .ddd format 7 gates the field: format-declared, always pinned, and never the same claim as a basis — an edge read both ways is the conflation the distinct type exists to end. `ledger show` lands with it: one screen per decision — hashed content, both edge kinds kept apart, the filing act, the acceptance situation — with --json, a --set/--group selector so a pass over 79 entries is one invocation rather than 79, and each edge's argument text rendered under its pointer. The weight class (mechanical | individual) is derived from the discharge, never hand-listed, so the grouping cannot go stale. ledger-cli gains a display-only ddd-core dependency for that argument text; ledger-core stays ontology-free, taking the resolver as an input. Gates green: cargo t, the documented clippy gate, ddd validate (222 entries), ledger verify (196 entries, 91 decisions). The 33 clippy errors under --all-targets pre-date this branch on main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YXS9qyjKVanMXnpwCJpwJm
Each is a re-decision of that entry's edge, filed for the principal's acceptance — not a silent rewrite. In `.ddd` the claim moves out of based_on into revisit_if at format 7, pin carried across unchanged (status, changed, and the content hash M8 recovered at that pinned state); in the ledger a new version re-takes the ddd-content pin at the entry's new content and states the reopen edge. Prior versions keep signing exactly the historical content they named. DDD-adapter-02 dec/ddd/internal-not-surface projected@2026-08-06 DDD-gates-01 dec/rust/no-unwrap reported@2026-08-06 DDD-adapter-01 dec/ddd/m6-proceeds-no-flip projected@2026-08-02 The third is the one whose pin has drifted, and the drift was deliberate — the claim moved projected -> reported -> established and was looked at twice. It moves out of the basis-loss list and into the reopen list, which is the correction the ruling makes: that decision's ground is the principal's stated default and has never moved. The other two are unmoved and do not fire. The two genuine basis losses stay where they were. The ontology question the M8 migration filed (question/ddd/watched-edge- kind) gets a version recording the ruling; the earlier version stated the open question and remains what it always said. Not migrated, and blocked rather than forgotten: the provenance audit's one upstream watched-not-grounding row — workspace-member-delivery tracking the What/How vocabulary. revisit_if gives the relation a home; it does not give a cross-repo pointer one. Recorded as §10.4 of the audit. Two gaps closed on the way: the ledger section of `ddd report escapes` prints reopens on their own lines, and the L2 graph carries the edge under its own predicate (ledger:revisitIf) — a query walking ledger:basedOn is asking what a decision rests on, and a reopen edge is not an answer. `ledger revise` gains --note (the reason for a re-decision belongs where the filing is read) and `ddd content-hash <id>` prints the pin a ledger entry must state — M8 computed these inline and hard-coded them, leaving anyone re-deciding an entry afterwards without the number. Gates green: cargo t, the documented clippy gate, ddd validate (222 entries), ledger verify (200 entries, 91 decisions), index rebuilt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YXS9qyjKVanMXnpwCJpwJm
DDD-gates-02 (projected): a pipeline of sequentially-gated CI steps reports what broke first, not what it did not check. Verified against the tree rather than taken on report — main at 75b5472 carried two defects and showed one: 9df74c1 added `note` to AddArgs and updated one of four call sites, so the test targets did not compile and CI stopped there; behind that, ledger-core/src/author/tests.rs sat at exactly the 400-line ceiling and went to 402 once the call sites were fixed. The second gate failure was found by hand (7258af1), not by the gate. The sharpest part of the finding is that the repo already fixed this failure mode one level down and did not carry it up: `cargo t` is `test --no-fail-fast` precisely so one failing binary cannot hide the rest, while the nine steps of product-ci.yml each run under the default `if: success()`. Family recorded in the entry: the M6 leakage prediction and L3's cross-file merge finding — a mechanism guarding the path it can see, blind to what sits behind it. The falsifier is two negative results a future run can genuinely produce, both about whether the hazard is real: that no red run's skipped steps would have failed on their own, or that the 75b5472 case is re-graded. Drafted so the remedy cannot fire it — fixing the pipeline changes what future runs report and says nothing about whether past masking hid anything. A claim its own remedy kills is the self-sealing defect DDD-method-07 names. The remedy is filed as a decision awaiting the principal's acceptance and is NOT implemented here: independent gates run anyway, or — the floor, where a step genuinely depends on a failed one — the run reports which gates did not execute. Allocated as a judgment, honestly: nothing checks the arrangement, so holding to it rests on a person, and a criterion would name a discharge resolving to no checker. Cost of the follow-up stated in the entry: a red build stops failing fast and pays each independent gate's runtime, the benchmark step most of all. The claim edge is genuine ground and sits in based_on, not revisit_if — if the instance is re-graded away the decision loses its reason. First new use of the distinction the 2026-08-13 ruling draws. `ledger add` gains --note for parity with revise. Gates green: cargo t, the documented clippy gate, ddd validate (224 entries), ledger verify (202 entries, 92 decisions), index rebuilt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YXS9qyjKVanMXnpwCJpwJm
docs/acceptance-worksheet-2026-08.md: grouping and flags only, since `ledger show` is now the read. It says plainly that where the two disagree, `ledger show` wins — it is derived from the log and the worksheet is written by hand. Group A is the 33 transcribed seam declarations, and the claim that they are one shape is checked rather than asserted: all 33 are criterion / pr, one contract: discharge, one ddd-content: basis and nothing else, no reopen edge, T1, first version, all filed by the M8 migration on 2026-08-12. What is being ruled once for the group is that the transcription is faithful. Group B is the 47 individual reads, partitioned into five sub-groups that sum to 47 — with the overlap named rather than double-counted: three of the seven re-typed bases are also the revisit_if conversions, so one screen carries both rulings. Flags: interceptor-not-extension is held, its basis still indeterminate:DDD-arch-03 pending the F-7h ruling. Nothing is mid-migration — the three conversions and the ruling record all landed as complete versions — and the worksheet says so rather than leaving the absence to be inferred. The audit's upstream row is noted as blocked, not in the pass at all, because nothing is filed for it. Uniform T1 confirmed across all 80: not one tolerance_override, so the floor was pinned rather than chosen and the grouping is doing the work the tier would otherwise do. One genuine T2 case proposed, not applied: the priced escape over 24 undeclared What boundaries and its decision — the one pair that knowingly carries exposure, and the first L6 signing would bind. typed-basis considered and declined as tier inflation. The cost of acting on the proposal is stated: revise has no --tolerance-override today, and raising the set floor instead strands every member below it. The sequence names the L009 trap first — accept takes the acceptor from git config and L009 checks it against the commit author — and is honest about the loop: the format has no group-acceptance primitive, so the loop records one judgment 33 times rather than making 33. The wall-clock table says why the number matters: it is the acceptance-latency instrument's first reading and L5's requirements input, and a null result is as useful as a positive one. ledger-cli/tests/show.rs exercises the screen through the binary — the ruling is about what a reader sees, so ground-and-reopen-never-share-a- block is asserted on rendered output, plus the format-4 declare-what-you- need rule, the selectors, and the two refusals (unknown id, two selectors at once). Gates green: cargo t, the documented clippy gate, ddd validate (224 entries), ledger verify (202 entries, 92 decisions). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YXS9qyjKVanMXnpwCJpwJm
129 contract-surface events over 15c6352..HEAD, all now discharged by signed bindings: 124 filed by `ddd bind`, across 15 freshly created declarations and 11 existing ones. Every new declaration carries real verdict_knowledge — what a reviewer learns at that boundary, and where it applies, what the boundary cannot do. The two that matter most say the ruling out loud: ledger-core's version.rs boundary states that based_on and revisit_if never merge (two fields, two hash keys, two types, and a caller reading either as the other would report a fired tripwire as a lost basis), and ddd-core's revisit.rs boundary states that a reopen edge always pins, that a claim is ground or tripwire and never both, and that firing means a fresh look is due rather than that the ground moved. show.rs's boundary states its own limit honestly: ledger-core resolves no basis argument itself, it takes a BasisText resolver as an input, and with NoText the pointers render bare — which is what keeps the substrate an outside implementation imports free of any adopter's ontology. Gates green: cargo t, the documented clippy gate, ddd validate (239 entries), ledger verify (202 entries, 92 decisions), xtask check (0 errors), ddd diff-contracts over 15c6352..HEAD (129 events, 0 undischarged). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YXS9qyjKVanMXnpwCJpwJm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the reopen edge feature (format 4/7) and the
ledger showcommand for rendering decision screens. This settles the watched-edge question from the basis-quality re-typing session by making reopen edges a distinct type, separate from ground bases, with their own scanning and reporting paths.Key Changes
Core reopen edge support:
revisit_iffield to ledgerVersionRaw(format 4) and dddDecision(format 7)RevisitRefandRevisitEdgetypes to represent reopen pointers structurally separate from basesreopen_scan) that never seesbased_on, ensuring fired tripwires don't report as basis lossDecision screen rendering (
ledger show):showmodule withScreenstruct carrying hashed content, both edge kinds kept apart, filing act, and acceptance situationBasisTexttrait for resolving pointer arguments;NoTextimplementation for bare pointersSelectorenum (One, Set, Group, All) for covering multiple decisions in one passGroupenum (Mechanical, Individual) derived from discharge, never hand-listedshow_renderwith aligned block output; JSON serialization via struct directlyledger showcommand with--decision,--set,--group,--jsonflagsLedger format evolution:
revisit_iffield, hashed when present, omitted when absentCANONICAL_FORMbump; every existing digest unchanged; file gate's ten classes unchangedDDD format evolution:
Decisionstruct gainsrevisit_if: Vec<RevisitEdge>fieldwhyrendering for reopen edges under their own headingReporting:
LedgerSectiongainsreopenedlist andreopen_checkedcount, separate frompin_driftddd reportshows fired reopen edges distinctly from basis lossReopenedstruct in ledger gate for reportingTesting:
show_tests.rscovering screen assembly, edge separation, acceptance situationrevisit_tests.rsfor reopen edge firing, coverage, gate separationsign_tests.rssplit fromtests.rs(signing verbs: accept, revoke, supersede)ledger-cli/tests/show.rsfor end-to-end screen renderingdocs/acceptance-worksheet-2026-08.md) documenting the 80-entry passSeam declarations:
show.rs,revisit.rs,show_render.rs,basis_text.rs,inspect.rs, and CLI command surfacesNotable Implementation Details
based_on.Group) is derived from discharge, not hand-listed, so it cannot go stale as entries are added.BasisTexttrait, keeping ledger-core free of adopter ontologies.https://claude.ai/code/session_01YXS9qyjKVanMXnpwCJpwJm