You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #15985 (card #15467) resolves the ioredis-mock@8 (peer ioredis@^5) versus ioredis@^6 mismatch by measuring it and declaring it inert — comments only, no code, dependency or CI change. The measurement is good and the route was the one triage named for that outcome.
⚠️But the whole deliverable is a claim in a comment, and the claim has an expiry condition it states itself: it holds for the pair ioredis 5.11.1 / 6.0.0 and stops holding if either range moves. Nothing checks that. ⇒ A dependency bump six months from now silently invalidates a header that will still read as authoritative.
Why this is worth a card rather than trust
This repository keeps rediscovering the same defect class, three separate times today alone:
a header promising RUN_REAL_REDIS=1 + REDIS_URL and "conditional describe.skipIf blocks at the bottom" — no such blocks existed, and neither name occurred anywhere else in the package (removed by that same PR);
⭐ In every one, the prose was correct when written and rotted without a signal. That is the shape here.
Suggested shape, ⛔ not prescribed
A pin asserting the two dependency ranges still match the pair the new header names — so the declaration reddens when it stops being true, instead of being quietly wrong.
⚠️This is a policy call, which is why it is filed rather than folded in. It reddens on every bump of either dependency, and whether that is a feature or a nuisance is a judgement:
For: the bump is exactly the moment the claim needs re-measuring, and a red pin puts the header in front of whoever is bumping — the only person positioned to re-check it.
Against: it is new verification surface nobody asked for, and a pin that fires on routine maintenance trains people to edit the pin rather than re-do the measurement, which would be worse than no pin.
⇒ A middle option worth considering: pin the conclusion rather than the versions — re-derive the overload intersection in CI — which does not fire on a bump that changes nothing. ⚠️ More expensive, and it needs both packages' type declarations resolvable in that environment.
What a taker should NOT do
⛔ Do not "fix" this by adopting @types/ioredis-mock and dropping the @ts-expect-error. That was measured and deliberately rejected on #15467: those types declare the mock constructor as returning a real ioredis Redis, so they assert conformance instead of verifying it — trading a visible any for an unearned certainty TypeScript would then vouch for. ⭐ That is the same failure mode this whole family is about, one layer up.
⛔ Do not re-litigate the inertness measurement itself; it is on PR #15985 with its controls, and the ablation there shows the suppression has not rotted (removing it yields TS7016 … implicitly has an any type).
What needs defending
PR #15985 (card #15467) resolves the
ioredis-mock@8(peerioredis@^5) versusioredis@^6mismatch by measuring it and declaring it inert — comments only, no code, dependency or CI change. The measurement is good and the route was the one triage named for that outcome.ioredis 5.11.1/6.0.0and stops holding if either range moves. Nothing checks that. ⇒ A dependency bump six months from now silently invalidates a header that will still read as authoritative.Why this is worth a card rather than trust
This repository keeps rediscovering the same defect class, three separate times today alone:
RUN_REAL_REDIS=1+REDIS_URLand "conditionaldescribe.skipIfblocks at the bottom" — no such blocks existed, and neither name occurred anywhere else in the package (removed by that same PR);eval-user.zod.tsdocumentingcreateEvalUseras "the single factory every surface uses (server buildScope, the customSession bridge, …)" — measured, there is no customSession bridge, and that non-existent producer is exactly the gap card action.visible 的 current_user.positions 装的是 auth 角色而非安全层岗位,按岗位收敛的按钮对所有人静默消失(17.2.0) #15136 fell through;resolve-authz-context.ts:1125-1129's ⛔ "neverpositions.includes(...)" — a comment, not a gate, which did not stop a privilege escalation from being written twice (fix(plugin-auth)!: session payloadpositions[]is the security axis, not the better-auth role scalar #15948 round 1, and the four pre-existing readers in Four server-side readers derive platform authority from the NAME inExecutionContext.positions— same species as #15948's blocked escalation, and already reachable onmain#15981).⭐ In every one, the prose was correct when written and rotted without a signal. That is the shape here.
Suggested shape, ⛔ not prescribed
A pin asserting the two dependency ranges still match the pair the new header names — so the declaration reddens when it stops being true, instead of being quietly wrong.
⇒ A middle option worth considering: pin the conclusion rather than the versions — re-derive the overload intersection in CI — which does not fire on a bump that changes nothing.⚠️ More expensive, and it needs both packages' type declarations resolvable in that environment.
What a taker should NOT do
⛔ Do not "fix" this by adopting
@types/ioredis-mockand dropping the@ts-expect-error. That was measured and deliberately rejected on #15467: those types declare the mock constructor as returning a real ioredisRedis, so they assert conformance instead of verifying it — trading a visibleanyfor an unearned certainty TypeScript would then vouch for. ⭐ That is the same failure mode this whole family is about, one layer up.⛔ Do not re-litigate the inertness measurement itself; it is on PR #15985 with its controls, and the ablation there shows the suppression has not rotted (removing it yields
TS7016 … implicitly has an any type).Related
service-cluster-redis's contract test runs ioredis-mock@8 (peerioredis@^5) against a package that depends onioredis@^6, with the import seam suppressed by @ts-expect-error #15467 / PR docs(service-cluster-redis): record the measured ioredis 5-vs-6 gap in the contract test header, and drop a live-Redis path that never existed #15985 — the measurement and the declaration this card would defend.service-cluster-redis's KV contract suite never exercises the WATCH/MULTI abort-retry path nor the versioned-delete MULTI branch — measured by instrumenting the shipped test #15983 — from the same instrumentation run:RedisKV.delete's versioned branch is unexercised, so the optimistic-concurrency claim in its header has zero assertions behind it. Same package, same species — a claim with nothing checking it.