Audit against the live feature set surfaced one missing entry and a few
soft phrasings:
- Free now lists "Ask follow-up questions on any past log" — the /api/chat
endpoint has no paid gate (router-level require_token only), so it's
available to every signed-in user. The landing-page screenshot already
showed it; the pricing page didn't mention it.
- "Per-group cross-asset summaries" → "Cross-asset indicator panels
(equities, rates, FX, …) with a one-paragraph AI read on each tab" —
more concrete about what the user actually sees.
- "Novice / Intermediate reading levels" → spelled out what each does
(Novice defines jargon; Intermediate is terse).
- Free's exclusion list explicitly includes "Daily email digest" so the
paid/free distinction reads cleanly without back-and-forth.
- Paid's daily-digest bullet now leads with the word count target
(~600 words) so the value is concrete, not abstract.
- Encrypted cloud sync bullet now names the actual security model
(PIN-derived in-browser + server-side outer wrap).
Added a small "Invite a friend" footnote — the credit ledger and invite
link both ship today; the rate kicks in with the payments rollout. Honest
phrasing keeps it from looking like vaporware.
Intro paragraph rewritten to lead with what's free (most of the editorial)
rather than what paid extends, since the free tier is the entry point.
Adds the unauthenticated surface that's needed to invite outsiders:
- Landing (/) — dual-purpose root: dashboard for logged-in users,
landing for everyone else. New maybe_current_user soft-auth helper
in app/auth.py supports it without disturbing the per-route
require_token deps on /news, /log, /upload, /settings.
- About, Pricing, Disclaimer, Terms, Privacy — own router
(app/routers/public.py), no auth dep, shared public_base layout
(brand link, thin nav, footer with legal links + ICO ref + date).
- Editorial positioning: news aggregator with a macro brain; tagline
"Understand markets. Don't gamble on them."; anti-trading-as-gambling
stance carried through About and Landing.
Legal pass following an independent lawyer-style review:
- Privacy: explicit UK-GDPR Art. 6 lawful-basis section; Art. 22
automated-decision line; explicit consent for sessionStorage sync
key (PECR); 30-day IP-log retention; Art. 21 objection right;
Children clause; Art. 33/34 breach-notification clause;
international-transfer mechanism (IDTA + UK Addendum). ICO
registration ZC098928 surfaced at the top.
- Pricing: paid-card AI-portfolio-analysis bullet rewritten to remove
advice-shaped wording ("what would invalidate the posture" gone);
added italic carve-out citing FSMA / FCA COBS.
- Disclaimer: separate EU/EEA carve-out + MAR 596/2014 Art. 3(1)(34)
commentator safe-harbour; "qualifies the Terms" line; hallucination
wording fixed.
- Terms: cl.4 explicit AI-training prohibition + harassment line;
cl.5 CCR 2013 14-day cancellation; cl.7 softened AI copyright
claim under CDPA s.9(3) ambiguity; cl.8 proportionate suspension +
pro-rata refund for paid users; cl.10 CRA 2015 Pt 1 statutory-rights
carve-out from the liability cap; cl.11 right to close account on
material change; cl.12 non-exclusive jurisdiction + UK consumer
local courts.
Code-side enforcement of the Privacy claim:
- openrouter.py: outbound OpenRouter calls now carry
X-OR-Allow-Training: false. DeepSeek doesn't expose a per-request
flag; the Privacy page discloses this caveat verbatim.
Apex domain prep:
- branding.APP_URL flipped to https://read.markets (was app.). DNS for
the apex already resolves; pending operator NPM step is a cert that
covers the bare apex + a 301 from app.read.markets. No hard-coded
subdomain references remain in code (verified with grep).
Nav + chrome:
- app dropdown gains Pricing / Terms / Privacy / Disclaimer links.
- login.html gains a small legal-links footer for the
highest-leverage moment to surface them.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>