Theme Tier-Gating Requires Multi-Repo Entitlement Sync
The Insight
Premium themes (Candy Themes for Starlight docs) are gated at subscription tiers. A new theme registration requires synchronized edits across 5 separate files spanning TypeScript, Go, and JSX. A mismatch in any file silently breaks the feature: the theme becomes inaccessible to all tiers, or accessible to tiers that shouldn’t have it. The discovery: Parity between the TS manifest, TS entitlements engine, and Go server-side validation is not enforced by the type system. TypeScript can compile with all union members registered, and all Go tests can pass, while a theme’s entitlement is missing from the Go map. The client offers it; the server rejects it.Why This Happens
Theme registration lives in two languages, three concerns:- Display —
manifest.tstracks which themes exist (TypeScript compilation) - Client-side gating —
engine.tstracks which tiers can see which themes (TS type-check) - Server-side validation —
entitlements.govalidates theme selections on PATCH (Go vet)
The Solution
Declare a verification gate that spans both languages:Key Metrics (Blackjack Theme, 2026-04-24)
- Files touched: 5 (1 CSS, 1 TS manifest, 1 TS engine, 1 Go map, 1 JSX comment)
- Parity checks: 3 (union member count = THEMES record = TS entitlements = Go map)
- CSS variable parity: 21
--sl-*variables (compare: new theme vs. reference theme) - Type errors before gate: 1 (missing THEMES.blackjack)
- Type errors after gate: 0
- Go vet errors: 0
- Silent bugs: 0 (gate caught all potential mismatches)
Related Doctrines
- candy-themes-tier-gated-registration.doctrine.md — Full pattern for registering a theme across all 5 files.
- sequential-taskset-gated-execution-pattern.doctrine.md — How to order the 5 edits as gated tasksets so rollback scope is minimized.