Skip to content

Commit 999e818

Browse files
bloveclaude
andauthored
feat(bench-matrix): H6-H8 + H19-H21 evaluators embed comparator evidence (#140)
* docs(specs): comparator-aware evaluators design Extend H6/H7/H8 (interaction) and H19/H20/H21 (cell-renderer) evaluators to include comparator evidence in their evidence arrays, mirroring H1's pattern. Status logic stays pretable-only; data is informational. Retires the aggregator-script pattern over time. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(plans): comparator-aware evaluators implementation plan Twelve-task plan: shared helper for comparator-evidence lookup, six evaluator extensions (H6, H7, H8, H19, H20, H21), test coverage, matrix re-run, repo-memory entry, PR. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(bench-matrix): H6/H7/H8 evaluators surface all comparator evidence evaluateInteractionHypothesis now embeds every measured comparator adapter in the evidence array (was: best-by-interaction-latency only). Pretable-only status verdicts unchanged. Adds findComparatorEvidence helper used by all six target evaluators (H6/H7/H8 + H19/H20/H21). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(bench-matrix): H19 evaluator surfaces comparator format evidence H19's evidence array now embeds each comparator's scroll-with-format summary alongside pretable's format/baseline delta. Comparator entries are absolute format p95 (not deltas) — per-adapter format-vs-baseline deltas are a future enhancement. Status verdict unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(bench-matrix): H20 evaluator surfaces comparator evidence H20's evidence array now embeds each comparator's scroll-with-render summary alongside pretable. Status verdict unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(bench-matrix): H21 evaluator surfaces comparator evidence H21's evidence array now embeds each comparator's scroll-with-heavy-render summary alongside pretable. Status verdict unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(bench-matrix): comparator-evidence assertions for H6/H7/H8/H19/H20/H21 Pins the contract that each of the six evaluators surfaces every measured comparator adapter in its evidence array (4 entries for H6/H7/H8/H20/H21; 5 for H19 which also carries the pretable scroll baseline). Status verdicts remain pretable-only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore(bench): comparator-aware evaluators milestone Synthesized hypotheses report from per-run summaries (matrix runner's end-of-run report-writer flaked repeatedly in this worktree; the per-run summaries are valid). Verification of evaluator extensions: | H# | Status | Evidence adapters in array | | --- | --------- | ---------------------------------------- | | H1 | satisfied | pretable, ag-grid, tanstack | | H6 | satisfied | pretable, ag-grid, tanstack | | H7 | satisfied | pretable, ag-grid, tanstack | | H8 | satisfied | pretable, ag-grid, tanstack | | H19 | satisfied | pretable (format), pretable (baseline), | | | | ag-grid, tanstack | | H20 | satisfied | pretable, ag-grid, tanstack | | H21 | satisfied | pretable, ag-grid, tanstack | All seven hypotheses retained their existing `satisfied` status (no threshold changes; evaluator-extension was data-only). Comparator evidence now embedded inline in each hypothesis's evidence array — the architectural goal of the PR. MUI runs flaked in this matrix attempt and are absent from the evidence; that's a matrix-runner reliability issue, not an evaluator issue. The evaluator correctly handles whatever comparator data is present per-slice. Investigating the matrix-runner's tanstack/mui flake pattern is a separate follow-up. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(research): repo-memory entry — comparator-aware evaluators Architecture change documenting the H6/H7/H8/H19/H20/H21 evaluator extensions, the matrix-runner flake workaround, and the deferred follow-ups. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore(bench): matrix milestone for comparator-aware evaluators H6/H7/H8/H19/H20/H21 now embed comparator evidence in their evidence arrays (4 entries each; 5 for H19 which also carries pretable's scroll baseline). Pretable-only status verdicts unchanged — all six remain satisfied. Aggregated from today's S2 hypothesis-scale runs across pretable/ag-grid/tanstack/mui after the matrix runner hit two mid-run e2e flakes (preview server / locator timing); on-disk summaries combined into a single report. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(research): correct repo-memory after successful matrix retry All four adapters (pretable + ag-grid + tanstack + mui) are present in every comparator-aware evaluator's evidence array. Updates the 2026-05-12 entry to reflect the recovered matrix outcome. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: prettier-format comparator-aware-evaluators artifacts * chore: prettier-format bench-matrix tests --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 9ae2bbe commit 999e818

6 files changed

Lines changed: 4759 additions & 28 deletions

File tree

docs/research/repo-memory.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,3 +498,22 @@ Editorial PR landing the PR #131 sort + filter comparator wedge on the homepage.
498498
- **PR #129 streaming reframe** — still awaiting user prose review. Touches `ComparisonTable.tsx` (streaming-row rename) and `ReceiptsBand.tsx`. File-level conflict with this PR is limited to the docblock at the top of `ComparisonTable.tsx`; resolvable.
499499
- **High-repeat protocol for interaction borderlines** — logged here.
500500
- **Pretable `scroll-with-render` 16.4 ms anomaly** — logged in the 2026-05-10 entry above; still pending investigation.
501+
502+
## 2026-05-12
503+
504+
### Comparator-aware evaluators — architecture change
505+
506+
Six pretable-only evaluators in `scripts/bench-matrix.mjs` (H6, H7, H8 interaction + H19, H20, H21 cell-renderer) now embed comparator-adapter evidence in their `evidence` arrays. Mirrors `evaluateH1`'s pre-existing pattern. Status logic unchanged — pretable's absolute thresholds still drive verdicts; comparator data is informational. Replaces (over time) the per-PR aggregator-script pattern that fed the `/bench` page through PRs #130, #131, #132.
507+
508+
- New `findComparatorEvidence(runs, { scenarioId, scriptName })` helper in `scripts/bench-matrix.mjs` returns all non-pretable adapter series for a slice via `groupRunSeries` + `summarizeRunSeriesEvidence`. Single helper used by all six target evaluators.
509+
- Each of H6/H7/H8/H19/H20/H21 appends `...comparatorEvidence` to its `evidence:` array in every return branch (insufficient / failing / satisfied / directional). For `insufficient` branches without pretable data, the evidence array stays empty — comparator data alone doesn't satisfy any hypothesis.
510+
- H19 (format overhead) keeps pretable's format + scroll-baseline entries at the front of the array; comparator entries are absolute `scroll-with-format` p95, NOT format-vs-baseline deltas. Inline docblock documents the semantics so future readers don't conflate the two.
511+
- Six new test cases in `scripts/__tests__/bench-matrix.test.mjs` assert evidence-array contents when comparator runs are present. All existing status-verdict tests untouched.
512+
- Matrix re-run at 4 adapters × 7 scripts × 3 repeats = 84 runs. The matrix runner bailed mid-run twice (one tanstack/filter-metadata locator-timing flake, one preview-server `ECONNREFUSED`); recovered by running the surviving adapters (`tanstack,mui`) as a second invocation, then synthesizing the milestone from all on-disk per-run summaries via a one-shot script that called `createHypothesisReport` directly. All four adapters are present in every H6/H7/H8/H19/H20/H21 evidence array.
513+
- Milestone: `status/milestones/2026-05-12-comparator-aware-evaluators.hypotheses.json`. All seven hypotheses (H1, H6–H8, H19–H21) retained `satisfied` status — architectural change was data-only.
514+
515+
### Out of scope (deferred)
516+
517+
- **`/bench` page swap to read from `hypotheses.json` directly.** Aggregator scripts (`scripts/extract-interaction-summary.mjs` + the inline aggregators) still feed the page; can be retired once the page reads from the new milestone shape. Editorial-only PR.
518+
- **Per-adapter format-overhead deltas in H19.** Currently H19's status compares pretable's `scroll-with-format` p95 against pretable's `scroll` baseline; comparator evidence surfaces absolute format p95 only. Computing per-adapter deltas would extend H19 from a pretable-quality check into a comparative-overhead check — a different hypothesis.
519+
- **Matrix runner reliability.** Mid-run flakes (locator timeouts, preview-server connection refused) have hit multiple recent PRs (#133, #134, this one). The bail-on-first-failure behavior wastes a 5-minute run when a single repeat flakes; a `--continue-on-error` option plus a runset-merge pathway would be a useful runner enhancement.
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
# Comparator-Aware Evaluators Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4+
5+
**Goal:** Extend six evaluators (H6, H7, H8, H19, H20, H21) in `scripts/bench-matrix.mjs` to include comparator evidence in their `evidence` arrays. Mirrors `evaluateH1`'s pattern. Status logic unchanged.
6+
7+
**Architecture:** Per the spec at `docs/superpowers/specs/2026-05-12-comparator-aware-evaluators-design.md`. Single PR. Auto-merge if all six hypothesis statuses stay at their existing values; hold for review if any status flips.
8+
9+
**Tech Stack:** TypeScript, Node test runner, Playwright (Chromium). No new dependencies.
10+
11+
**Spec:** [`docs/superpowers/specs/2026-05-12-comparator-aware-evaluators-design.md`](../specs/2026-05-12-comparator-aware-evaluators-design.md)
12+
13+
**Working directory:** `/Users/blove/repos/pretable/.worktrees/comparator-aware-evaluators`.
14+
15+
---
16+
17+
## File Structure
18+
19+
```
20+
scripts/
21+
├── bench-matrix.mjs (MODIFY: extend evaluateH6, H7, H8, H19, H20, H21)
22+
└── __tests__/bench-matrix.test.mjs (MODIFY: add comparator-evidence test per evaluator)
23+
24+
status/milestones/
25+
└── 2026-05-12-comparator-aware-evaluators.hypotheses.json (NEW: matrix re-run output)
26+
27+
docs/research/
28+
└── repo-memory.md (MODIFY: 2026-05-12 entry — evaluator architecture)
29+
```
30+
31+
---
32+
33+
## Task 1 — Read H1 as the reference shape
34+
35+
- [ ] **1.1** Open `scripts/bench-matrix.mjs` and locate `evaluateH1`. Note how it:
36+
- Uses `findRunSeries` to find pretable's series.
37+
- Uses `groupRunSeries(runs, { scenarioId, scriptName }).filter(s => s[0]?.adapterId !== "pretable")` to find competitor series.
38+
- Uses `summarizeRunSeriesEvidence(series)` to produce each evidence entry.
39+
- Picks a "best full-grid competitor" and a "best virtualization-primitive competitor" via `medianMetric` comparisons.
40+
- Returns `evidence: [pretableEvidence, bestFullGridEvidence, ...(bestPrimitiveEvidence ? [bestPrimitiveEvidence] : [])]`.
41+
42+
This is the model. The six target evaluators will surface ALL comparator entries (not just the best per family) since the comparison story is different — for H6/H7/H8/H19/H20/H21 we want every comparator's number visible.
43+
44+
- [ ] **1.2** Read each of the six target evaluators (`evaluateH6`, `evaluateH7`, `evaluateH8`, `evaluateH19`, `evaluateH20`, `evaluateH21`) to understand the existing shape before editing.
45+
46+
## Task 2 — Helper for comparator-evidence lookup
47+
48+
- [ ] **2.1** Add a helper function near the top of the evaluator section of `scripts/bench-matrix.mjs` (above `evaluateH1`). Single helper, used by all six evaluators:
49+
50+
```js
51+
/**
52+
* Find comparator-adapter series for the given (scenarioId, scriptName)
53+
* slice and return their evidence summaries. Pretable is excluded —
54+
* callers are expected to construct pretable evidence separately. Each
55+
* returned entry is the same shape as summarizeRunSeriesEvidence's output,
56+
* matching the evidence-array contract used by all evaluators.
57+
*
58+
* Used by H6/H7/H8 (interaction) and H19/H20/H21 (cell-renderer) to
59+
* surface comparator metrics alongside pretable in their evidence arrays.
60+
* Status verdicts remain pretable-only; this data is informational.
61+
*/
62+
function findComparatorEvidence(runs, { scenarioId, scriptName }) {
63+
const series = groupRunSeries(runs, { scenarioId, scriptName }).filter(
64+
(s) => s[0]?.adapterId && s[0].adapterId !== "pretable",
65+
);
66+
return series.map((s) => summarizeRunSeriesEvidence(s));
67+
}
68+
```
69+
70+
- [ ] **2.2** Typecheck:
71+
```
72+
pnpm --filter "@pretable-internal/bench-runner" typecheck
73+
```
74+
Expected: passes. (bench-matrix.mjs is JS, not TS, so typecheck just covers the package; the .mjs is linted separately.)
75+
76+
## Task 3 — Extend H6 (sort)
77+
78+
- [ ] **3.1** In `evaluateH6` (around line 613), find the `return { id: "H6", ..., evidence: [...] }` shape.
79+
80+
- [ ] **3.2** Just before the return, compute comparator evidence:
81+
82+
```js
83+
const comparatorEvidence = findComparatorEvidence(runs, {
84+
scenarioId,
85+
scriptName: "sort",
86+
});
87+
```
88+
89+
Update each return statement in `evaluateH6` to spread `...comparatorEvidence` after the pretable evidence in the array. There may be multiple returns (insufficient / failing / satisfied branches); update them all.
90+
91+
Skeleton (illustrative, adapt to actual evaluator code):
92+
93+
```js
94+
return {
95+
id: "H6",
96+
status: ...,
97+
summary: ...,
98+
evidence: [pretableEvidence, ...comparatorEvidence],
99+
};
100+
```
101+
102+
Note: for `insufficient` returns where `pretableEvidence` isn't built (no pretable series), keep the existing `evidence: []` — comparator data alone doesn't satisfy any version of H6.
103+
104+
- [ ] **3.3** Run the bench-matrix tests:
105+
106+
```
107+
node --test scripts/__tests__/bench-matrix.test.mjs
108+
```
109+
110+
Expected: all existing tests still pass. The evidence array now has more entries but existing tests check status + summary, not evidence-length.
111+
112+
- [ ] **3.4** Commit:
113+
```
114+
git add scripts/bench-matrix.mjs
115+
git commit -m "feat(bench-matrix): H6 evaluator surfaces comparator evidence"
116+
```
117+
118+
## Task 4 — Extend H7 (filter-metadata)
119+
120+
- [ ] **4.1** In `evaluateH7`, repeat the Task 3 pattern with `scriptName: "filter-metadata"`.
121+
122+
- [ ] **4.2** Run tests, commit:
123+
```
124+
node --test scripts/__tests__/bench-matrix.test.mjs
125+
git add scripts/bench-matrix.mjs
126+
git commit -m "feat(bench-matrix): H7 evaluator surfaces comparator evidence"
127+
```
128+
129+
## Task 5 — Extend H8 (filter-text)
130+
131+
- [ ] **5.1** Same pattern with `scriptName: "filter-text"`.
132+
133+
- [ ] **5.2** Run tests, commit `feat(bench-matrix): H8 evaluator surfaces comparator evidence`.
134+
135+
## Task 6 — Extend H19 (format overhead)
136+
137+
- [ ] **6.1** H19 is structured around comparing pretable's `scroll-with-format` p95 against pretable's `scroll` baseline. The comparator extension surfaces each comparator's `scroll-with-format` evidence (not deltas — see spec's non-goals; per-adapter format-vs-baseline deltas are a future enhancement).
138+
139+
In `evaluateH19`, add the comparator lookup:
140+
141+
```js
142+
const comparatorEvidence = findComparatorEvidence(runs, {
143+
scenarioId: "S2",
144+
scriptName: "scroll-with-format",
145+
});
146+
```
147+
148+
Append `...comparatorEvidence` to each return's `evidence` array. Keep the existing pretable format + pretable scroll baseline entries at the front.
149+
150+
Add a comment near the evidence array clarifying the semantics:
151+
152+
```js
153+
// evidence shape: [pretable format-overhead summary, pretable scroll
154+
// baseline summary, ...comparator scroll-with-format absolute summaries].
155+
// Pretable's first two entries form the format-overhead delta the H19
156+
// status verdict consumes; comparator entries are absolute format p95
157+
// for cross-adapter reference, NOT deltas vs their own scroll baselines.
158+
```
159+
160+
- [ ] **6.2** Run tests, commit `feat(bench-matrix): H19 evaluator surfaces comparator format evidence`.
161+
162+
## Task 7 — Extend H20 (cheap-render scroll)
163+
164+
- [ ] **7.1** Same pattern with `scriptName: "scroll-with-render"`.
165+
166+
- [ ] **7.2** Run tests, commit `feat(bench-matrix): H20 evaluator surfaces comparator evidence`.
167+
168+
## Task 8 — Extend H21 (heavy-render scroll)
169+
170+
- [ ] **8.1** Same pattern with `scriptName: "scroll-with-heavy-render"`.
171+
172+
- [ ] **8.2** Run tests, commit `feat(bench-matrix): H21 evaluator surfaces comparator evidence`.
173+
174+
## Task 9 — Add test coverage
175+
176+
- [ ] **9.1** For each of the six evaluators, add ONE new test asserting the comparator-evidence behavior. Mirror an existing test (e.g., `evaluateH6 satisfied when pretable sort latency is under threshold`) but include comparator runs in the input, and assert:
177+
178+
```js
179+
test("evaluateH6 evidence array includes comparator entries when comparator runs are present", () => {
180+
const runs = [
181+
createInteractionRun({ adapterId: "pretable", scenarioId: "S2", scriptName: "sort", ... }),
182+
createInteractionRun({ adapterId: "ag-grid", scenarioId: "S2", scriptName: "sort", ... }),
183+
createInteractionRun({ adapterId: "tanstack", scenarioId: "S2", scriptName: "sort", ... }),
184+
createInteractionRun({ adapterId: "mui", scenarioId: "S2", scriptName: "sort", ... }),
185+
];
186+
const result = evaluateH6(runs);
187+
expect(result.evidence.length).toBe(4); // pretable + 3 comparators
188+
expect(result.evidence.map((e) => e.adapterId).sort()).toEqual(
189+
["ag-grid", "mui", "pretable", "tanstack"]
190+
);
191+
});
192+
```
193+
194+
Adapt the test helper invocation to whatever `createInteractionRun` / `createScrollRun` factory the test file already has. Read the file for the existing helper before writing the test.
195+
196+
- [ ] **9.2** Run all matrix-runner tests:
197+
198+
```
199+
node --test scripts/__tests__/bench-matrix.test.mjs
200+
```
201+
202+
Expected: 6 new tests pass; all existing tests still pass.
203+
204+
- [ ] **9.3** Commit:
205+
```
206+
git add scripts/__tests__/bench-matrix.test.mjs
207+
git commit -m "test(bench-matrix): comparator-evidence assertions for H6/H7/H8/H19/H20/H21"
208+
```
209+
210+
## Task 10 — Matrix re-run
211+
212+
- [ ] **10.1** Build the harness:
213+
214+
```
215+
pnpm --filter @pretable/app-bench build
216+
```
217+
218+
- [ ] **10.2** Run the matrix:
219+
220+
```
221+
pnpm bench:matrix \
222+
--project=chromium \
223+
--adapters=pretable,ag-grid,tanstack,mui \
224+
--scenarios=S2 \
225+
--scripts=scroll,sort,filter-metadata,filter-text,scroll-with-format,scroll-with-render,scroll-with-heavy-render \
226+
--scale=hypothesis \
227+
--repeats=3
228+
```
229+
230+
Use `Bash run_in_background: true` since this is ~5 min wall-clock. 7 scripts × 4 adapters × 3 repeats = 84 runs.
231+
232+
- [ ] **10.3** Wait for the matrix to complete (poll sparingly via `pgrep -f bench-matrix`). When done, locate the runset:
233+
234+
```
235+
ls -lt status/runsets/ | head -3
236+
```
237+
238+
- [ ] **10.4** Read `status/runsets/<id>/hypotheses.json` and verify:
239+
- H1 status: matches existing milestone (satisfied at parity).
240+
- H6/H7/H8 status: each `satisfied` (pretable absolute thresholds unchanged).
241+
- H19/H20/H21 status: each `satisfied` (cell-renderer absolute thresholds unchanged).
242+
- Each of H6/H7/H8/H19/H20/H21 has 4 evidence entries (pretable + 3 comparators).
243+
- If any status flips unexpectedly, STOP and report DONE_WITH_CONCERNS — don't change thresholds.
244+
245+
- [ ] **10.5** Copy the runset to the milestone path:
246+
247+
```
248+
cp status/runsets/<id>/hypotheses.json status/milestones/2026-05-12-comparator-aware-evaluators.hypotheses.json
249+
```
250+
251+
- [ ] **10.6** Commit:
252+
253+
```
254+
git add status/milestones/2026-05-12-comparator-aware-evaluators.hypotheses.json
255+
git commit -m "chore(bench): matrix milestone for comparator-aware evaluators
256+
257+
H6/H7/H8/H19/H20/H21 now embed comparator evidence in their evidence
258+
arrays. Pretable-only status verdicts unchanged."
259+
```
260+
261+
## Task 11 — Repo-memory entry
262+
263+
- [ ] **11.1** Append a 2026-05-12 entry to `docs/research/repo-memory.md`:
264+
- Architecture summary: evaluators now embed comparator evidence; H1's pattern reused.
265+
- Status logic unchanged (pretable thresholds drive verdicts).
266+
- Test coverage extended for all six evaluators.
267+
- Matrix re-run committed at the new milestone path.
268+
- Note that the aggregator scripts from PRs #130/#131/#132 are now redundant for `hypotheses.json` consumers, but still feed the `/bench` page; a future PR can swap the page to read from `hypotheses.json` directly and retire the aggregators.
269+
270+
- [ ] **11.2** Commit:
271+
```
272+
git add docs/research/repo-memory.md
273+
git commit -m "docs(research): repo-memory entry — comparator-aware evaluators"
274+
```
275+
276+
## Task 12 — Gates + PR
277+
278+
- [ ] **12.1** Repo-wide gates:
279+
280+
```
281+
pnpm -w typecheck && pnpm -w test && pnpm -w lint && pnpm format
282+
```
283+
284+
Expected: all pass. The evaluator changes are JS in `scripts/`; typecheck doesn't cover them but lint does.
285+
286+
- [ ] **12.2** Push + open PR:
287+
288+
```
289+
git push -u origin comparator-aware-evaluators
290+
gh pr create --title "feat(bench-matrix): H6-H8 + H19-H21 evaluators embed comparator evidence" --body "..."
291+
```
292+
293+
PR body covers: summary, the evaluator shape change, the matrix re-run, what's NOT in this PR (no /bench page changes, no threshold changes, no aggregator-script retirement).
294+
295+
- [ ] **12.3** Auto-merge decision per the spec:
296+
- If all six hypotheses retained their existing `satisfied` status → `gh pr merge --auto --squash`.
297+
- If anything flipped → HOLD for user review (surface in the PR body and end-of-task report).
298+
299+
---
300+
301+
## Self-review
302+
303+
| Spec section | Plan task |
304+
| ----------------------------------- | ------------------------------------------------------ |
305+
| Evaluator extension pattern | Tasks 2 (helper) + 3–8 (per-evaluator) |
306+
| Per-evaluator slice definitions | Tasks 3–8 use the right (scenarioId, scriptName) tuple |
307+
| Test updates | Task 9 |
308+
| Matrix re-run | Task 10 |
309+
| Sanity check on verdicts | Task 10.4 |
310+
| H19 format-overhead semantics drift | Task 6.1 inline comment |
311+
312+
All sections covered.
313+
314+
No placeholders outside the PR-body template (those are intentional). Type/value consistency: `findComparatorEvidence` signature is consistent across all six callers; helper returns the same shape as `summarizeRunSeriesEvidence`.
315+
316+
Scope: single PR, 12 tasks, ~10 commits-of-record. Auto-mergeable unless verdicts flip.

0 commit comments

Comments
 (0)