Uh oh!
There was an error while loading. Please reload this page.
tooling(qa): roll-up view over qa-run records — selector, latest verdict, staleness - #9616
Merged
Conversation
…dict × staleness Answers "what is the latest verdict for every checklist selector, and is it stale?" in one command, replacing a 23-issue manual read. A generated VIEW, not a tracker: no cache, no snapshot, no last-run file. The qa-run issues stay the only source of truth. Three things were measured over the live corpus rather than assumed, and each changed the design: - The title convention has drifted. Neither the documented form (.claude/skills/checklist-test/SKILL.md) nor the form described in the card is what any record writes: 23/23 use five ·-separated fields with the judged/total folded into a parenthetical on the selector, in five distinct phrasings, absent entirely on one record. The parser accepts the shape the records actually have and PRINTS anything it cannot parse. - The bodies are not one shape and are deliberately not parsed. 9 of 23 records carry no markdown table at all; the other 14 carry 26 distinct header shapes, and most of those tables are clause-level rather than item-level — they use the word "verdict" for a different unit. Counting them as items would produce a confidently wrong matrix. The view says, every run, that it did not read them. - Staleness is three-valued because a shallow clone cannot always tell. merge-base --is-ancestor answers false for commits behind the graft boundary, so a boolean would have rendered the nine stalest records as fresh. "Could not tell" renders as ? and is never counted as fresh. Reads REST core only (1 call for the whole corpus, 15000/hr quota) — not the search API and not GraphQL. --self-test drives the pure core over fixtures taken from the real corpus: 60 assertions, no network. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
os-steve
marked this pull request as ready for review
August 18, 2026 13:45
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#9486
Adds
scripts/qa/qa-rollup.mjs— one command that answers "what is the latest verdict for every checklist selector, and is it stale?", replacing a 23-issue manual read.It is a generated view, not a tracker: no cache, no checked-in snapshot, no last-run file. It reads the API, prints the matrix, and exits. Verified — after a full run
git statusshows nothing new. Theqa-runissues stay the only source of truth.Three assumptions were measured, not inherited — each one changed the design
1. The title convention is not followed by anything. Three conventions are in play, and the records follow none of the documented ones:
.claude/skills/checklist-test/SKILL.mdThat parenthetical appears in five distinct phrasings (
18/18,77 items,FULL area,6/14 items consulted,5 of 10 items) and is absent entirely on one record. The parser accepts the shape the records have; anything it cannot parse is printed in a "Not parsed" section, never dropped. A roll-up that silently omits records is the "derived list read as authoritative" defect this repo has paid for repeatedly (#9294, #9331, #9503, #9590). Today that section reads "none" — all 23 parse.2. The bodies do not have one shape, so they are deliberately not parsed. Measured across the corpus: 9 of 23 records carry no markdown table at all (the 2026-08-11 wave is prose with
## PASS — 4 itemsheadings); the other 14 carry 26 distinct table header shapes. Worse than heterogeneous — most are clause-level, not item-level (clause / verdict / oracle evidenceappears 38 times). They use the word "verdict" for a different unit, so a parser that greps verdict cells counts clauses and reports them as items: a confidently wrong matrix, which is worse than no matrix.So the script reads the field that is actually a contract — the title's own counts, authored by the person who ran the tests — and the output states, every run, that it did not read the bodies. Nobody can mistake this view for a body-derived one.
3. Staleness is three-valued, because a shallow clone cannot always tell.
git merge-base --is-ancestorneeds the sha present with history behind it. This container clones shallow (graft boundary713ccbc95, 2026-08-16), and the92f26f75wave predates it — so--is-ancestoranswers false for commits that almost certainly are ancestors. Reading that as "not behind, therefore fresh" would have rendered the nine stalest records in the corpus as fresh, silently. Freshness is thereforecurrent/stale/unknown, withunknowncarrying its reason (shallow/unreachable/diverged) and rendering as?. "Could not tell" is never counted as fresh.Rate limit (the card's untested assumption). Measured: REST core, 1 call for the whole 23-record corpus, against a 15000/hr quota (14967 remaining at the time). Deliberately not the search API (30/min) and not GraphQL, whose quota was measurably under pressure (2699/5000 remaining) while this was written. Comments are never fetched, because bodies are not parsed.
What the view surfaces today
Real signals visible in the first run, none of which any current view shows:
ai,attachments-storage,cli,i18n,search) have no verdict newer than 2026-08-11, and honestly render? shallowrather than a fabricated freshness.dashboards(10 items) has never been run — an area in the checklist that no record names. Reported as absence of a verdict, not as a verdict of NOT-RUN.records-formsis titled "(FULL area)" but judged 13 of 33 items, rendered13/33*. The*marks a denominator taken from the checklist rather than claimed by the record — the two provenances are kept visually distinct precisely so this gap is legible instead of reassuring.—, never0. A record that did not declare NOT-RUN has not declared zero of them.Notes for review
package.jsonentry, on purpose. The card asks for a view, not a gate; wiring one would expand the verification surface and touch a file two open PRs hold. I checked the conflict factually, as dispatched: ci: at most one open PR may modify a declared single-writer path #9598 adds one line to the samescriptsblock, chore(deps)(deps-dev): bump the development-dependencies group across 1 directory with 11 updates #9466 bumps devDependencies there. ci: at most one open PR may modify a declared single-writer path #9598 introduces a single-writer-path guard, but its declared list contains only.objectui-sha— rootpackage.jsonis not declared, so that gate would not have blocked this. The decision is scope discipline, not the guard. Wiring--self-testas acheck:*family once ci: at most one open PR may modify a declared single-writer path #9598/chore(deps)(deps-dev): bump the development-dependencies group across 1 directory with 11 updates #9466 land is a clean follow-up..claude/skills/checklist-test/SKILL.md:126no longer matches what any record writes. That file is human-merge-only, so this is reported, not edited.skip-changeset: this PR adds one repo-internal tooling script and publishes nothing.Gates
Run after the final commit, all green at
506c30962:Reverse-verified against real data: re-running with
--target e4e5c6e3flips the 14 rows measured on that sha fromSTALE (122 behind)tocurrent, while the 5 shallow-unknown rows correctly stay?— confirming the freshness column reads live git ancestry rather than a fixed label.Generated by Claude Code