● Changelog · what shipped

Engine, Data, UX, Security — in Plain Product Voice

Curated entries — not the git log. Each item explains what changed for the reader of the site, why it matters, and links to where you can verify it live.

2026

ux

Easy / Quant reading modes across the dashboard

Pharma Signals, Smart Money Confluence, Emerging Signals and Insider Clustering all respect the Easy / Quant toggle in the top bar. Easy shows a one-line verdict per row; Quant keeps the full breakdown.

Until today the global Easy / Quant toggle had visible effect only on the homepage and on per-ticker pages. Four dashboard pages now mirror the same pattern. Easy on /dashboard/pharma renders one card per Phase 3 trial: ticker, condition, failure probability and a STRONG BEARISH / BEARISH / MIXED / LOW RISK verdict pill - no expand. Easy on /dashboard/confluence is a one-line "why" per ticker plus the DOUBLE or TRIPLE pill. Easy on /dashboard/emerging shows the type icon, headline and risk pill only. Easy on /dashboard/insiders is a single sentence per cluster ("5 insiders at Energy companies bought $14M..."). Quant mode keeps the previous detailed cards on every page. Reading mode persists across sessions in localStorage.

/dashboard/pharma/dashboard/confluence
uxengine

Smart Money Mirror Portfolio - adaptive thresholds

The dashboard portfolio builder, formerly "My Portfolio Builder" with all-Amazon allocations, is now Smart Money Mirror Portfolio with adaptive thresholds that scale to the number of funds the user has loaded.

Two regressions fixed. First: at $5K budget with five funds loaded, Stable strategy was collapsing into 100% AMZN because filters were hardcoded "fundCount >= 4". Thresholds now scale via active-fund-count factory: Giants requires 80% of loaded funds, Stable 60%, Mixed 40%. Null-safe score defaults so a ticker with no APEX row still passes a "score >= 45" gate. Mixed strategy was reweighted to prefer concentrated single-fund alpha bets (+8 score bonus when a manager holds >=8% of a name) so the feed actually mingles mega-caps with off-radar Druckenmiller / Ackman / Loeb picks. Second: the dashboard variant was rendering an AI Portfolio Analysis section that was calling a deleted API route - removed entirely (the deterministic rationale on every pick card was always there).

/dashboard/portfolio
mobileux

Mobile-responsive dashboard tables

Insider Clustering raw-feed table and the Emerging Signals 4-up legend reflow correctly below 480px instead of crushing columns into unreadable slivers.

Wrapped the Insider raw-feed 6-column grid in an overflow-x:auto container with a 620px minimum width so phones get horizontal scroll rather than crushed cells (touch-momentum enabled on iOS). The Emerging Signals signal-type legend (Lone Wolf / Conviction / Early Movers / Stealth Exit) was rendered with a rigid 4-column grid; now uses auto-fit minmax so it flows 4-up on desktop, 2-up on tablet, 1-up on phone. Headers (h1) across nine dashboard pages switched from a literal fontSize of 36 to clamp(24px, 6vw, 36px).

security

Next.js 15.5.18 - security advisory closed

Bumped Next.js to address GHSA-8h8q-6873-q5fj (Server Components denial-of-service).

npm audit fix moved Next 15.5.15 to 15.5.18, the patched release. 0 vulnerabilities remain at any severity. The repo security-scan workflow now passes on every push instead of failing on the dependency-audit step.

uxseo

Standalone /disclaimer, /story, /contact and /changelog.rss

New public pages and a real RSS feed for the changelog so readers can subscribe in any feed reader.

/disclaimer collects the legal footing (not investment advice, model-output caveats, past-performance, data-lag, no warranty, geographic scope, AI explainer note) on its own canonical surface and is linked from the dismissable bottom banner. /story indexes the case-study series (NVDA 65 -> 87 live, two planned post-2026-05-16). /contact lists the five inboxes (research, enterprise, founder, support, security) in one place. /changelog/rss.xml emits a real RSS 2.0 feed with content:encoded so Feedly and other readers can subscribe; the page also adds a link rel="alternate" for autodiscovery.

/disclaimer/story/contact
enginedata

Commodity sensitivity layer + macro catalyst calendar

Per-ticker beta vs oil / gold / copper / DXY is now refreshed weekly, and the macro catalyst calendar widens conformal prediction intervals around FOMC / CPI / NFP days.

Phase 1: a weekly GitHub Actions cron (Mon 06:30 UTC) computes 228 tickers' regression beta against four commodity reference series and stores it on stock_universe.beta_*. Phase 2: a monthly cron-job.org task pulls 47 upcoming macro events into the macro_catalysts table; the scoring pipeline now widens conformal half-widths the trading day before any FOMC / CPI / NFP release. The widening factor is calibrated and proprietary. The two layers run together but are governed by separate calibration windows so we can land them at different paces. Commodity factor enters the prior weight vector only after 2026-05-17.

ux

Google sign-in + onboarding rebuild

Google OAuth is wired end-to-end and the onboarding flow now uses spotlights, a celebration card and an explicit 4-page-hierarchy explainer slide.

Google sign-in landed on /auth/login and /auth/register, gated by NEXT_PUBLIC_GOOGLE_OAUTH_ENABLED. The callback exchanges OAuth ?code= for a Supabase session via auth.exchangeCodeForSession(). The onboarding checklist grew from 4 to 5 steps with a sticky "tried Quant view" flag, every step now spotlights its next-click target via a CSS pulse selector, and the welcome tour gained a slide that explains the page hierarchy (Signal Feed / All Stocks / Watchlist / Track Record) explicitly so first-time users don't miss the seven hidden dashboard pages behind the Discover dropdown.

dataengine

Universe expanded to 1,000 tickers (US + EU + Asia)

Added 626 names beyond the original 374 US-only set: London, Paris, Frankfurt, Milan, Zurich, Tokyo, Hong Kong, Korea, plus mid-cap US. Engine now multi-currency end-to-end (USD-equivalent P&L on virtual portfolio).

Expansion ran in three phases: first new mid-cap US batches, then EU native listings (.L .DE .PA .AS .MI .BR .SW), then Asian (.HK .T .KS). Migration 038 added currency + fx_to_usd_at_open to virtual_trades and formalised virtual_prices with currency/fx_to_usd, so paper-trade P&L stays USD-correct even when FX moves. Migration 039 cleaned 13 confirmed-delisted tickers (SGEN/QTS/STOR/SQ/GPS/CDAY/PKI/CEIX/TTM/BDEV.L/SOL.BR/AVST.L/DARK.L) and renamed bare symbols to the form Yahoo trades them under.

/dashboard
dataengine

100% daily coverage on the 374-stock universe (at the time)

Cron architecture redesigned: every ticker in the universe gets a fresh Framler score every trading morning, plus a recompute-zscore pass on the full cross-section.

cron-job.org runs nine 10-stock batches between 06:00 and 06:16 UTC. A GitHub Actions workflow then sequences another 29 batches for offsets 90 through 370. After all 38 batches land, recompute-zscore rebuilds the cross-section μ/σ that the z-score composite relies on. The universe at the time was 374 US tickers; it has since grown to 1,000+ — see the 2026-05-07 entry above for the expansion details.

/status
seo

Schema.org JSON-LD on every ticker, blog post, and pattern page

Centralised typed schema library emits FinancialProduct, Article, and BreadcrumbList graphs on ~395 URLs.

A typed builder library (src/lib/seo/json-ld.ts) generates Schema.org JSON-LD for ticker pages (FinancialProduct with sector, exchange, Framler score, verdict, price as PropertyValues), blog posts (Article + Breadcrumb via the shared BlogShell), and pattern pages (Article + Breadcrumb). Site-wide Organization + WebSite schema rides in the root layout. Result: rich-snippet eligibility on Google + structured citation hooks for ChatGPT, Perplexity, Claude.

security

Public security page + RFC 9116 disclosure

/security publishes the live security posture; /.well-known/security.txt gives bug-bounty researchers an instant contact.

The /security page lists 13 in-place controls (HSTS preload, CSP whitelist, DENY frame-ancestors, EU data residency, cron Bearer auth, admin role checks, cookie isolation, scheduled key rotation, public math invariant battery) and 7 roadmap items (2FA + WebAuthn, CSP nonce, per-IP rate limits, CSRF tokens, SOC2 Type I readiness, audit log, bug-bounty programme). Each claim is independently verifiable via headers, code, or endpoints — nothing is a marketing assertion.

/security
api

Public API documentation page

/docs catalogues seven read-only JSON endpoints anyone can hit without an API key.

Live (/api/health), pipeline freshness (/api/status), aggregate track-record (/api/track-record), 60-day HMM regime history (/api/regime-history), 46-invariant math battery (/api/diag/engine), single live quote (/api/quote), 30-day sparkline (/api/sparkline). Each entry shows method, path, parameters, sample response, cache policy. Covers the read surface only — authed and admin endpoints are intentionally excluded.

/docs
engine

Engine v2.2 — pattern-conditional variance dampener

When a confluence pattern fires AND its factors are tail-coupled, the engine narrows the prediction interval by up to 15%. Three independent witnesses → posterior strictly narrower than the prior.

Patterns previously moved only the MEAN of the forecast — a structurally supported pattern (Squeeze, Quality Compounder, etc.) pushed the score in its direction. Variance was unchanged regardless of how strongly the pattern was supported by the underlying factor co-movement (Schmidt-Stadtmüller tail-dependence λ). New patternIntervalDampener: when patternFires AND λ ≥ 0.20, total variance inflation shrinks linearly down to 0.85× at λ ≥ 0.40. Information-theoretic justification: three independent affirmations of the same direction — composite score, pattern label, empirical tail co-movement — give a posterior strictly narrower than the prior under non-redundant evidence. Capped at 0.85× so a runaway pattern can never collapse the interval.

engine

Engine v2.1 — math-foundation: piecewise α + VIX-conditional base variance

Short-horizon alpha at h=1 nearly doubles so 1d/7d forecasts actually separate across tickers. Market base variance now tracks daily VIX implied move instead of a fixed 16% literal.

A1 — piecewise alphaHorizonScale: prior pure √(h/90) gave h=1 alpha of only 0.105 of full alpha; nearly every bullish ticker clustered at P(positive 1d) = 62–65%. New scaler is 0.20·h^0.171 for h ≤ 7 (anchored so h=7 still matches √(7/90)) and √(h/90) for h ≥ 7 (h=30 and h=90 calibration anchors preserved). Top setups now land 1d P(up) 0.72–0.78, weak bulls 0.55–0.62 — readable spread instead of a flatline. Literature: Moskowitz-Ooi-Pedersen 2012 "Time series momentum" show the premium expresses faster than random-walk √t in the first 5–10 trading days. A4 — VIX-conditional base variance: refreshCalibrationCache() now also pulls vix_implied_move_30d from apex_calibration_constants (calibrate-vix cron writes it daily). Per-day variance becomes (vim²)/30 instead of the static (0.16²/252) literal. High-VIX regimes widen base variance for every ticker without per-ticker IV; per-ticker IV still overrides when available.

Methodology
engine

Engine v2.0 — forward-return composer + invariant battery

A unified Bayesian engine composes every layer into one coherent forward-return distribution per horizon, with an internal invariant battery that runs on every request.

The math symphony itself: a single composer that fuses the 13-factor composite, regime conditioning (BOCPD posterior), confluence patterns, conformal intervals (Vovk 2005), Schmidt-Stadtmüller tail-dependence, Kalman DLM exposures, and Mondrian binning into one forward-return distribution per 1d / 7d / 30d / 90d horizon — one mean, one 90% confidence interval, one probability of positive return. Each layer reduces to a no-op when its evidence is absent so missing data degrades gracefully. A battery of mathematical invariants (graceful degradation, monotone variance growth, distributional ordering, multiplier symmetry, CI containment) runs on every internal request and gates deployments. This release consolidates what previous notes labelled separately as v6, v7, v8, v9.1–v9.6, v10 and v11 — only two real architectural shifts have happened: v1.x factor scoring → v2.x the math symphony.

Methodology
mobileux

Mobile-first card layout for /dashboard/stocks

Phone width below 600px collapses each row into a 3-line card — ticker pills + action top, name middle, change + score + sparkline bottom.

Previous responsive rule kept a 6-column grid even at 320px, which overflowed on iPhone SE. The CSS rewrite uses nth-child grid-area assignments — JSX is unchanged, the row stays a single Link, tap target preserved across the whole card.

/dashboard/stocks
Changelog — Framler | Framler