diff --git a/server/src/systemNotices/registry.ts b/server/src/systemNotices/registry.ts index 3dca1513f..faf2f8198 100644 --- a/server/src/systemNotices/registry.ts +++ b/server/src/systemNotices/registry.ts @@ -106,11 +106,14 @@ export const SYSTEM_NOTICES: SystemNotice[] = [ conditions: [{ kind: 'managed', is: false }], publishedAt: '2026-08-22T00:00:00Z', priority: 110, - // The 4.0.x window. The copy is about this release, so somebody arriving on - // 4.1 — or jumping 3.x straight to 4.2 — should get that release's notice - // instead of this one, not a summary of a version they skipped. + // The whole 4.x line. The copy is about what 4.0.0 brought, and that is still + // what somebody arriving anywhere on 4.x is being introduced to — the minor + // releases after it add to that picture rather than replace it. Held open to + // the 5.0.0 boundary (exclusive) so a 4.1/4.2 install is not left with no + // notice at all, which is what a per-release window did the moment 4.1.0 + // shipped without an entry of its own. minVersion: '4.0.0', - maxVersion: '4.1.0', + maxVersion: '5.0.0', }, // ── Thank-you + support the project — shown once per install AND once per upgrade ── diff --git a/server/tests/unit/systemNotices/registry.test.ts b/server/tests/unit/systemNotices/registry.test.ts index 1c4c2ce41..0d7a4d6c7 100644 --- a/server/tests/unit/systemNotices/registry.test.ts +++ b/server/tests/unit/systemNotices/registry.test.ts @@ -65,19 +65,21 @@ describe('registry integrity', () => { } }); - it('the 4.0.0 release notice is confined to the 4.0.x line', () => { + it('the 4.0.0 release notice covers the whole 4.x line', () => { const release = SYSTEM_NOTICES.find(n => n.id === 'release-4-0-0'); expect(release).toBeDefined(); - // Its copy is about this release, so it must not greet somebody who skipped - // straight past it, and it must not run alongside the next release's notice. + // It must not greet somebody still on 3.x... expect(isNoticeVersionActive(release!, '3.4.1')).toBe(false); expect(isNoticeVersionActive(release!, '4.0.0')).toBe(true); expect(isNoticeVersionActive(release!, '4.0.7')).toBe(true); - // The upper bound is exclusive, so every 4.0.x patch still gets it. - expect(isNoticeVersionActive(release!, '4.0.9')).toBe(true); expect(isNoticeVersionActive(release!, '4.0.12')).toBe(true); - expect(isNoticeVersionActive(release!, '4.1.0')).toBe(false); - expect(isNoticeVersionActive(release!, '4.2.0')).toBe(false); + // ...and it stays up across the minors, so no 4.x install is left without a + // notice the way 4.1.0 was under the old per-release window. + expect(isNoticeVersionActive(release!, '4.1.0')).toBe(true); + expect(isNoticeVersionActive(release!, '4.2.0')).toBe(true); + expect(isNoticeVersionActive(release!, '4.9.9')).toBe(true); + // The upper bound is exclusive: 5.0.0 gets its own notice. + expect(isNoticeVersionActive(release!, '5.0.0')).toBe(false); }); it('the thank-you notice hands over to the release modal at 4.0.0', () => {