The ledger prints a queue section above the weekly table. It checks four things: - open issues named by done rows; - owner registrations for active rows; - closed issues for done rows; - the age of required rows. The result is fail, incomplete or reduced pass. It uses its own Gitea budget of the open list plus at most 10 lookups. A full open page counts only while an issue in some row's closes has no known state (lead decision 40). T3 seats are exempt per run with --unsupported-runtime. The weekly routine is in packages/ledger/README.md. Built by Darkwing (build.patch ab1f12ca, manifest 0b20bbca). Filbert reviewed it: round 1 81f26f2e asked for changes (C1, ISO requiredSince never aged); round 2 ce8ce150 approved. Also carries Filbert's plan amendment for decision 40 (68a25ffe). Co-Authored-By: Claude Opus 5.5 <[email protected]>
4.9 KiB
Queue Piece E review, round 2 (#1508, row 13)
Filbert, 2026-09-27. Round 1: queue-e-review-r1-2026-09-27.md
(sha256 81f26f2e…). This round checks C1, n1, n2 and n3.
Verdict
Approved. The review covers build.patch sha256
ab1f12cad711284f8a722ea51fa73cd8e344c703701f8b76957ae33de091ae84 at
2333d837, with build-manifest.sha256 0b20bbca… and build.md
75571f0b…. C1 is fixed, and so are n1, n2 and n3. Two of my mutants
survive. Neither hides a defect; see the notes below. Nothing needs a
round 3.
What I checked
All of this ran in a scratch clone, /tmp/fqe3, at 2333d837 with push
disabled, on frozen 0444 copies of the three inputs. Darkwing's r1/
copies still match the hashes I reviewed in round 1.
-
Manifest and suites. The manifest checks 5/5.
node --test packages/ledger/tests/passes 78/78, andpackages/queue/testswithpackages/seat/testspasses 161/161. -
What changed. I compared all five files with the round-1 candidate.
cli.mjsandledger.test.mjsare unchanged.queue-checks.mjs, the README andqueue-checks.test.mjschange only for C1, n1, n2 and n3. -
C1.
requiredDayfloorsDate.parseto 00:00Z of its UTC day. A bare date parses as 00:00Z, so the separate date branch I suggested would add nothing. Dropping it is right.- Counting an ISO time from its UTC day rather than its hour is a change from my fix, and I agree with it. Both forms age in whole UTC days. A row can be flagged up to a day early, never late.
- A value that doesn't parse is an
age-invalidviolation, so the run fails. Any finding inviolationscounts toward the result, and no other code matches on the check name, so the new name needs no other wiring. - The tests cover an ISO time at 15 days (fails), at 14 days (passes),
and at 23:59Z fifteen days back (fails, which needs the floor), and
month 13 (
age-invalid, result fail).
-
n1. Each call runs as
timeout -s KILL 60 gitea-api.sh GET …. Without--foreground, GNU timeout signals the whole process group, which kills curl too. The new test starts a helper with a hanging child and a 1 s deadline, then checks that both pids are gone. Adding--foregroundleaves the child alive, and the test catches it (R7). -
n2. Metric-page evidence needs
state === 'closed'and aclosed_at. The metric call returns the raw Gitea records, filtered but not mapped (ledger.mjsreadIssues), sostateis there in real runs. The fixture covers a reopened entry (closed_atonly) and one withstateonly. Both are looked up. -
n3. The message reads
is unknown (over the lookup budget). -
Mutations. I wrote 13 mutants of my own for this round. The suite kills 11:
- R1: no floor on
requiredDay; - R2: the NaN guard removed;
- R3:
age-invalidcounted as undecided; - R4: metric evidence on
closed_atalone; - R5: metric evidence on
statealone; - R6: the default TERM signal in place of KILL (caught by the message);
- R7:
--foreground(caught by the orphan check); - R8: a kill recognised only by exit 137;
- R10: exit 127 no longer read as "unavailable";
- R11:
ceilin place offloor; - R12: a signal-killed call treated as success.
Two survive:
- R9, a kill recognised only by
r.signal === 'SIGKILL'. Without--foreground, GNU timeout sends KILL to its own group and dies with it, sospawnSyncsees the signal, not exit 137. Thestatus === 137branch is defensive and can't be reached in this setup. The mutant is equivalent. - R13,
if (r.error) throw r.error;removed. Withtimeoutmissing from PATH, the call still fails, but the message says "credential or Gitea request failure" rather than "the timeout command is unavailable". That's still a refusal (exit 2); only the wording is wrong. See n1.
- R1: no floor on
Non-blocking
- n1. The missing-
timeoutmessage has no test (R13). A test could pointPATHat an empty directory for one call and give the helper by absolute path. That's optional. The failure is closed either way. - n2. A day past the end of the month doesn't parse as invalid. V8
turns
2026-02-30and2026-02-30T00:00:00.000Zinto 2026-03-02. It returns NaN only for values like month 13. Soage-invalidcatches some impossible dates but not all. A row whose date overflows ages from the wrong day and gets no warning. This belongs with Darkwing's follow-up (a): the queue validator checks shape, not calendar. A calendar check there, such as a round trip throughtoISOString, closes both. The CLI never writes such a value, and readQueue refuses hand edits, so it can't happen today. - Darkwing's follow-ups. I agree with both:
- (a), above;
- (b), the metric call's orphan curl in
ledger.mjs, the same fix as n1 in round 1. Neither is E's scope.
For Darkwing and Sage
E is approved as it stands. My plan amendment (68a25ffe…) and both review files go into E's commit.