Context
Commit 112bc4a83 (#5405, "dual-read browser localStorage keys during the rebrand") gave useLocalStorage a legacyKey param so a user's pre-rebrand gittensory_*-prefixed localStorage value would be read once and migrated forward to the new loopover_* key. It correctly set, e.g., const LEGACY_DISMISS_KEY = "gittensory_maintainer_onboarding_preview_dismissed";.
Two days later, commit 81e4ac34d (#5743, "Phase 5 - full-cutover rename all gittensory-* directories to loopover-*") did a blanket gittensory->loopover text substitution across ~480 files. That substitution wasn't scoped to directory/import paths only - it also rewrote two string literals that were supposed to stay as the old prefix:
apps/loopover-ui/src/components/site/app-panels/onboarding-preview-card.tsx:20-22 - LEGACY_DISMISS_KEY is now identical to the current key (loopover_maintainer_onboarding_preview_dismissed) instead of the old gittensory_... one.
apps/loopover-ui/src/components/site/notification-readiness-card.tsx:33-36 - same collision for the notification opt-in key.
Confirmed via git show 112bc4a83:... vs git show 81e4ac34d:... that these are the exact two call sites where key === legacyKey today - every other rebrand-migrated key (try-it.tsx's LEGACY_STORAGE_KEY = "gittensory.session_token", app.workbench.tsx's "gittensory.workbench.tab", app.runs.tsx's "gittensory.runs.views", app.index.tsx's "gittensory.onboarding") survived intact and is still genuinely distinct from its current key.
Failure scenario: a maintainer who dismissed the onboarding-preview card, or opted into notifications, before the rebrand now has their preference silently lost - useLocalStorage's fallback branch (apps/loopover-ui/src/lib/use-local-storage.ts:21-27) reads legacyKey, finds nothing under the new key (since it's the same key it just failed to find data under), and the user sees the onboarding card reappear / gets defaulted back to notifications-off with no way to know their old preference existed.
Requirements
⚠️ Required pattern - restore the gittensory_... literal for both LEGACY_DISMISS_KEY and the notification opt-in legacy key, matching the correct, uncorrupted shape already present at apps/loopover-ui/src/components/site/api/try-it.tsx:19-21 (STORAGE_KEY = "loopover.session_token" / LEGACY_STORAGE_KEY = "gittensory.session_token"). Do not touch any of the other already-correct legacy keys listed above.
Deliverables
Test Coverage Requirements
apps/loopover-ui is not covered by the src/** 99% patch gate (UI-only path) - add or extend tests for both components confirming the legacy-key migration path actually works.
Expected Outcome
A pre-rebrand localStorage value under either affected key is correctly migrated forward instead of silently appearing lost.
Links & Resources
apps/loopover-ui/src/components/site/app-panels/onboarding-preview-card.tsx:20-22, apps/loopover-ui/src/components/site/notification-readiness-card.tsx:33-36, apps/loopover-ui/src/lib/use-local-storage.ts:21-27, apps/loopover-ui/src/components/site/api/try-it.tsx:19-21 (the correct pattern to mirror)
Context
Commit
112bc4a83(#5405, "dual-read browser localStorage keys during the rebrand") gaveuseLocalStoragealegacyKeyparam so a user's pre-rebrandgittensory_*-prefixed localStorage value would be read once and migrated forward to the newloopover_*key. It correctly set, e.g.,const LEGACY_DISMISS_KEY = "gittensory_maintainer_onboarding_preview_dismissed";.Two days later, commit
81e4ac34d(#5743, "Phase 5 - full-cutover rename all gittensory-* directories to loopover-*") did a blanketgittensory->loopovertext substitution across ~480 files. That substitution wasn't scoped to directory/import paths only - it also rewrote two string literals that were supposed to stay as the old prefix:apps/loopover-ui/src/components/site/app-panels/onboarding-preview-card.tsx:20-22-LEGACY_DISMISS_KEYis now identical to the current key (loopover_maintainer_onboarding_preview_dismissed) instead of the oldgittensory_...one.apps/loopover-ui/src/components/site/notification-readiness-card.tsx:33-36- same collision for the notification opt-in key.Confirmed via
git show 112bc4a83:...vsgit show 81e4ac34d:...that these are the exact two call sites wherekey === legacyKeytoday - every other rebrand-migrated key (try-it.tsx'sLEGACY_STORAGE_KEY = "gittensory.session_token",app.workbench.tsx's"gittensory.workbench.tab",app.runs.tsx's"gittensory.runs.views",app.index.tsx's"gittensory.onboarding") survived intact and is still genuinely distinct from its current key.Failure scenario: a maintainer who dismissed the onboarding-preview card, or opted into notifications, before the rebrand now has their preference silently lost -
useLocalStorage's fallback branch (apps/loopover-ui/src/lib/use-local-storage.ts:21-27) readslegacyKey, finds nothing under the new key (since it's the same key it just failed to find data under), and the user sees the onboarding card reappear / gets defaulted back to notifications-off with no way to know their old preference existed.Requirements
Deliverables
LEGACY_DISMISS_KEYinonboarding-preview-card.tsxrestored to its pre-rebrandgittensory_...value, distinct from the current key.notification-readiness-card.tsxrestored to its pre-rebrandgittensory_...value, distinct from the current key.useLocalStorage.Test Coverage Requirements
apps/loopover-ui is not covered by the src/** 99% patch gate (UI-only path) - add or extend tests for both components confirming the legacy-key migration path actually works.
Expected Outcome
A pre-rebrand localStorage value under either affected key is correctly migrated forward instead of silently appearing lost.
Links & Resources
apps/loopover-ui/src/components/site/app-panels/onboarding-preview-card.tsx:20-22,apps/loopover-ui/src/components/site/notification-readiness-card.tsx:33-36,apps/loopover-ui/src/lib/use-local-storage.ts:21-27,apps/loopover-ui/src/components/site/api/try-it.tsx:19-21(the correct pattern to mirror)