fix: round 3 — a vacuous ordering test, a clamp that was a silent rewrite, a regex that missed

Round 3 over round 2's fixes. The trend is 22 → 13 → 6, and the character has
shifted: these are mostly defects in the REVIEW's own work, not in the epic.

The ordering test I added to hold the middleware's position could not fail for
either arrangement it names. All four `@app.middleware("http")` layers — the
access log, the two header decorators AND the setup gate that must be inside —
register as the same `BaseHTTPMiddleware`, so asserting on the class passes for
the pre-move stack and for a cap moved back outside CORS. It names the layers by
their dispatch function now, which is the only thing that distinguishes them.

The `sysconfig` bounds check CLAMPED, and clamping is a silent rewrite — the thing
this module refuses to do everywhere else, where an unusable override falls back
to the env default and logs once. On the max side the difference is cosmetic; on
the min side it is a live bug. `download_upload_max_bytes` had `min=0` before E7,
and a stored 0 means "no per-file cap" to the route that reads it. Clamped to 1 it
becomes a ONE-BYTE cap: uploads dead, nothing in the log, the admin page showing
"1". It raises `OutOfRange` now and takes the existing fallback, with its own
event code.

The `capped_body` sweep grepped for an identifier as the limit argument, so a site
written `capped_body(request, 4 * 1024 * 1024)` — or with the parameter not named
`request` — was MISSED, and a miss reads as "no new sites". Parsed with `ast`
instead: every call is seen whatever it looks like, and an unfamiliar argument
shape fails the equality instead of vanishing.

Frontend: the shrink test drove the mock in a way the real hook cannot produce
(it moved `visible` in the same step as the shrink, and the comment miscounted the
tags), so it reproduced the right END STATE by accident rather than the sequence.
`visible` is now left alone across the shrink, which IS the precondition.

Ops: the baseline guard answered "did this run rewrite it?" and therefore went
green on the second run over an already-tightened, uncommitted baseline — the
exact state its own comment says marks the localdev stack stale ever after. It
asks both questions now. And `.dockerignore` joins BAKED_PATHS: it decides what
the COPY lines actually take, so it is an input to the build context exactly as
the copied trees are.
This commit is contained in:
2026-09-22 00:12:30 +02:00
parent 6b86673af4
commit 3f24248e01
3 changed files with 116 additions and 57 deletions
@@ -67,24 +67,27 @@ describe("TagFilterChips — the overflow menu", () => {
});
it("does not come back when the chip set SHRINKS under the open menu", () => {
// The nastier half of the same bug. `useChipOverflowFit` holds `visible` in state and re-decides
// in a layout effect, so the render in which the set shrinks still carries the PREVIOUS
// measurement — `chips.length - visible` goes negative there, and a `hidden === 0` guard reading
// an unclamped value never fires. The flag then survives the one window it exists to close.
const four = [...chips, chip("delta")];
fit.visible = 1;
const { rerender } = render(<TagFilterChips chips={four} />);
// The nastier half of the same bug, and it needs the hook's real timing to reproduce.
// `useChipOverflowFit` keeps `visible` in state and only rewrites it from a LAYOUT EFFECT, so
// the render in which the set shrinks still carries the measurement taken for the PREVIOUS,
// longer set. `length - visible` is negative in that render, a `hidden === 0` guard reading it
// unclamped never fires, and the flag survives the one window it exists to close.
//
// So `fit.visible` is left ALONE across the shrink — that staleness is the precondition, not a
// convenience of the mock. Five chips of which three fit, then three of them are deleted in the
// tag manager: 3 - 5 = -2.
const five = ["alpha", "beta", "gamma", "delta", "epsilon"].map(chip);
fit.visible = 3;
const { rerender } = render(<TagFilterChips chips={five} />);
fireEvent.click(moreBtn()!);
expect(menu()).toBeTruthy();
// Three tags are deleted in the tag manager. `visible` is still the stale 3.
fit.visible = 3;
rerender(<TagFilterChips chips={[chip("alpha"), chip("beta")]} />);
rerender(<TagFilterChips chips={five.slice(0, 2)} />); // `visible` is still the stale 3
expect(menu()).toBeNull();
// …and now the layout effect lands: two long names, only one fits.
// …and now the layout effect lands: two long names, only one of them fits.
fit.visible = 1;
rerender(<TagFilterChips chips={[chip("alpha"), chip("beta")]} />);
rerender(<TagFilterChips chips={five.slice(0, 2)} />);
expect(menu()).toBeNull();
expect(moreBtn()).toHaveProperty("ariaExpanded", "false");
});