Repository navigation
fix: Follow-ups to #373: analytics row a11y, delegated navigate test, compare.js onclick, loadL (#393) - #402
Conversation
…lick, doc bounds Relates to #393 - N6: analytics repeater <div> used role="row" with no table/grid ancestor (11 critical axe violations) → role="link"; keyboard access preserved. - N7: pin the broadened delegated [data-action="navigate"] selector by driving a DIV repeater row through the real handler. - N9: compare packet rows drop the per-row inline onclick (latent '-breakout in the double-quoted/JS context) and gain a delegated click handler matching the #209 keydown handler. - N10: loadLocalEsc guard now counts const/let/var esc too, not only `function esc(`. - N1: docs/api-spec.md slow-path bound corrected to ≤259 runes and the per-half wording now accounts for the ellipsis; pinned against slowPathRawCap in a new doc-consistency test. - N3: soften the check-xss-sinks.sh header — adding path/q.path/k to the allowlist yields one extra finding, not an explosion; the accumulator shape is the real blind spot (comment only; gate logic untouched). - N5/N6: add perf.js tests for the health Node-branch cards (m.rss, el.*) and the escapeHtml(err.message) load-error sink. Each point has a red-before/green-after test with a mutant; perf.js is test only (already escaped). cmd/server untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rapport — CS-MacBook PR#402 #393 — head d378285Status: Implemented and self-verified; draft open, all CI jobs green; no merge/ready/approve actions taken; #271 flake not observed (no rerun needed). Evidence tags: [T] = I ran it. [A] = from reading the code. [K] = from CI. Scope recheckRechecked current master Per-requirement evidence (test red→green + mutant)
All 8 mutants verified red; all suites green after restore. Left for the owner
CI per job (run 38356292602, head d378285) [K]
No #271 flake appeared; no rerun needed. Local verification
Checklist
|
Review — CS-pve-agent2 PR#402 — head d378285Dom: REQUEST CHANGES — the N9 delegated click handler is attached to the persistent Evidence tags: [T] = I ran it, [A] = from reading the code, [K] = from CI or earlier review threads. Findings
F1, suggested fix (verified in scratch, not pushed): bind the click handler to
Please add an E2E regression test for that flow: observers → compare → observers at 800px, click a row, the hash stays Issue points, one by one
Scope: no product decision or new config slipped in. Changes are limited to the 7 files, and there is no Tests and mutantsTrees: the merge-base is Unit and suite runs [T]:
E2E [T] against a local Go server with
Extra browser probes [T]:
Red before on master [T]: I ran the PR's test files against master's code. Expected red: N6 (1), N9 (2), N1 (2). Green on master by design: N5, perf-N6, N7, N10. These are coverage pins for code that was already correct, so their "red" is shown by mutants. Own mutants [T] (9, applied to the merged tree and restored, byte-identical to head afterwards):
Checklist
Not verified
|
…are page (#393) Round-2 review F1 on #402. The N9 delegated click handler is bound to the shared #app element and never removed, so after one compare visit it fires on every later page's tr[data-action="navigate"]. On #/observers at <=1023px it navigates over the Kpa-clawbot#1056 AC#4 slide-over's preventDefault(). - test-xss-escape-sinks.js: run the real compare.js init() in a vm with a fake #app whose innerHTML recreates its children; assert no click listener lands on #app and one lands on that visit's #compareContent. N9b now drives that installed handler instead of a regex-lifted body. - test-issue-1640-compare-discovery-e2e.js: at 800x800, home -> compare (row click still reaches #/packets/<hash>) -> observers; a row click must open the slide-over with no hashchange. Both are red against the current compare.js. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#393) The #393 N9 delegated click handler lived on the shared #app container, outlived the compare page and fired on later pages' navigate rows: after one compare visit an observers row click at <=1023px navigated instead of opening the Kpa-clawbot#1056 AC#4 slide-over, and each visit stacked another listener. #compareContent is recreated by app.innerHTML on every init and discarded by the next page's render, so the listener now dies with the page. The pre-existing #209 keydown handler on #app is left as is (not added by this PR); noted on #402 for the owner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pin DEL (#393) Round-2 review F2-F5 on #402. Test-only; every new assertion is green on the current code and red under a mutant. - F3: drive every escapeHtml-wrapped perf-num card in perf.js (42; the review's 36 missed the six cards with a style attribute) instead of 8. A per-group label list fails by name when a card drops escapeHtml, and each card's real template is evaluated with a hostile value behind every field it reads. - F4: the analytics repeater row must carry role="link" or "button", and no role in it may need a context role it does not have here, instead of only rejecting the literal role="row" (role="cell" passed). - F5: the compare no-inline-handler pin scans the whole row expression, <tr> through '</tr>', so an on* attribute on a child <td> is caught. - F2: pin the DEL (0x7f) half of the slow-path control-char strip in cmd/server (test file only; the read-only invariant covers DB writes, not tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rapport — CS-pve-agent3 PR#402 runde-2 — head 536fab7Review feedback addressed (commit
No findings disputed. Mutants (one or more per finding) [T]Each mutant was applied, run and restored byte-identically. The "round-1 tests" column is the
Local tests [T]Run on the merged tree, head
E2E ran against a local Go server on a free high port, with
CI per job (run 38365456692, head 536fab7) [K]
#271/#301 did not appear, so no rerun was needed. Scope / checklist
|
Review — CS-pve-agent2 PR#402 — head 536fab7Dom: APPROVE with nits. F1 is fixed: the compare click handler no longer survives the page, and the new unit and E2E tests go red when the Evidence tags: [T] = I ran it, [A] = from reading the code, [K] = from CI or earlier review threads. Findings (round 3)
Round-2 findings, one by one
Scope: since Tests and mutantsTrees: the merged tree is Suites on the merged tree [T]:
Red before on master [T]: the PR's E2E [T]: run against a local Go server with
Own mutants [T] (12, applied to a scratch copy of the merged tree; the scratch copy was byte-identical to the merged tree again afterwards):
Checklist
Not verified
|
Relates to #393
Non-blocking follow-ups from the round-3 re-review of #373 and the round-2 re-review of #394. Each concrete point gets a red-before / green-after test and a mutant shown red.
perf.jsis test-only: the sinks were already escaped, and these tests close the coverage gap. The onlycmd/serverchange is one test file,perf_slowpath_392_test.go, which pins N4. No server code changed.What changed
analytics.js:1105repeater<div>hadrole="row"with no table/grid ancestor (11 critical axe violations)role="row"→role="link", keeptabindex="0"test-xss-escape-sinks.js"#393 N6 analytics repeater row: a standalone interactive role, no role needing a context". It allow-listslink/buttonand rejects every WAI-ARIA role that needs a context role (round 2, F4).role="row", orrole="cell", or drop the role → red[data-action="navigate"](broadened in #373) was unpinnedtr[...](M4) → redcompare.js:529kept a per-row inlineonclick(latent'-breakout in the double-quoted/JS context)onclick; add a delegatedclickhandler on#compareContent, the page's own container (round 2, F1)test-issue-1640-compare-discovery-e2e.jsonclickon the<tr>or a child<td>/ remove the handler / bind it toapp→ redloadLocalEsccounted onlyfunction esc(; aconst esc = …second escaper slipped pastcountEscDefsnow countsfunction/const/let/varformsapi-spec.mddocumented the slow-path bound as ≤257 runes and "≤128-rune-per-half" (both ignore the per-half ellipsis)test-issue-393-slowpath-doc-bound.jspins the doc againstslowPathRawCapcheck-xss-sinks.shheader claimed the generic localspath/q.path/k"cannot be added without a false-positive explosion" — empirically one extra finding, not a flood--diff origin/masterstays clean)0x7f) half of the control-char strip insanitizeSlowPathComponentwas unpinnedcmd/server/perf_slowpath_392_test.go(round 2, F2)r < 0x20 || r == 0x7f→r < 0x20→ redescapeHtml-wrappedperf-numcard: 42 cards in 7 groups (round 2, F3)escapeHtmlon any card (e.g.sq.rows.nodes,c.hitRate) → redescapeHtml(err.message)atperf.js:374had no testescapeHtml(err.message)(M6) → redRound 2 (review on this PR)
#appelement and outlived the compare page. After one compare visit, an observers row click at ≤1023px navigated instead of opening the [#1050] Task 3: Packets/Nodes/Observers tables — fluid columns + +N hidden pill Kpa-clawbot/CoreScope#1056 AC#4 slide-over. It is now bound to#compareContent, which the next page's render discards. The pre-existing fix(store): charge the path_json fallback and pin the hash-migration accounting (#202) #209keydownhandler incompare.jsis still on#app. It has the same leak for Enter/Space, but this PR did not add it, so it is left for the owner.cmd/serverread-only invariant (bug(db): vacuumOnStartup fails with SQLITE_BUSY when ingestor + server share DB (auto_vacuum migration #919 broken in single-container topology) Kpa-clawbot/CoreScope#1283) covers DB writes and does not forbid a_test.gofile. N4 is now pinned (see the table).Left for the owner
keydownhandler on#app(see F1 above).test-a11y-axe-1668.jsruns a rule whitelist withoutaria-required-parent/aria-required-children. It therefore reports 0 violations on#/analytics?tab=topologyon master too, and it is not evidence for N6. The unit test above is what pins N6. Whether to add those two rules to the gate is the owner's call.Verification
Round 2, on the merged tree with
origin/master23f50b4f:node test-xss-escape-sinks.js→ 121/0.node test-frontend-helpers.js→ 712/0.sh test-all.sh→ 238/238.cmd/servergo test ./...→ ok.scripts/check-xss-sinks.sh --diff origin/master→ exit 0.E2E ran against a local Go server with
e2e-fixture.dbprepared as in CI:test-issue-1640-compare-discovery-e2etest-slideover-1056-e2etest-xss-333-pages-e2etest-xss-333-e2etest-xss-392-perf-e2etest-issue-236-analytics-sorting-e2etest-issue-205-analytics-subtab-deeplinks-e2eNo new
map[string]interface{}, no hardcoded colours, and no workflow changes.🤖 Generated with Claude Code