Context

The owner asked on 2026-10-27 for opportunities to change item statuses or relations: “claims that a lot of interesting downstream material depends on but which is currently in proposed state”. Then: “the record has changed materially since that last audit was interrupted. also, that was the first time we utilized that process, and would likely benefit from changing it.”

The audit of ADR-047 ran from 2026-10-19 to 2026-10-21. Measured on origin/main at 99ce85e6f against the queue’s own record revision (3064087c, version 172):

  • The record moved. 611 commits came after the queue’s revision. They added 326 THEORYs, 91 CLAIMs, 63 QUESTIONs, 60 CASEs and 32 TERMs, and modified 103 CLAIMs and 168 THEORYs.
  • The decisions went stale. 230 of the 308 decision files judge an entry that has changed since its reviewed_revision. ADR-047 called such a review stale, and nothing re-ran one.
  • It ranked the load-bearing claims last. Counting transitive dependents along rests_on, grounds, uses and presupposes, 15 of the 19 most-relied-on Proposed entries never entered the queue. CLAIM-027 has 19 dependents, CLAIM-177 13 and CLAIM-025 13. The waves ordered candidates by kind of evidence, and the record’s own interpretive theses came last, in wave 5. Of the 32 reviewed there, 22 were retained. NOTES records the reason: “ADR-047 gives arguments no audit route, and interpretive promotions go to the owner.”
  • The owner questions were never asked. All five decided promotions that are still undone (CLAIM-322, CLAIM-328, CLAIM-046, CLAIM-241, and THEORY-073’s narrowing) wait on an owner ruling. About forty such rulings sit in one string, the queue’s handoff.next_step, and no pull request put them to the owner.
  • Relations were out of scope. On the same tree, 49 edges have an Active CLAIM resting on or grounded in a Proposed entry. Four claims use Superseded TERMs. 37 Open QUESTIONs list an Active answer. The audit did not look for any of these.
  • Separating review from promotion was costly. The queue’s history cites 114 pull requests, numbered #165 to #308, over three days.

Decision

The worklist is derived and kept nowhere. record/status-review/worklist.py reads the frontmatter on a freshly fetched main and prints these sections:

  • Load-bearing Proposed entries: Proposed CLAIMs, THEORYs and TERMs, ranked by their transitive dependents along rests_on, grounds and uses (for CLAIMs and ARGs) and presupposes (for THEORYs). Each entry shows its premises the record does not hold and its live objections.
  • Held: the same entries, when a blocker note under 14 days old (luria’s stale_days) says what they wait on. They come back as work when the note is older, so a blocker is re-read rather than forgotten. The timer is a floor, not the only way back: an entry comes back sooner when something its note names has moved (an entry it names is revised, or a work it names gets a reading), and any held entry may be reviewed at any time. The timer guarantees each one is looked at again at least once.
  • Credence inversions: Active CLAIMs whose rests_on or grounds names something not Active.
  • Sound arguments whose conclusion is not held: an Active ARG whose premises are all Active, concluding a claim that is not, unless a held undercutter already says what it does not carry (ADR-059).
  • Concessions not written into their targets: an Active claim whose objects_to target has no revision dated on or after it that names it in its history note. A revision made for something else does not write a concession in. Every Active objection counts, whatever its role: the record holds it true, and conceded counters went Active under the convention ADR-059 replaced. ADR-059 records a concession by revising the target; the fifth pass found four clusters where it had been left in a note. A target filed with the concession already in its text says so in a dated note headed ## Note of YYYY-MM-DD: filed with its concessions that names the objections, rather than taking a version bump that records no revision.
  • Retired premises: live entries that need something Superseded or Rejected, with the live successor reached along superseded_by.
  • Open questions with an Active answer.
  • Stale converses: a Proposed reading that still lists an Active claim under supports. The repair bot writes the converse grounds, and the lint’s inverted_ground then fails.
  • Ready for a ruling: Proposed CLAIMs with all premises held, no live objection and no standing blocker note, grouped by line. A live objection is a Proposed or Active one whose concession is not yet written: narrowing the target answers it, and the narrowing’s history note names it.
  • Sole blockers: the unheld premises ranked by how many claims each is the only thing holding back.
  • Blocker notes a premise has changed since, and Proposed readings no source of which is read in full, which need reading, not review.

The sections that must be empty are printed first, then the work in the order a pass takes it. The load-bearing ranking is printed last: once the record’s reliance flattened, it stopped ordering work (version 6). How a pass is run, from building the worklist to landing the pull request, is record/status-review/README.md.

Nothing is persisted between passes except the record itself, so record growth is absorbed by rerunning the script. Work in progress is the open pull request.

A pass reviews clusters, starting from the most relied-on. A cluster is a load-bearing entry, its premises the record does not hold, and its live objections. It is reviewed from the bottom up, because a claim cannot go Active over a Proposed premise. Each pass also takes whatever the other sections list for the entries it touches. A pass is sized to what a reviewer can read in one sitting: about five clusters.

Every claim has a route, interpretive ones included. An interpretive thesis is proposed for Active when four things hold:

  1. Every premise is Active.
  2. Each live objection is answered by an Active counter, or the thesis is narrowed to concede it.
  3. Nothing in the record meets its defeated_if.
  4. The owner assents.

The pull request is where the owner assents. It lists each interpretive status change separately, and merging it is the ruling. Demonstrated and empirical entries follow ADR-047’s evidence rulings, which stand unchanged:

  • a checked step-by-step re-derivation meets a request for a proof;
  • one study read in full suffices for a title that claims no more than it measured;
  • a narrowing’s dropped claims go to Proposed entries.

Relations are in scope. A pass decides each item it takes from the other sections:

  • An inversion is resolved by demoting the conclusion, promoting the premise, or changing the edge. A demonstrated conclusion that only borrows a framing from its premise is conditional, and it says so.
  • A retired premise moves to its successor, or the entry says why the old sense is meant.
  • An Open question with an Active answer becomes Answered, or gets a note saying what part is still open.

While reading a cluster, the reviewer also turns body citations that do the work of a premise or an objection into the matching field.

Reasoning lives on the entries. A status change carries a dated history note on the entry. An entry kept Proposed gets the blocker that holds it, stated as a missing result or an unanswered objection and not as “needs more evidence”, in a dated note in its body headed ## Note of YYYY-MM-DD: what holds it back. The heading is fixed because the worklist reads it. The pass as a whole, including what it looked at and left alone, is one workbench entry. There are no per-code decision files.

Owner rulings are a checklist in the pull request. A ruling the pass needs goes in the pull request description, one checkbox each, with the proposed answer already made in the diff where one exists. A ruling still open when the pull request merges is filed as a QUESTION. It is not left in prose.

Forcing functions: making the backlog visible to the lint

The owner asked, the same day, for rules in the luria configuration that would stop this backlog from forming again. The backlog was possible because of a blind spot, and the lint could have exposed it. The blind spot has three parts, each measured on the same tree:

  • The age signal could not fire. The record’s first commit is dated 2026-09-25, and luria.stale_days is unset, so it defaults to 90. No document in a record 32 days old can be 90 days old, so the pending-documents headline has never named one as stale. The report ranks 1,075 undecided documents by age and by raw citation count. It does not rank them by how much rests on them. This is DP-15’s absence reading as success.
  • Nothing measures reliance. “A lot depends on it” is a transitive count along rests_on, grounds, uses and presupposes. No report or warning class computes it, so the claims the owner asked about were invisible to every tool.
  • Nothing checks credence across an edge. Reference fields check that a target is present, resolves and is in force. “In force” counts Proposed as in force. So an Active claim resting on a Proposed one (49 edges), or an Open question with an Active answer (37), is no finding at all.

Proposed mechanisms, in the order they can be adopted:

  1. luria.stale_days: 14. This is configuration only, under luria 1.1.0. The headline starts counting stale documents at the record’s own pace, 611 commits in the week before this decision. It is a report, and it gates nothing.

  2. A field that says what holds a Proposed CLAIM back. It would be held_back_by, prose, required_when: {status: [Proposed]}, and it is configuration only. A THEORY already has promote_when. A CLAIM has defeated_if, which says what would sink it, but nothing says what would float it. The field moves the blocker from a ledger onto the entry, where the lint can ask for it. Adopting it means backfilling 278 Proposed CLAIMs, or rolling it out under a baseline.

  3. Pattern-backed warning classes (a luria change). patterns are already written in Cypher and checked against the schemes. Today they feed only chains and views. A pattern declared with report: true would make each match a row of its own warning class. That class is then acknowledgeable, mutable, and gateable by fail_on and baseline like any other. The three credence checks become configuration:

    patterns:
      inverted_premise:
        match: "(c:CLAIM {status: 'Active'})-[:rests_on]->(p:CLAIM {status: 'Proposed'})"
        report: true
      inverted_ground:
        match: "(c:CLAIM {status: 'Active'})-[:grounds]->(p:THEORY {status: 'Proposed'})"
        report: true
      answered_but_open:
        match: "(q:QUESTION {status: 'Open'})<-[:answers]-(c:CLAIM {status: 'Active'})"
        report: true

    This is the general mechanism: a blind spot found later becomes a pattern and a class, with no luria release. Under baseline, the count may fall and may not rise.

  4. Reliance in the pending report (a luria change). A luria.reliance list names the fields that carry dependence. The pending-documents table gains a column of transitive dependents and sorts by it. A load-bearing warning class names any undecided document with at least luria.load_bearing dependents (for example 5). worklist.py’s first section is the prototype, and it would retire once luria computes this.

  5. An acknowledged retired premise expires. The four claims that use Superseded TERMs (CLAIM-004, CLAIM-042, CLAIM-061 and CLAIM-064) are not unseen. Each carries an inactive-ok-file directive, “the definition current when this claim was written”. That is true, and it silenced the one finding that asked whether the claim still holds in the successor’s sense. luria’s directives already take until <date>, and the expired-directives class reports one that has lapsed. The rule is that a directive excusing a retired rests_on, grounds or uses target carries an until. As a convention this needs no change to luria. As a check it would be a luria change: a directive class that requires until.

What was adopted. On 2026-10-27 the owner said “go ahead with all the things, use your best judgement”:

  • Mechanism 1 is adopted with this decision.

  • Mechanism 2 is declined. Most of what holds a Proposed claim back is already in its graph: a premise not held, or a live objection. Mechanism 3 reports those from the source. A field that restated them would be a hand-kept projection of the graph and would drift (DP-3). This is the failure the old ledger’s decision files showed. The residue a graph cannot hold, such as a missing comparison or an unread source, goes in a dated note on the entry, as this decision’s first pass did.

  • Mechanisms 3, 4 and 5 are luria changes, in dmarx/luria#382. They are adopted here when a release carries them. As built:

    • a pattern declared report: true is its own warning class, named after the pattern and acknowledged with pattern-ok:;
    • reliance: adds a “Relied on” column to the pending report;
    • load_bearing: N adds the load-bearing class;
    • unbounded-acknowledgements names an inactive-ok with no until that excuses a retired premise.

    A match: holding a property map must be quoted in YAML. The example above is quoted for that reason.

    Adopted with luria 1.3.0, on 2026-10-28. On the first run, against this record:

    • The four credence patterns matched nothing, after the status reviews, and are in lint.fail_on. A new inversion fails unless a pattern-ok: in its first node’s document says why.
    • unbounded-acknowledgements counted 41, and is held at that lint.baseline, a count that may fall and may not rise.
    • load-bearing counted 38 at five dependents. It stays a warning, with the ranking in the pending report. Filing a claim on a Proposed premise is ordinary argument-building, so a ratchet on that count would fail pull requests for doing their work.
  • Mechanism 5 is also adopted now, as a convention. An inactive-ok directive that excuses a retired target held in rests_on, grounds or uses carries until <date>, no more than 30 days out.

Alternatives considered

  • Resume ADR-047’s queue. It holds 308 decided candidates and no pending ones. A new triage under its rubric would re-rank a record a third larger by evidence class, and that order puts the claims the owner asked about last.
  • Keep the ledger and add a reliance wave. This fixes the order but keeps the two costs that were measured: decision files that drift from the entries they judge, and a hand-maintained queue whose owner questions went unasked. ADR-047 rejected a derived queue because it “cannot record what is in progress or what to do next”. Under this decision the pull request records what is in progress, and the worklist, rerun, says what to do next.
  • Review in one pull request and promote in another. ADR-047 kept them apart so that a review could succeed with no status changed. That is still allowed: a pass may change nothing. But the separation cost about 140 pull requests over three days, and the five promotions that needed the owner were never put to the owner. A pull request that proposes the change and names the ruling puts both in front of the reviewer at once.
  • The curation journal for the pass narrative. Its blurb is why things entered or left the record. The workbench’s blurb is working sessions on the record’s own arguments, which is what a status review of claims is.

Consequences

  • No ledger can drift from the record, because there is no ledger. The cost is that a pass leaves no machine-readable disposition, so the next pass sees a retained claim only as still Proposed. The dated note in the entry’s body says why.
  • ADR-047 is Superseded. The owner accepted this decision on 2026-10-27. record/promotion-audit/ stays as the history of the first audit. Its five undone promotions and its open owner rulings are carried into the first pass under this decision, as rulings.
  • The worklist’s sections are fired once on a fixture record by record/status-review/test_worklist.py (DP-4).
  • Ranking by reliance favours entries that are cited, not entries that are important and new. A new thesis with no dependents yet does not surface here. The worklist is one input to choosing what to review, and it does not decide the choice.