The filter bar derived its condition chips from the loaded corpus, so an
episode whose only linked documents sat pages deep in the timeline never
surfaced a chip — the condition route into an older document silently
disappeared at four-digit corpus sizes. The usage endpoint (already read
on page mount) now returns `linkedEpisodes` — every episode carrying at
least one live document link, one indexed grouped query, no blobs — and
the view unions it with the active-filter fallback. Additive DTO change;
OpenAPI regenerated.
Concurrent uploads all read the same pre-insert usage SUM, so a burst
could overshoot the per-user quota by rate-limit x cap in one window. A
transaction-scoped advisory lock keyed on the user id serialises the
sum-and-insert; uploads by different users never queue on each other.
Integration probes pin both races: four parallel uploads against a
two-file quota land exactly two, and two racing identical uploads
collapse onto one row via the partial unique index.
Also aligns the round-trip integration test with the serve-route CSP
posture: the proxy carve-out owns the response CSP, the route sets none.
Pins what the unit mocks cannot: the binary2 round-trip through upload and
/original with class-correct headers, the policy error contract, sha256
dedupe per user with the partial unique index live, Idempotency-Key replay
without a second row, tombstone-inclusive quota accounting, pre-link +
replace-set + kind/episode/year list filters, restore incl. both 409
shapes, bulk per-id semantics, usage with a per-user override, and the
purge job claiming only past-grace tombstones. Migration 0227 applies
clean on the fresh testcontainer as part of the ordered chain.
Tasks: W1-T1, W1-T5, W1-T6, W1-T7, W1-T8, W1-T9, W1-T10, W1-T12.