From 960988bae228823b5f2fd7f6fcf15e6e839cfe35 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Wed, 14 Oct 2026 10:54:59 -0500 Subject: [PATCH] docs: brief for the ledger reasoning-row and issue-page fix (#1607) Two fail-closed refusals stop every full weekly ledger run: T3's new role 'reasoning' summary rows, and more than 50 issues updated since the week's start. Owner darkwing after row 112, reviewer filbert. Co-Authored-By: Claude Opus 5.5 --- ...-10-14_ledger-reasoning-and-issue-pages.md | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 docs/plans/2026-10-14_ledger-reasoning-and-issue-pages.md diff --git a/docs/plans/2026-10-14_ledger-reasoning-and-issue-pages.md b/docs/plans/2026-10-14_ledger-reasoning-and-issue-pages.md new file mode 100644 index 000000000..282daa2a3 --- /dev/null +++ b/docs/plans/2026-10-14_ledger-reasoning-and-issue-pages.md @@ -0,0 +1,102 @@ +# Ledger reads current T3 and a busy week's issues (2026-10-14) + +Filed by Sage while running row 7's overdue week (2026-10-04 through +2026-10-10). Gitea #1607. Row 7 and row 13's Monday-run gate both wait +on this. + +## The weekly ledger runs on current T3 and a week with more than 50 updated issues + +### Problem + +Two refusals stop every full weekly run today. Each one is a fail-closed +check doing its job, so the fix is to the checks, not to the run. + +1. T3 messages with role `reasoning`. Since 2026-10-13T14:01Z, T3 stores + reasoning summaries in `projection_thread_messages` with role + `reasoning` and ids starting `reasoning:summary:` (2,975 rows on + 2026-10-14; every one has that id prefix). `packages/ledger/src/t3.mjs:97` + refuses any role other than `user` or `assistant`, so the run exits 1 + with `T3 message reasoning:summary:… has an unknown role`. `--no-t3` + is the only way past it, and that drops the seat table and the human + message count. +2. More than 50 issues updated since the start date. + `packages/ledger/src/ledger.mjs:46-68` reads one page of 50 and refuses + a full page (exit 2). The query is updated-since with no upper bound, on + purpose, so a close in range isn't hidden by a later update. That also + means `--until` can't narrow it. On 2026-10-14 the week from 2026-10-04 + matched 132 issues (pages of 50, 50 and 32). `--no-issues` is the only + way past it, and that leaves issues closed, median hours open and human + messages per closed issue unknown. + +The one-page rule came from the 2026-09-12 ledger brief (#1506, BUILD-LOG +"Single-request constraint"). It was there to stop silent partial totals, +not to save calls. Sage, as lead, replaces it here with a bounded page +loop that still refuses rather than guessing. The tradeoff is up to 10 GET +calls per run instead of 1. + +### Owner and reviewer + +- Owner: darkwing, after row 112. +- Reviewer: filbert (decision 130, not a sandbox row). + +### Files owned + +- `packages/ledger/src/t3.mjs` +- `packages/ledger/src/ledger.mjs` +- `packages/ledger/src/cli.mjs`, only if the coverage line or excluded + counts print there +- `packages/ledger/tests/` (changed or new tests and fixtures) +- `packages/ledger/README.md` + +### What ships + +1. T3 reasoning summaries are skipped, not refused: + - A message with role `reasoning` whose id starts `reasoning:` is not + counted anywhere, and the report shows how many were skipped next to + the imported and deleted thread counts. + - Role `reasoning` with any other id prefix still refuses, and so does + any other role that isn't `user` or `assistant`. + - Skipping happens before the text, `created_at` and header checks, so + a summary's content can't refuse or change a run. +2. Issues are read in pages, with a hard ceiling: + - Same query as today (all states, type issues, updated since the + start, limit 50), pages 1, 2, 3 and so on, stopping at the first page + with fewer than 50 rows. + - At most 10 pages. If page 10 is full, refuse with exit 2 and say the + ceiling was reached; never report partial totals. + - Every page gets today's record checks. A duplicate issue number + across pages refuses with exit 2, since an update during the read can + shift rows between pages. + - Any failed page refuses the whole read with today's error text rules, + with no stderr or response body echoed. + - The report says how many pages it read. +3. README: the T3 section names the `reasoning` skip and the remaining + refusals. "Gitea calls and missing evidence" describes the page loop, + the 10-page ceiling and the duplicate refusal, and drops "one-call + boundary" and "not hidden pagination". +4. Tests, offline with fixtures as today: + - A T3 fixture with a `reasoning:summary:` row counts the same as one + without it, and reports one skipped. + - Role `reasoning` with id `x-1` refuses, and so does role `system`. + - A fake gitea tool serving pages of 50, 50 and 7 yields 107 issues and + 3 pages. 10 full pages refuse. A duplicate across pages refuses. A + failing page 2 refuses. + - A mutant that drops the id prefix check, and one that stops after + page 1, each fail a test. Record both in the packet. +5. Suites: every package suite and every `scripts/test-*.sh` on the packet + gate. + +### Out of scope + +- The open-issue list in `queue-checks.mjs` (`OPEN_LIMIT`, its `full` + flag). It reports rather than refuses; it's a separate row if it matters. +- Row 32's guideposts. That row stays parked. +- Running the week. Sage reruns 2026-10-04 through 2026-10-10 after + landing and posts it on #1508 under row 7. + +### Gate + +Filbert approves on the issue, naming the candidate manifest. Sage reruns +the full gate at the landing target. No live service runs this code, so +there are no Mos notices and no restart. After landing, Sage runs the week +without `--no-issues` or `--no-t3` and exits 0.