compliance: flag-gate AI portfolio + cloud sync + Stripe; de-risk prompts; harden reviewer

Implements docs/read-markets-compliance-changes.md as flag-gated changes
(no deletions) so paused features stay in the tree for future re-enable.
All four flags default False so a fresh deploy is compliance-safe.

- New env flags: PORTFOLIO_AI_ENABLED, PORTFOLIO_SYNC_ENABLED,
  TICKER_UNIVERSE_AGGREGATE_ENABLED, SUBSCRIPTIONS_ENABLED.
- Gates: /api/analyze, /api/portfolio/sync*, /api/stripe/*, /pricing,
  ticker_universe writes, portfolio_analysis.analyse(). is_paid_active()
  returns True for any auth'd user when subscriptions are paused.
- Prompts (PROMPT_VERSION 10): universal _COMPLIANCE_RIDER prepended to
  every system prompt; watch list removed; price-target / close-above-below
  / trigger / forward-state-as-description rules added; SPECULATIVE
  pivoted to regime-only scenarios; daily + weekly digests tightened.
- Reviewer: deterministic regex/lexicon pre-check fail-closed under the
  Haiku call; portfolio rider gated by PORTFOLIO_AI_ENABLED; base prompt
  sharpened for forward-state and MAR forward-opinion patterns;
  ReviewerVerdict audit table; generate_with_review retry helper.
- Migration 0026: purge portfolio_sync + ticker_universe; create
  reviewer_verdicts.
- Copy: MAR cite fixed to Art 3(1)(35) + Art 20 + Del Reg 2016/958;
  portfolio reframed as browser-only viewer in disclaimer / privacy /
  terms / about / pricing / landing (en + it). TODO(legal) marker for
  lawyer sign-off on disclaimer.
- Tests: 13 lexicon + 6 reviewer compliance regressions; conftest enables
  all flags so existing 402 tests still cover their code paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Giorgio Gilestro 2026-05-29 19:57:12 +02:00
parent ee8384f1ba
commit 47dce1a1a4
38 changed files with 1188 additions and 279 deletions

View file

@ -37,18 +37,20 @@
<section class="public-section">
<h2 class="public-section__head">About the AI output</h2>
<p>
The strategic log, indicator summaries, and portfolio analysis are
generated by large language models from publicly available market
data and news. They can be wrong, incomplete, or out of date. Numbers
can be misread. Models occasionally generate inaccurate or invented
information (often called &ldquo;hallucinations&rdquo;). Treat them
as a <em>prompt to think</em>, not as facts to act on.
The strategic log and indicator summaries are generated by large
language models from publicly available market data and news. They
can be wrong, incomplete, or out of date. Numbers can be misread.
Models occasionally generate inaccurate or invented information
(often called &ldquo;hallucinations&rdquo;). Treat them as a
<em>prompt to think</em>, not as facts to act on.
</p>
<p>
The portfolio analysis is an interpretation of holdings <em>you
supplied</em>. It does not consider your overall wealth, debts, tax
position, or anything we don&rsquo;t see. It is not personalised
advice.
The portfolio feature is a browser-only composition viewer: it
parses a CSV you supply, computes neutral statistics (weights,
sector / currency / concentration breakdown), and shows them to
you. Your holdings stay in your browser; they are never sent to
or stored on the server. There is no AI commentary on your
portfolio.
</p>
</section>
@ -79,13 +81,22 @@
EU/EEA member state, nor in any jurisdiction where its provision
would require local licensing or registration. Where any output of
the Service could be construed as an &ldquo;investment
recommendation&rdquo; under Regulation (EU) 596/2014 (Market Abuse
Regulation) or its UK equivalent, it is non-personalised, produced
by a non-regulated source for educational purposes only, and the
operator (a) has no position in, or remuneration linked to, the
specific instruments mentioned in any individual piece of commentary,
and (b) is not a &ldquo;relevant person&rdquo; within MAR Art.
3(1)(34).
recommendation&rdquo; within the meaning of
<strong>Article&nbsp;3(1)(35) of Regulation (EU) 596/2014 (Market
Abuse Regulation)</strong>, with conduct duties under
<strong>Article&nbsp;20 MAR</strong> and
<strong>Commission Delegated Regulation (EU) 2016/958</strong>
(or the UK onshored equivalent), the operator&rsquo;s position is
that the Service publishes <em>non-personalised commentary on
public market data by a non-regulated source for educational
purposes</em>, and does not directly propose a particular
investment decision in any specific instrument. The operator has
no position in, and no remuneration linked to, the specific
instruments mentioned in any individual piece of commentary.
</p>
<p style="font-size:12px; color: var(--muted);">
{# TODO(legal): final wording on the MAR paragraph above is pending
lawyer sign-off. See docs/read-markets-compliance-changes.md. #}
</p>
</section>