5.7.12 Flip the `transitioned` matrix seam to settable + real copy (en/zh) — depends on both channels being real (5.7.10 + 5.7.11)
Estimate: 16m · Depends on: 5.7.10, 5.7.11
Why this exists + why BLOCKED. This is the surface symptom of the bug (/settings/account draws the "An item you're watching changes status" row disabled with a "Soon" tag + "Available once issue-watching ships (Story 5.4)" copy, though 5.4 shipped). 5.7.6 drew it "disabled until 5.4 lands" with no flip-subtask, and 5.4 had already landed — the static disable became permanent (notes.html mistake #40). The flip is one boolean + two strings, BUT it MUST land AFTER 5.7.10 (in-app delivery) and 5.7.11 (email gate) — otherwise enabling the toggles ships DECORATIVE controls (the "worse than disabled" defect). Hence dependsOn: [5.7.10, 5.7.11]; seeded blocked until both are done, then flip to planned in the same seed/* PR that lands the second blocker.
Fix.
lib/notifications/preferences.ts— flip thetransitionedrowsettable: false→true; rewrite the line-70 comment from the "drawn disabled until issue-watching ships" seam note to one that states: watcher transition events (Story 5.4 — shipped) are fanned in by 5.7.10 (in_app) + 5.4.5/5.7.11 (email), gated by the user’s transitioned·{channel} cell. (Defaults are already{ email: true, in_app: true }— correct; the resolver does the right thing the moment the flag flips.)messages/en.json+messages/zh.json— replacesettings.account.notifications.events.transitioned.desc(KEEP the label) with real present-tense copy mirroring the other three rows, e.g. en "Someone changes the status of an item you watch (including moves to done or back open)."; zh a translation of the same (replace the 即将推出 / Story-5.4 placeholder). Both locales flip together.- No UI change —
NotificationPreferencesCard.tsxalready branches onrow.settable(the "Soon" tag drops, the switches enable, the aria-label flipscellAriaSoon→cellAriaautomatically).
Acceptance criteria
- The
/settings/accountmatrixtransitionedrow is ENABLED: both switches clickable, no "Soon"/即将推出 tag, helper text is the new real copy (en + zh both updated); aria-label iscellArianotcellAriaSoon. notificationPreferencesService.setPreferenceno longer throwsNotificationEventTypeNotSettableErrorforeventType: "transitioned"; the matrix DTO fromGET /api/notification-preferencesreportssettable: truefor the row.- Toggling each cell persists and the cell trusts the response (the inline-edit no-tree-refresh contract holds); the three existing rows are unchanged (defaults, AA contrast).
- Audit grep (
grep -rn "Available once\|settable: false\|until.*ships\|ships (Story") acrossapp components lib messagesfinds no remaining stale "coming once Story X ships" guard whose Story X is alreadydone(the audit is the rule, not just this row).
Context refs
lib/notifications/preferences.ts(thetransitionedsettableflag + line-70 comment)messages/en.json+messages/zh.json—settings.account.notifications.events.transitionedapp/(authed)/settings/account/_components/NotificationPreferencesCard.tsx(no change; branches onrow.settable/cellAriavscellAriaSoonalready)lib/services/notificationPreferencesService.ts(setPreference— the not-settable throw that stops gating once flipped) + the matrix DTO- The superseded bug
bug-notification-pref-transitioned-still-disabled-after-5-4-shipped(tombstoned — its "minimal flip" premise was wrong) + notes.html mistake #40