Skip to content

Commit 5c59c20

Browse files
docs(puzzle-page): document 3-tier v0/v1/v2 rollout gating structure
Replaces the previous "DCR's /PuzzlePage endpoint itself has no access control or kill-switch..." limitation bullet (added in an earlier task, before this structure existed) with an accurate description of what's now in place, and adds a new "Feature-tier rollout gating (v0/v1/v2)" subsection to "Open questions / known limitations" documenting: - What each of the three cumulative AB test tiers (puzzles-new-hub / puzzles-new-hub-v1 / puzzles-new-hub-v2) actually gates, mirroring the JSDoc content added to ab-testing/config/abTests.ts. - The cumulative dependency rule (v1 requires v0, v2 requires v0+v1) and how to roll back a single phase without a deploy. - That all three tiers currently sit at 0% audience (hidden from the public), same as before this structure existed. - That today only the "More from Puzzles & Games" rail is actually gated at the DCR render level (behind isPuzzlesHubV1Enabled) - every other v0-scoped feature currently in this codebase renders unconditionally; v0's real "gating" today is frontend's route-level PuzzlesHubExperiment check deciding whether a request reaches /PuzzlePage at all, not a DCR-side render-time check. - An explicit pointer that future v1/v2 work (calendar, progress indicators, sign-in message, on-the-ball/film-reveal) should be gated behind isPuzzlesHubV1Enabled/isPuzzlesHubV2Enabled respectively, using the helpers added in this task's earlier commits - so this is discoverable later without rediscovering the whole design. - That no frontend repo changes are needed for any of this - frontend doesn't render Puzzle Page UI itself, so feature-tier gating naturally lives entirely on the DCR side, and frontend's existing route-level PuzzlesHubExperiment gate (already reusing puzzles-new-hub) is unaffected by v1/v2 and doesn't need to check them. No functional/code changes in this commit - documentation only. tsc --noEmit clean, full-repo eslint clean, full test suite passing (177 suites / 1295 tests). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent ebc184d commit 5c59c20

1 file changed

Lines changed: 76 additions & 11 deletions

File tree

dotcom-rendering/docs/puzzle-page.md

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,21 +315,86 @@ darkMode: boolean } }` and the `?guardian-puzzle-context=<JSON>` query
315315
to V1, pending investigation into whether/how each provider's iframe URL
316316
scheme (AmuseLabs, Wordiply) supports requesting a specific historical
317317
date at all.
318-
- **DCR's `/PuzzlePage` endpoint itself has no access control or
319-
kill-switch that doesn't require a code change and redeploy.** The AB
320-
gate (`game-page-experiment`) that originally hid this page in DCR was
321-
removed entirely (see git history). Reader-facing access control now
322-
lives on the `frontend` side instead, via its existing
323-
`PuzzlesHubExperiment`/`puzzles-new-hub` AB test gating which readers
324-
ever reach one of these puzzle-page URLs in the first place — DCR itself
325-
still has no equivalent gate or kill-switch of its own in front of
326-
`/PuzzlePage`. If DCR's endpoint is ever exposed to traffic that bypasses
327-
`frontend`'s gating (e.g. hit directly), there is currently nothing
328-
stopping it from rendering.
318+
- **DCR's `/PuzzlePage` endpoint itself still has no route-level access
319+
control** (unchanged from before) — `frontend`'s existing
320+
`PuzzlesHubExperiment`/`puzzles-new-hub` AB test gate decides whether a
321+
reader ever reaches one of these puzzle-page URLs in the first place;
322+
DCR's endpoint renders unconditionally for any request with a known
323+
`slug`. **What has changed**: DCR now has a real, cumulative,
324+
code-change-free kill-switch for individual _feature tiers_ within the
325+
rendered page — see "Feature-tier rollout gating (v0/v1/v2)" below. This
326+
addresses the previous "no kill-switch" limitation for feature-level
327+
rollback; it does not add route-level gating to `/PuzzlePage` itself
328+
(that remains `frontend`'s responsibility, unchanged).
329329
- **The Puzzles Hub (`src/layouts/PuzzlesLayout.tsx` and friends) is a
330330
separate, unrelated feature** (a directory/listing page) and is not
331331
documented in this file.
332332

333+
### Feature-tier rollout gating (v0/v1/v2)
334+
335+
The Puzzles & Games rollout uses a 3-tier, **cumulative** AB-test/
336+
kill-switch structure (`ab-testing/config/abTests.ts`), so any rollout
337+
phase can be turned on/off — or rolled back to an earlier phase — without
338+
a DCR code change or redeploy. This is per the product rollout plan (v0 =
339+
w/c 5 Oct launch, v1 = w/c 12 Oct launch, v2 = no date confirmed yet).
340+
341+
- **`puzzles-new-hub` (v0, the master switch)**: gates the baseline
342+
experience — the new Puzzles Hub page, and the 6 V0 puzzle pages (sudoku
343+
x4, word-wheel, wordiply) with no archive, no calendar, no progress
344+
indicators, no sign-in prompt, no related-content rail, and a hub
345+
sub-nav with no links yet. Turning this off hides everything, including
346+
every later tier.
347+
- **`puzzles-new-hub-v1`**: the w/c 12 Oct layer, **on top of v0** — does
348+
nothing unless `puzzles-new-hub` is _also_ enabled. Activates: full hub
349+
sub-nav links, a sign-in-to-track-progress message, a calendar/archive
350+
view for crosswords/logic-puzzles/word-games (not Wordiply), progress
351+
indicators, the "More from Puzzles & Games" rail, newsletter signup, and
352+
changes to the existing crossword page (print CTA repositioning, "play
353+
other puzzles" container).
354+
- **`puzzles-new-hub-v2`**: a future layer, **on top of v0+v1** — does
355+
nothing unless both `puzzles-new-hub` and `puzzles-new-hub-v1` are
356+
_also_ enabled. Activates: On the Ball/Film Reveal (Trivia and Quizzes),
357+
a "Most played" container, EventKit-driven navigation, migrating
358+
existing crossword pages onto the Puzzle Page template, and
359+
search-engine mobile app nudges. No launch date confirmed yet; kept at
360+
0% until that work begins.
361+
362+
The cumulative design is deliberate: it's impossible to end up with, say,
363+
v2 features showing while v0 is switched off, since each tier's gate
364+
function requires every tier below it to also pass. To roll back a single
365+
phase without a deploy, flip only that tier's `audienceSize`/`status` in
366+
`abTests.ts` and leave the tier(s) below it untouched (e.g. to roll back
367+
from v1 to v0, turn off `puzzles-new-hub-v1` only).
368+
369+
The corresponding gate-check helpers live in DCR:
370+
371+
- `isPuzzlesHubEnabled` (`src/lib/puzzlesHubExperiment.ts`) — v0 only.
372+
- `isPuzzlesHubV1Enabled`/`isPuzzlesHubV2Enabled`
373+
(`src/lib/puzzlesHubVersionExperiment.ts`) — cumulative, as described
374+
above.
375+
376+
**Current state**: all three tiers sit at `audienceSize: 0/100` — hidden
377+
from the public entirely, same as before this structure existed. Today,
378+
only one DCR-rendered feature actually checks a tier gate:
379+
`PuzzlePageLayout.tsx`'s "More from Puzzles & Games" rail, gated behind
380+
`isPuzzlesHubV1Enabled` (since that rail is v1-scoped, not v0). Every
381+
other v0-scoped feature currently in this codebase renders unconditionally
382+
at the DCR level — v0's "gating" today is really just `frontend`'s
383+
route-level `PuzzlesHubExperiment` check deciding whether a request
384+
reaches `/PuzzlePage` at all, not a DCR-side render-time check. When
385+
future v1/v2 work is implemented (calendar, progress indicators, sign-in
386+
message, on-the-ball/film-reveal, etc.), it should be gated behind
387+
`isPuzzlesHubV1Enabled`/`isPuzzlesHubV2Enabled` respectively, using the
388+
helpers above, the same way the related-content rail already is.
389+
390+
**No `frontend` repo changes are needed for any of this.** `frontend`
391+
doesn't render Puzzle Page UI itself, so feature-tier gating naturally
392+
lives entirely on the DCR side. `frontend`'s existing route-level
393+
`PuzzlesHubExperiment` gate (already reusing `puzzles-new-hub`) is
394+
unaffected by `puzzles-new-hub-v1`/`puzzles-new-hub-v2` and doesn't need
395+
to check them — it only ever needed to decide whether a reader reaches
396+
`/PuzzlePage` at all, which is still governed by v0 alone.
397+
333398
### SEO risks to revisit before shipping calendar/archive features
334399

335400
**Read this before adding date-specific URLs (V1 calendar navigation) or

0 commit comments

Comments
 (0)