Referrals: align localStorage key spec with implementation (R4 drift) #85

Closed
opened 2026-04-28 05:38:44 +00:00 by PlasticDigits · 8 comments
PlasticDigits commented 2026-04-28 05:38:44 +00:00 (Migrated from gitlab.com)

Summary

QA/spec documentation treats referral browser storage as a single key (yieldomega.ref.v1). The implementation correctly uses two concepts:

Purpose Key(s) Source
Pending referral (from ?ref= / path capture) yieldomega.ref.v1 in localStorage + sessionStorage frontend/src/lib/referralStorage.ts (REF_STORAGE)
Registered “my code” UX cache (plaintext for share links after registerCode) yieldomega.myrefcode.v1.<walletLowercase> Same file (MY_REF_KEY_PREFIX)

Functional behavior is correct; the gap is naming/documentation so checklists and humans do not assume one key covers both flows.

Prefer updating the spec/docs to match the source of truth (implemented keys). Renaming runtime keys would break existing users’ cached pending codes / stored plaintext unless a migration is added — unnecessary for a documentation-only mismatch.

Optional hardening (only if product wants strict naming): document a migration strategy if keys ever change; out of scope unless we deliberately rename.

Acceptance criteria

Cross-link: GitLab #64 referrals surface.

Labels / dependencies

Related to referrals checklist R4 under #64; no contract changes.

## Summary QA/spec documentation treats referral **browser storage** as a single key (`yieldomega.ref.v1`). The implementation correctly uses **two** concepts: | Purpose | Key(s) | Source | |--------|--------|--------| | **Pending** referral (from `?ref=` / path capture) | `yieldomega.ref.v1` in **localStorage** + **sessionStorage** | [`frontend/src/lib/referralStorage.ts`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/frontend/src/lib/referralStorage.ts) (`REF_STORAGE`) | | **Registered “my code”** UX cache (plaintext for share links after `registerCode`) | `yieldomega.myrefcode.v1.<walletLowercase>` | Same file (`MY_REF_KEY_PREFIX`) | Functional behavior is correct; the gap is **naming/documentation** so checklists and humans do not assume one key covers both flows. ## Recommended solution **Prefer updating the spec/docs to match the source of truth** (implemented keys). Renaming runtime keys would break existing users’ cached pending codes / stored plaintext unless a migration is added — unnecessary for a documentation-only mismatch. Optional hardening (only if product wants strict naming): document a **migration** strategy if keys ever change; out of scope unless we deliberately rename. ## Acceptance criteria - [ ] Product doc [`docs/product/referrals.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/product/referrals.md) explicitly lists **both** keys and their payloads (pending: JSON with `code` + `ts`; my-code: per-wallet JSON with normalized `code` + `ts`). - [ ] [`docs/testing/invariants-and-business-logic.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/testing/invariants-and-business-logic.md) (referrals / #64 rows) distinguishes **pending capture** vs **post-register wallet cache** keys so R4/R7 rows cannot be misread. - [ ] [`skills/verify-yo-referrals-surface/SKILL.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/verify-yo-referrals-surface/SKILL.md) row **R4** references the **`myrefcode`** key pattern (wallet-suffix), not only `yieldomega.ref.v1`. - [ ] [`frontend/e2e/referrals-surface.spec.ts`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/frontend/e2e/referrals-surface.spec.ts) / [`referral-path.spec.ts`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/frontend/e2e/referral-path.spec.ts) comments or assertions remain accurate (pending key checks stay on `yieldomega.ref.v1`; add a short comment if Anvil register tests assert share links without asserting my-code key). - [ ] Inline reference in [`ReferralsPage.tsx`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/frontend/src/pages/ReferralsPage.tsx) lede (if expanded) stays consistent — still **not** implying a single opaque “stable key” without naming shapes. Cross-link: GitLab [#64](https://gitlab.com/PlasticDigits/yieldomega/-/issues/64) referrals surface. ## Labels / dependencies Related to referrals checklist **R4** under #64; no contract changes.
PlasticDigits commented 2026-04-28 05:49:26 +00:00 (Migrated from gitlab.com)

mentioned in commit 2204641a7b

mentioned in commit 2204641a7b35f2a29246607e30a06a32f85e494a
PlasticDigits commented 2026-04-28 05:49:59 +00:00 (Migrated from gitlab.com)

Implemented (merged to main)

Documentation and UX copy now match referralStorage.ts: pending capture uses yieldomega.ref.v1 (localStorage + sessionStorage); post-register “my code” cache uses yieldomega.myrefcode.v1.<lowercase wallet> (localStorage only). Cross-links: product doc anchor #referral-browser-storage-keys, invariants #64 section + compact test map, skills/verify-yo-referrals-surface/SKILL.md, skills/README.md, yieldomega-guardrails item 15.

Verification checklist for @brouie

Leaving issue open for your sign-off.

## Implemented (merged to `main`) Documentation and UX copy now match [`referralStorage.ts`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/frontend/src/lib/referralStorage.ts): **pending** capture uses `yieldomega.ref.v1` (localStorage + sessionStorage); **post-register “my code”** cache uses `yieldomega.myrefcode.v1.<lowercase wallet>` (localStorage only). Cross-links: product doc anchor `#referral-browser-storage-keys`, invariants #64 section + compact test map, [`skills/verify-yo-referrals-surface/SKILL.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/verify-yo-referrals-surface/SKILL.md), [`skills/README.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/README.md), yieldomega-guardrails item 15. **Verification checklist for @brouie** - [ ] [`docs/product/referrals.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/product/referrals.md) — table lists both keys and JSON payloads (`code`, `ts`). - [ ] [`docs/testing/invariants-and-business-logic.md` § Referrals](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/testing/invariants-and-business-logic.md) — R4 vs R7 rows and #85 paragraph distinguish pending vs `myrefcode`. - [ ] [`/referrals` “Links that count”](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/frontend/src/pages/ReferralsPage.tsx) — names both key patterns without implying one opaque key. - [ ] Playwright (CI-equivalent): `npm run build` then `CI=1 npx playwright test e2e/referrals-surface.spec.ts e2e/referral-path.spec.ts --workers=5` — 3 passed locally after merge. Leaving issue **open** for your sign-off.
Brouie commented 2026-04-28 07:24:31 +00:00 (Migrated from gitlab.com)

Verified end-to-end on 7b0f37d. All 4 checklist items pass.

docs/product/referrals.md

Storage keys table at lines 33-36 lists both keys with full JSON payloads:

  • yieldomega.ref.v1 (localStorage + sessionStorage) — pending capture
  • yieldomega.myrefcode.v1. (localStorage only) — post-register

Plus an explicit cross-link to #85 at line 38: "do not assume a single yieldomega.ref.v1 row covers post-register 'my code'; that row is pending capture only." That covers the exact drift I flagged in the #64 close note.

docs/testing/invariants-and-business-logic.md

Three places where the spec drift is now resolved:

  1. Line 227 — explicit "Browser storage (issue #85):" paragraph distinguishing pending vs my-code, with cross-link back to product/referrals.md.
  2. Line 236 — R4 row says "post-register UX implies localStorage under yieldomega.myrefcode.v1. (not yieldomega.ref.v1)" — explicit "not" call-out.
  3. Line 239 — R7 row scoped to pending: "Asserts yieldomega.ref.v1 pending JSON".
  4. Bonus: line 310 summary row in the master invariants table also distinguishes both keys with #85 + #86 cross-links.

R4 vs R7 separation is clean now and matches referralStorage.ts at runtime.

Line 52 lede now names both keys explicitly: "Pending referral codes use key yieldomega.ref.v1 in localStorage and sessionStorage; after you register, your share-link code is cached per wallet under yieldomega.myrefcode.v1. plus your lowercased wallet address (localStorage only). Neither store owns codes onchain — ReferralRegistry + TimeCurve do."

No longer implies a single opaque key.

Playwright (CI-equivalent)

npm run build — built in 11.22s clean.

CI=1 npx playwright test e2e/referrals-surface.spec.ts e2e/referral-path.spec.ts --workers=5:
Running 3 tests using 3 workers, 3 passed (3.0s).

Matches your local result.

Closing #85.

cc @PlasticDigits

Verified end-to-end on 7b0f37d. All 4 checklist items pass. ## docs/product/referrals.md Storage keys table at lines 33-36 lists both keys with full JSON payloads: - yieldomega.ref.v1 (localStorage + sessionStorage) — pending capture - yieldomega.myrefcode.v1.<walletLowercase> (localStorage only) — post-register Plus an explicit cross-link to #85 at line 38: "do not assume a single yieldomega.ref.v1 row covers post-register 'my code'; that row is pending capture only." That covers the exact drift I flagged in the #64 close note. ## docs/testing/invariants-and-business-logic.md Three places where the spec drift is now resolved: 1. Line 227 — explicit "Browser storage (issue #85):" paragraph distinguishing pending vs my-code, with cross-link back to product/referrals.md. 2. Line 236 — R4 row says "post-register UX implies localStorage under yieldomega.myrefcode.v1.<wallet> (not yieldomega.ref.v1)" — explicit "not" call-out. 3. Line 239 — R7 row scoped to pending: "Asserts yieldomega.ref.v1 pending JSON". 4. Bonus: line 310 summary row in the master invariants table also distinguishes both keys with #85 + #86 cross-links. R4 vs R7 separation is clean now and matches referralStorage.ts at runtime. ## ReferralsPage.tsx — "Links that count" lede Line 52 lede now names both keys explicitly: "Pending referral codes use key yieldomega.ref.v1 in localStorage and sessionStorage; after you register, your share-link code is cached per wallet under yieldomega.myrefcode.v1. plus your lowercased wallet address (localStorage only). Neither store owns codes onchain — ReferralRegistry + TimeCurve do." No longer implies a single opaque key. ## Playwright (CI-equivalent) npm run build — built in 11.22s clean. CI=1 npx playwright test e2e/referrals-surface.spec.ts e2e/referral-path.spec.ts --workers=5: Running 3 tests using 3 workers, 3 passed (3.0s). Matches your local result. Closing #85. cc @PlasticDigits
Brouie (Migrated from gitlab.com) closed this issue 2026-04-28 07:24:50 +00:00
Brouie commented 2026-04-28 08:02:25 +00:00 (Migrated from gitlab.com)

mentioned in issue #86

mentioned in issue #86
Brouie commented 2026-04-30 02:14:16 +00:00 (Migrated from gitlab.com)

mentioned in issue #91

mentioned in issue #91
PlasticDigits commented 2026-04-30 05:25:10 +00:00 (Migrated from gitlab.com)

mentioned in issue #100

mentioned in issue #100
PlasticDigits commented 2026-05-13 16:01:24 +00:00 (Migrated from gitlab.com)

mentioned in issue #205

mentioned in issue #205
PlasticDigits commented 2026-05-20 04:19:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #223

mentioned in issue #223
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#85
No description provided.