From 58921084d381f5c8d8f5d5a4407a6701eaaadf61 Mon Sep 17 00:00:00 2001 From: Matthew Valancy Date: Sat, 20 Jun 2026 04:15:42 -0700 Subject: [PATCH] test(adaptive-quality): guard tier cost-monotonicity invariant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A richer quality tier must never render less work than a cheaper one (smaller attachment preview, higher label-LOD threshold, or a disabled effect a lower tier enables). The existing suite only guarded maxInitialNodes; this locks the same invariant across attachmentPreviewSize, labelLodZoom, and the four effect flags — the config-regression class that would let a 'lower' tier paradoxically do MORE work. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/lib/__tests__/adaptiveQuality.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/web/src/lib/__tests__/adaptiveQuality.test.ts b/packages/web/src/lib/__tests__/adaptiveQuality.test.ts index 4c98e54b..e038a8af 100644 --- a/packages/web/src/lib/__tests__/adaptiveQuality.test.ts +++ b/packages/web/src/lib/__tests__/adaptiveQuality.test.ts @@ -108,6 +108,25 @@ describe('profileForTier (ADAPT-3, ADAPT-2, ADAPT-9)', () => { } }); + it('never lets a richer tier render less work than a cheaper one (ADAPT-3 invariant)', () => { + // TIER_ORDER is cheapest → richest. As the tier rises, cost-bearing + // knobs must move monotonically toward "more work", never less — a + // lower tier doing MORE rendering would make adaptive downgrades pointless. + for (let i = 1; i < TIER_ORDER.length; i++) { + const lo = profileForTier(TIER_ORDER[i - 1], {}); + const hi = profileForTier(TIER_ORDER[i], {}); + // Bigger preview = more work; richer tier must not request a smaller one. + expect(hi.attachmentPreviewSize).toBeGreaterThanOrEqual(lo.attachmentPreviewSize); + // Lower labelLodZoom = labels appear sooner = more labels drawn; richer + // tier must not have a higher threshold than a cheaper one. + expect(hi.labelLodZoom).toBeLessThanOrEqual(lo.labelLodZoom); + // An effect on at a cheaper tier must stay on at every richer tier. + for (const flag of ['glowEffects', 'animations', 'entranceAnimation', 'particleCelebrations'] as const) { + if (lo[flag]) expect(hi[flag]).toBe(true); + } + } + }); + it('clamps attachment previews to ≤256px under Save-Data at any tier (ADAPT-2)', () => { for (const tier of TIER_ORDER) { expect(profileForTier(tier, { saveData: true }).attachmentPreviewSize).toBeLessThanOrEqual(256);