Comment 27191 on #1543, correction 27192. Candidate afb2ae0e. Co-Authored-By: Claude Opus 5.5 <[email protected]>
11 KiB
Row 54, read-only console views, round 2 review (Darkwing)
Issue #1543, request comment 27187, packet comment 27188. Base
d64f434f. Candidate manifest sha256
afb2ae0e66e6388a35b4bedf915080d876a3d8576f79ae2ab660e81188a3a215, 14
files. The packet manifest and the checkout both check 14 OK, and
row54.patch applied at 6637bca5 gives the same 14 files. 6637bca5
is d64f434f plus queue revs 373 to 380, the round 1 review packets and
SESSIONS lines. None of those touch packages/.
Verdict: approve. Both round 1 blockers are fixed and tested. So are the D29, D20 and D21 test gaps, and the views.test :167 failure has a cause I can follow. Filbert's items that I could check from outside (After, the redactor, Required, the settings refusal) behave as stated on the real queue as well as on the fixture. Every suite is green. 40 of 45 mutants die; three new survivors are small test gaps, none blocking (notes 4 to 6).
Method
- Detached worktrees
papplyandmutwtat6637bca5withrow54.patchapplied and staged. Both check 14 OK.mutwtstill checks 14 OK after the mutant runs (r2/mut/manifest-after.txt). r2/gate.sh, the same gate as round 1: thepackages/webui,packages/queueandpackages/businessnode suites,build-tokens.mjs --check, then everyscripts/test-*.shwithDOCKER_HOST=unix:///nonexistent.sock, 21:18:07Z to 21:21:30Z. Thentest-releasewith Docker.- 45 mutants (
r2/mut/mutate.py,r2/mut/run.sh): my 31 from round 1, with D07 moved onto the new redactor, and 14 new ones (E01 to E14) on round 2's changes. Each runs against the fullpackages/webuisuite, D31 againstpackages/queue, 21:22:02Z to 22:07:37Z. - Node probes (
r2/probes/probe-r2.mjs, outputprobe-r2.txt): the round 1 redactor strings plus URL,~/and:shapes (Q1); the realqueue-read.mjsbeside a broken, missing or refusing store, and a broken or missingerrors.mjs(Q2); fake children that print a stack and exit 1 or 3, or refuse with a path (Q3); settings with no system config (Q4). - A sweep of the real queue (
r2/probes/probe-realq.mjs, outputprobe-realq.txt):/api/queueand every/api/queue/:idread for all 61 rows, with the candidate's reads rooted at the canonical checkout, because the store refuses a linked worktree.rows()writes nothing (decision 83). - Browser probes in Chromium through the candidate's
tests/browser.mjs(r2/probes/probe-browser-r2.test.mjs, outputprobe-browser-r2.txt): round 1's B1 to B4 on the seeded fixture, and B5 on real rows 8, 9, 35, 38, 47 and 54. - Read
row54-r1-to-r2.patchline by line, and Dewey's round 2 evidence.
Node v26.8.1, TMPDIR=~/darkwing-scratch/r54b/tmp. No tracker request.
Suites
| Suite | Result |
|---|---|
| packages/webui (node) | 39/0 |
| packages/queue (node) | 149/0 |
| packages/business (node) | 60/0 |
| build-tokens --check | rc 0, "tokens.css is current" |
| test-auth | 15/0 |
| test-conductor | 17/0 |
| test-config | 24/0 |
| test-discord | 66/0 |
| test-extension-package | 18/0 |
| test-foundation | 44/0 |
| test-queue | 27/0 |
| test-release | 4/0 without Docker, 14/0 with it |
| test-task, Docker unreachable | 26/0 |
As in round 1, I didn't run test-task with real Docker, because it makes live model calls.
Round 1 items
| Item | Result |
|---|---|
| Required 1, Arbiters | Fixed. B1 on the seeded fixture: the API gives {"delivery":"pm","technical":"cto"} and the page shows "pm (delivery), cto (technical)". The seeded views test asserts that line. E07 (back to names()) dies |
| Required 2, import leak | Fixed, both ways I suggested. Q2: a store with a syntax error, a missing store, a missing or broken errors.mjs, a store that throws a plain error at load, and rows() throwing all give read-failed "the queue read failed (exit 1)", with no base path. Q3: exit 1 and exit 3 with a file:// stack give the fixed message. E01 (static imports) and E02 (forward any exit) die |
| D29 mirror focus | Test added. D29 dies |
| D20 output cap, D21 timeout | Tests added. Both die |
D22 host state .live |
No test, follow-up. Still survives |
| :167 | Explained (below) |
Note 4, GROUPS =[[ |
Fixed |
A store that refuses at load with exit 2 still has its message forwarded,
which is right: that text is the store's own. Q2 load-refusal-2 throws
a QueueError with an absolute path and a file:// URL in it, and both
come out as <path> and file:<path>.
The :167 account holds together. With reads and no bus, the palette's
/api/bus/inbox and /api/bus/tasks reads answer 503 not-configured,
which is a refusal, and row 53's rule forgets every read on a refusal,
api:queue included. Whether the queue rows were listed then depended on
which finished first. Dewey's views-no-bus mutant drops the test's stub
bus and dies at that check, which is the evidence I'd want. In round 1,
D06, D07 and D09 also timed out at :167, though D07 and D09 can't reach
that test. A race explains that and a timeout didn't. The product
question Dewey raises, whether
not-configured on a bus route should forget the queue read, belongs to
Sage and row 53, and I agree it isn't row 54's to change.
Filbert's items, checked from outside
I didn't review these as Filbert's reviewer; I checked what my probes reach.
| Item | Result |
|---|---|
| B1, After | B5 on real rows: row 38 shows "36 done, 37 done" and row 54 "53 done", each id a link. E08 and E14 die |
| R1, redactor | Q1 below. Over all 61 real rows the reads carry no /home/, /mnt/, ~/, file: or user name; rows 8, 35 and 47 carry <path> where their notes had ~/ paths, and B5 shows the same on their pages |
| N1, settings with no system config | Q4: not-configured, "the Console has no system config, so it knows no notifier config". E11 dies |
| N2, Required | B5 row 9: "yes since 2026-09-13" (27 d ago). E09 dies; E10 survives, note 4 |
Probes
| Probe | Candidate |
|---|---|
| Q1 redactor | config:/…, file:/…, file:///…, ~/…, key=~/k, see:~/x, `~/.mosaic` and </…> become <path>. https://, ssh://, http://127.0.0.1:3773/x/y, git@host:org/repo.git, origin/refactor, a~/b, ~ and ~user/x are unchanged. ./…, Windows paths and id_<digits> are unchanged, as in round 1. Notes 1 and 2 |
| Q2 import and load failures | all seven cases: fixed read-failed or the store's refusal, no base path |
| Q3 fake children | exit 1 and 3 fixed; exit 2 forwards with file:<path> and <path>; exit 2 silent gives "the queue refused the read" |
| Q4 settings, no system config | no business: "knows no business"; --business acme: "knows no notifier config". Both not-configured |
| Q5 real queue sweep | 61 rows; no absolute or ~/ path in the list or any row |
| B1 Arbiters | "pm (delivery), cto (technical)" |
| B2 mirror focus | kept on palette and mode; a mirror change moves the command bar |
| B3 H1 focus | kept |
| B4 navigation | one refresh due after it, as in round 1 |
| B5 real rows | After, Required and Note as in the table above; the last page's text has no /home/ or ~/ |
Mutants
40 of 45 killed (r2/mut/summary.txt). I checked each kill site in its
output against its diff, and each one fails at the assertion meant for
it. The round 1 mutants not in the table die at the same assertions as in
round 1, at the current line numbers.
| Mutant | Change | Result |
|---|---|---|
| D14 | role vars not allowlisted | survived, equivalent as in round 1 |
| D20 | no output cap | killed, "the queue read printed too much", reads.test.mjs:105 |
| D21 | timeout times 1000 | killed by the test's own 60 s timeout, reads.test.mjs:87 |
| D22 | host state without .live |
survived, the follow-up |
| D29 | keep() without the mirror |
killed, "the refresh keeps focus on the mirror select", views.test.mjs:198 |
| E01 | static imports in queue-read.mjs |
killed, the child's output, reads.test.mjs:93 |
| E02 | non-2 exit forwards the child's stderr | killed, the 503 body, reads.test.mjs:97 |
| E03 | redactor without the : prefix |
killed, redactor test reads.test.mjs:31 and the seeded page check |
| E04 | : prefix without the URL lookahead |
killed, reads.test.mjs:25 and the business read at :116 |
| E05 | no ~? |
killed, reads.test.mjs:29 and the seeded page check |
| E06 | no < prefix |
killed, reads.test.mjs:31 |
| E07 | Arbiters back to names() |
killed, views.test.mjs:169 and :228 |
| E08 | After back to qLink |
killed, views.test.mjs:219 |
| E09 | Required shows the raw value | killed, views.test.mjs:220 |
| E10 | "since" on any truthy requiredSince |
survived. Note 4 |
| E11 | no notifier dataRoot check |
killed, reads.test.mjs:197 |
| E12 | instanceof without the null check |
survived. Note 5 |
| E13 | Arbiters without || none |
survived. Note 6 |
| E14 | After without when |
killed, views.test.mjs:219 |
mutwt checks 14 OK after the run (r2/mut/manifest-after.txt). The
browser probe ran during D01 and D02, and both died at their own
assertions (views.test.mjs:158 and :103), so the extra load didn't
make a false kill.
Notes (not blocking)
file://localhost/home/u/xpasses through, because a:followed by//and a host reads as a URL. Node writesfile:///…with an empty host, which is redacted, so I don't see a way for this to reach a page today. The README's rule describes it.path</home/u/x>becomespath<<path>>, andhttp://alone becomeshttp:<path>. Both are cosmetic.- D22 stays untested, as Dewey says. P5c in round 1 showed the read works.
- E10. The store allows
requiredSince: "unknown"on a required row (checkTimewithunknown: true,queue.mjs:330). The candidate shows "yes" for it, and the mutant would show "yes since" with a<time>around "unknown". No real row has it today (all 5 required rows carry a date), and the test atviews.test.mjs:220accepts both forms. A seeded"unknown"row would pin it. - E12. With
errors.mjsmissing, the mutant child throws a TypeError inside itscatchand prints Node's stack,file://path included, exit 1 (r2/probes/e12-check.sh, outpute12-check.txt).reads.mjsdrops stderr on exit 1, so the API answer is the same and the mutant is equivalent there. The child's own contract isn't: the load-failure test breaks onlystore.mjs, and adding a missingerrors.mjscase to that loop would kill it. - E13. An empty
arbitersobject would give an empty Arbiters cell instead of "none". Cosmetic, and no test seeds one.
Files
r2/candidate-manifest.sha256: copy of Dewey's.r2/gate.sh,r2/out/: suite runs,summary.txtandtest-release-docker.txt.r2/mut/: mutant definitions, runner, diffs, outputs,summary.txtandmanifest-after.txt.r2/probes/: the three probes, the E12 check, and their output.