Skip to content

The site says what the product does: pricing, mobile, security, privacy, terms and sync copy corrected - #967

Merged
NewWorldVenture merged 1 commit into
mainfrom
claude/roadmap-implementation-ld8bon
Oct 4, 2026
Merged

NewWorldVenture merged 1 commit into
mainfrom
claude/roadmap-implementation-ld8bon

Conversation

@NewWorldVenture

Copy link
Copy Markdown
Owner

Summary

Follow-up to #966. While fact-checking the FAQ, other public pages turned out to make claims the code does not back up. Each one below was verified against the code; the plan cards were checked against the tier matrix production itself renders on /pricing (catalogue defaults plus admin overrides — for these features they match the defaults).

/pricing

  • Trial card: "Your free trial includes Family Basic" was followed by "Up to 5 family members" and "10 AI requests/month". A trialing family is resolved to Basic (lib/server/entitlement.ts), and Basic's AI allowance is unlimited (AI_MONTHLY_ALLOWANCE[1] = null). Now: unlimited members, unlimited AI during the trial.
  • Family Basic card listed the Daily Briefing, Rewards and the Sports hub — all gated at Family+ (lib/constants/feature-catalog.ts, live matrix agrees). Family+ listed the AI Concierge, which is gated at Basic. Rewards and Sports moved to Family+, the Concierge to Basic, the Daily Briefing dropped from Basic (Family+ already lists the briefings).
  • Basic's prelude "Everything in your trial, plus:" implied the trial lacks Basic features; now "Family Basic also includes:".
  • Plan outcomes and the comparison table no longer say the trial gets "ten assistant requests a month" or that Basic prepares "the Daily Brief". (The in-app plan list in lib/constants/plans.ts was already right.)

/mobile and the in-app offline banner

  • No native iOS/Android app is published (the Expo companion is v0.1.0, unlisted). The meta description, hero and the "iOS & Android" point now describe installing from the browser.
  • Offline is a read cache that refetches on reconnect; there is no write queue. "Changes will sync when you're back" → "Changes can't be saved until you're back online"; /mobile says screens "refresh", not "sync".

/security (Trust Center)

  • The disclosure programme no longer "rewards researchers" or credits them "on our security acknowledgments page" — the bounty is planned in lib/marketing/trust-ledger.ts and no such page exists. That step now says reporters are kept updated until a fix (which the FAQ already promises).
  • Export is self-serve (Settings → Privacy, /api/privacy/export); whole-account deletion is by request, by a person. The control card and ledger row now say "Export anytime, delete on request". LAST_REVIEWED moves to today.

/privacy and /terms — please review, this is legal text

  • Privacy "Your rights": export is a download from Settings → Privacy; deleting the whole account is a request.
  • Terms: no longer "offers a free plan", nor says trials "convert to a paid plan unless you cancel" — the trial takes no payment method, never converts by itself, and locks when it ends. "You may … delete your account at any time" → "… ask us to delete your account".
  • Both pages' "Last updated" dates move to 2026-10-04 (LEGAL_REVISED), as the repo's rule requires for a policy revision.

Calendars

  • Switching band: "Two-way sync with Google, Apple and Microsoft calendars" → two-way with Google Calendar; Apple and Outlook through their published links (lib/calendar/providers.ts; Apple CalDAV is off unless APPLE_SYNC_ENABLED, Microsoft needs credentials).
  • In-app sync tooltips (lib/sync/capabilities.ts) stop offering a public ICS feed: app/api/sync/feeds/[token] issues no token today. The capability flags themselves are unchanged (pinned by tests/sync-capabilities.test.ts as the planned design).

Housekeeping

Guards

  • New tests/pricing-cards-match-plan-gates.test.ts: maps each card item to its catalogue feature; Basic may list nothing gated at Family+, Family+'s additions must be Family+, the trial may not be capped below Basic, outcome lines stay on the right side.
  • tests/marketing-claims-contract.test.ts now also reads pricing, plan outcomes, the legal pages and the offline banner, and forbids each retired claim (native apps, a free plan, 10 AI requests, rewards/acknowledgments page, two-way Apple/Microsoft sync, deferred offline sync).

Verification

  • npx tsc --noEmit, eslint on changed files, npm run i18n:gate: clean.
  • Every test file touching pricing, mobile, security, privacy, terms, plan outcomes, offline, switching, the trust ledger, revision dates or sync capabilities: 333 files, 5,720 tests, all passing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K


Generated by Claude Code

…cy, terms and sync copy corrected

Every claim below was checked against the code, and the plan cards against
the live tier matrix production renders on /pricing:

- Pricing cards. The trial card read "Your free trial includes Family Basic"
  and then capped it at 5 members and 10 AI requests; a trialing family is
  resolved to Basic (lib/server/entitlement.ts), whose AI allowance is
  unlimited. Family Basic sold the Daily Briefing, Rewards and the Sports hub,
  all gated at Family+, while the AI Concierge, gated at Basic, was sold as a
  Family+ extra. The cards now follow the gates, Basic's prelude no longer
  implies the trial lacks it, and the outcome lines and comparison cells drop
  "ten requests" and Basic's "Daily Brief".
- Mobile. No native iOS/Android app is published; the page now describes the
  browser install. Offline screens are a read cache that refreshes on
  reconnect, so neither /mobile nor the in-app offline banner promises that
  changes sync later.
- Security. The disclosure programme no longer "rewards" researchers or
  credits them on an acknowledgments page — the bounty is planned in the
  trust ledger and no such page exists; the step now promises updates until
  a fix, which the FAQ already did.
- Privacy, Trust Center, Terms. Export is self-serve (Settings → Privacy) and
  deletion of a whole account is by request, so the copy says so. The Terms no
  longer offer a free plan or a trial that converts to paid: the trial takes
  no card and locks when it ends.
- Calendars. The switching band no longer claims two-way Apple and Microsoft
  sync — Google is two-way, Apple and Outlook arrive by published link — and
  the in-app sync tooltips stop offering a public ICS feed nobody can get.

Revision dates move with the copy (lib/marketing/content-revisions.ts), /faq's
included, which #966 missed. New keys are translated into all six full
catalogues and ten retired keys are removed from all seven.
tests/pricing-cards-match-plan-gates.test.ts ties each card item to its
catalogue tier; the public-claims guard now reads pricing, plan outcomes, the
legal pages and the offline banner, and forbids each retired claim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
@vercel

vercel Bot commented Oct 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
bubaly Ignored Ignored Oct 4, 2026 8:41pm UTC

Request Review

@NewWorldVenture
NewWorldVenture marked this pull request as ready for review October 4, 2026 21:12
@NewWorldVenture
NewWorldVenture merged commit 7e19a9f into main Oct 4, 2026
7 checks passed
NewWorldVenture pushed a commit that referenced this pull request Oct 4, 2026
…ing "native iOS"

After #967 shipped, production's /mobile still described "an installable app
with native iOS and Android companions" in its meta description, its Knowledge
Center answer and its FAQPage structured data. Those come from admin-edited
rows (marketing_seo_pages, marketing_pages, marketing_aeo_questions) that
migration 0229 seeded before the correction, and the store overrides the code.

The six claims retired on 2026-10-04 now live in lib/marketing/retired-claims.ts,
shared by the copy contract and the editorial readers. getSeoPage drops a title
or description that states one, so the page's code value is used; every AEO
reader (per path, per category, site-wide, and the page-payload fallback)
leaves such a question out. A true editorial override still wins. The seed
generator's /mobile description is corrected and the contract now scans it.
"free plan" gains a word boundary so the tracked keyword "free planner for
parents" is not mistaken for the claim.

The new test is red without the reader changes (4 of 6) and green with them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture added a commit that referenced this pull request Oct 4, 2026
…ter, and a retired claim cannot come back from the database (#968)

* A migration lands in release order: retired holes stay retired, and no number is skipped

Production applies migrations with `supabase db push`, in version order, and
the CLI refuses a file numbered below the last version the remote ledger has
recorded unless it is given --include-all, which the production workflow does
not pass. A number below main's high-water mark that no file holds was being
treated as reservable, and that is how the closed branches came to collide:
#834 and #890 both held 0475/0476, #958 waited behind them on 0477, and
0488/0489/0490 each had to wait on the lower ones before they could ship.

The 43 holes at or below 0474 are now retired (RETIRED_MIGRATION_VERSIONS),
the reservations that left them released: work that once held one takes the
next free number when it lands. Above the mark the sequence has no gaps, so a
migration cannot skip a number to save it for later and leave a new hole.
The filename audit fails on either, naming the file and the number to use;
the test pins the retired list to exactly the numbers no file holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* The audit summary is counted from its register, and the one-row drift is corrected

The "Current reconciled audit counts" section was a hand-kept tally that every
checkpoint carried forward with "no recount was performed", and two of them
disagreed: one said 11,701 NOT STARTED / 2,484 IN PROGRESS, another 11,700 /
2,485 after LIBRARY-2E628A2A31CE moved to IN PROGRESS. A row-by-row recount of
Register B gives 14,538 unique IDs = 11,700 + 2,485 + 185 PASS + 159 FIXED +
PASS + 9 BLOCKED, 344 closed (2.37%), with no duplicate ID and no status
outside the five.

scripts/audit-register-counts.mjs derives those numbers from the rows and
compares them with the summary; the test fails when the summary, the heading's
declared size or a row's status drifts, so the next checkpoint states what the
register holds instead of copying the last tally forward.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* Register evidence reconciled with main: every MAIN row re-run, citations that never landed named

The 112 MAIN-* rows rest on "historical evidence retained verbatim" from the
upstream appendix (57f22c0), last re-run on 2026-09-27/28. Each now carries a
2026-10-04 reconciliation on main 663d99d: the 80 test files those rows cite
(756 tests) pass together, and the database probes they cite pass in the CI
Database job on that commit (run 37231782229: replay from nothing, every
boundary probe, ledger-repair rehearsal).

Four rows cited evidence that never reached main, and now say so with the
guard main actually carries: MAIN-F-E03's two tests were only on unmerged
commit 68a5a7a (main's are a-family-media-reference-is-never-rendered-raw
and a-private-image-does-not-outlive-the-session); MAIN-F-E02, MAIN-F-K03 and
MAIN-I-01 cited probes from unmerged commits f6b27a3/0c4ad3d5c (main's are
the 0391/0382 step-up probes, member-location-owner-check and
social-restriction-delete-check).

Across all 1,598 test/probe files Register B cites, 10 more rows point at
files absent from main; all ten are IN PROGRESS, so no closure rests on
missing evidence. Each now names where its file lives (unmerged meal-plan,
#890 or repo-connect branches) or that it is on none of the 604 branches.

Every reconciled MAIN row also states the production qualification: the
production ledger records 0001-0176 only (run 37207015645), so a FIXED + PASS
whose fix is a migration from 0177 on is a repository verdict, not a
production one. No status changed; the counts are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* Production handoff: the numbering rule from 0475 on, and the admin digest's 0471/0474

0471 and 0474 landed on main without an entry in the production migration
handoff; they now have one (what each does, deploy order 0471 then 0474, the
probes that prove them in CI). The handoff also states the release-order rule
the filename audit now enforces: holes at or below 0474 are retired, the
reservations that left them released, and work that held one takes the next
free number when it lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* A retired claim cannot come back from the database: /mobile stops saying "native iOS"

After #967 shipped, production's /mobile still described "an installable app
with native iOS and Android companions" in its meta description, its Knowledge
Center answer and its FAQPage structured data. Those come from admin-edited
rows (marketing_seo_pages, marketing_pages, marketing_aeo_questions) that
migration 0229 seeded before the correction, and the store overrides the code.

The six claims retired on 2026-10-04 now live in lib/marketing/retired-claims.ts,
shared by the copy contract and the editorial readers. getSeoPage drops a title
or description that states one, so the page's code value is used; every AEO
reader (per path, per category, site-wide, and the page-payload fallback)
leaves such a question out. A true editorial override still wins. The seed
generator's /mobile description is corrected and the contract now scans it.
"free plan" gains a word boundary so the tracked keyword "free planner for
parents" is not mistaken for the claim.

The new test is red without the reader changes (4 of 6) and green with them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* Ledger history restored: #869's checkpoint, the overwritten 06:47 section, two rows' evidence and a Path

Review 5984508520 named four historical-preservation blockers on main's
finalaudit.md that predate this branch, and one error in it:

- #869's 10:44 UTC release checkpoint (head f55b7a2) never reached main:
  #869 closed unmerged. Its 103 lines are restored verbatim.
- #842 (squash 77d73ae) rewrote the 06:47 UTC source checkpoint's header
  in place as the 14:46 UTC one. The 06:47 section as published (ledger
  commit d1afa3c) is restored verbatim beside #869's, under one dated
  "Restored checkpoints" heading that says neither is a current status.
- LIBRARY-3E7235F73734's Notes and SUPPORT-E8F3F434DAC5's Tests, Retest and
  Notes were replaced rather than appended to. The earlier text (d1afa3c)
  is appended back to each cell, quoted, with its source.
- SUPPORT-454BB6ECF37C's Path had been replaced with prose by ac654fe; it
  is restored to supabase/migrations/0475_meal_plan_slot_writes_are_atomic.sql,
  and the absence of that file from main is stated in the Notes instead.

The correction: eight meal-row annotations said 0475/0478 were "retired
below the high-water mark". They are above it (the retired range ends at
0474) and are being taken on main by the month-end bill and messaging work;
the annotations now say so. The 112 production qualifications no longer say
a later migration "is not applied": the ledger does not record it, and the
ledger alone does not prove a schema effect absent.

No ID, status, severity or count changes; the register still reconciles
(14,538 = 11,700 + 2,485 + 185 + 159 + 9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* Production handoff records every published branch migration candidate

Review 5984531842 asked that branch claims be recorded rather than inferred
from main. All 604 branches were read on 2026-10-04: 22 migration files
numbered 0465 or above exist only on branches, including #964's 0491 and the
colliding pairs at 0475, 0476 and 0477. They are listed with every branch that
carries them. Retiring the holes at or below 0474 deletes none of them; a
candidate that lands takes the next free number then, as the month-end bill,
calendar feed and messaging lanes do (0475, 0476, 0477/0478).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* Ledger: #842's overwritten Last Updated records restored, and #965's #779 evidence composed

Review 5984609845, as the designated ledger writer:

- #842 (squash 77d73ae) replaced seven dated "Last Updated" status lines in
  place: three from main as it stood before #842 (2026-10-01 09:10, 2026-09-27,
  2026-09-30 13:54) and four from the #842 branch at d1afa3c (2026-10-03
  06:47, 2026-10-02 19:01, 17:14 and 14:40). None appeared anywhere else in the
  file. Each is restored verbatim under "Restored Last Updated records", with
  the ledger version and line it came from; none is a current status.
- #965's ledger evidence at its head 0344101 (its one finalaudit.md hunk,
  the #779 dispatch-admission and release sections, 134 lines prepended to the
  top of the file) is composed here verbatim. #965 adding the same hunk later
  is an identical change and merges without conflict.

No register row, status or count changes (14,538 = 11,700 + 2,485 + 185 + 159
+ 9).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

* Migration registry: the second 0491 (#969) is recorded, and the landing map is labelled owner-directed

Review 5984812135: draft #969 publishes 0491_preserve_recurring_bill_anchor
beside #964's 0491 deadlock file. Both are recorded with their exact heads
as an unconfirmed collision. The 0475-0478 landing map is labelled as what
it is: directed by the repository owner in this session, with the
coordinator's request for cross-session confirmation noted, in the registry
and in the eight meal-row annotations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants