v0.131.0Current2026-09-09
Simple view - a calm front door, and setup that waits until you have looked around
- Lyra grew to 56 pages and 40 nav entries, and that density had become the reason not to open it. Simple view is the new default: one calm page with your book, what moved, where government money actually went, the small caps already backed by that money, and which themes are running - then a quiet link into each. No charts, no carousels, no countdowns, nothing sliding. The nav shrinks to those same six places, and there is nothing to configure. Flip to Full view any time from the header (or the Explore drawer on mobile) and the whole dense desk is exactly where you left it - the switch is remembered.
- Setup no longer blocks the door. You can choose "Look around first" on the welcome screen and land straight in the app; the onboarding beats you skipped become a "Finish setting up" checklist on the home page, each one deep-linking into the same questions as before and saving to your account when you answer it. Nothing was removed from onboarding - only the moment it asks. The checklist reads your real state (holdings, watchlist, profile, alerts), so it ticks itself off and disappears when you are done, and it can never claim you are set up when you are not.
- Everything in Simple view obeys the same honesty rules as the rest of the app: government awards show the real contract description straight from USAspending with a provenance chip when any row is sample, theme scores say they are analyst-authored rather than live readings, unscanned holdings read "not scanned" instead of a fabricated price, and the news block says the feed is not connected rather than showing sample headlines. A drift guard in the test suite fails the build if any Simple-view destination stops existing.
v0.130.02026-08-14
The final sweep: all 35 remaining audit findings closed
- Every finding left on the honesty-audit register is now fixed - provenance, labels, colour, and placeholder zeros across the whole app. The biggest class: unmeasured values no longer render as measurements. A Solo holding or watch rule outside the scanned universe says "not scanned" instead of showing your own buy price as the market price, RSI 0.0 as a reading, or your target as the live quote; the account watchlist does the same; the ticker header renders "-" for the hourly change this feed cannot measure instead of a flat-looking +0.0%; and live IPO rows with unsynced columns show "-" and "Not categorised" rather than $0.0B raises and an asserted Software sector - with no bear/base/bull range modelled from a missing price.
- Sample data is now demo-tour-only everywhere, chipped per tile. The Economy / Markets / Commodities chart-pack boards - authored sample series that rendered on live pages with institution favicons implying RBA/Fed provenance - only render on the demo tour, every tile chipped Sample, with rates linking out as "check the live rate" instead of claiming attribution; live pages say the feeds are not connected. The IPO drawer carries the same Sample banner as the detail page; scout proposals badge demo payloads; a fresh live deploy with an empty signals table now shows honest empty states instead of the authored demo book under the LIVE badge; and the paper-bot tour can no longer replace a real executed account snapshot when revisited with a stale tour URL.
- Labels and colours now say exactly what the number is. The simulation lab computes EV at YOUR win-rate assumption (the old tile was $0.00 by construction) and labels its inputs as bull/bear scenario P&Ls; the win-rate strip shows "-" until a trade closes; risk:reward is tinted by threshold, zero deltas render neutral everywhere, theme totals share one tone scale, and the ticker page MetricBar diverges from a visible zero line so -2% can never draw longer than -45%. Onboarding stops overclaiming: coverage reads "US tech hourly - your tickers live on demand" (no phantom ASX/ETF hourly scanning), alerts "fire with each hourly scan" not "in real time", strategy names resolve from the registry, and fresh Solo reads carry their real computation time instead of a months-old demo stamp.
v0.129.12026-08-14
Sample headlines no longer ship in the live page source at all
- Live verification of 0.129.0 caught a last subtlety: the Command page passed the raw sample news feed to the ticker-tape and momentum board as props, so even though neither ever DREW a fabricated headline on a live page, the headlines still sat serialized in the page source for anyone reading view-source. Both call sites now gate the data itself - what may not render is never sent to the browser.
v0.129.02026-08-14
The re-audit verdict: every fix verified holding, and the three leaks it found are dead
- A fresh 6-reviewer audit re-checked all 47 original findings against the shipped code and confirmed every fix genuinely holds - then went deeper and found three critical leaks the first pass missed. All three are fixed. The intelligence ticker-tape on Command was still streaming fabricated Goldman/Reuters headlines under a pulsing green dot on live pages: it now takes the resolved feed with its provenance, streams live rows as live, sample rows only on the demo tour under a Sample chip, and says "Live news feed not connected" otherwise.
- Signed-out visitors on a live deployment no longer inherit the authored demo book as "Your book". The demo NVDA/AMD portfolio and watchlist rendered under the green LIVE badge with real trigger-zone narration ("price is in your $128.00 buy zone... Your move.") - an anonymous visitor now gets an honestly empty book with the app's real empty states. And the hype meter can no longer mix provenance: when the nightly hype sync has no rows, it says so instead of quietly substituting sample buzz scores under the Live banner.
- Two small dishonesties introduced by earlier fixes are also corrected: the calendar drawer now carries the same Sample-dates provenance chip as the board behind it (and its earnings box says "Not wired yet" instead of mislabelling live events as Sample), and the wire only carries the illustrative macro/policy headlines on the demo tour - a live or Solo wire with no newsflow is honestly empty, with Solo no longer inheriting the authored demo signal-change rows. The remaining 36 medium/polish findings from the re-audit are logged for the next wave - none is a fabricated number a trader could act on.
v0.128.02026-08-14
Honesty audit closed out: the last 12 findings patched, none deferred
- Every remaining finding from the 47-item visualisation audit is now fixed - including the ones 0.127.0 deferred as "needs backend work". Your Solo watchlist threshold is finally yours: the add-rule form saves the signal-score trigger you type on this device, and the trigger board narrates YOUR target instead of a hardcoded 70 you never set. A Solo holding outside the scanned universe now says "not scanned" instead of rendering RSI 0.0 and Signal 0 as if the engine measured an extreme reading.
- Provenance chips reached the last unlabelled corners. Every sample calendar row now carries its own Sample chip - on the agenda, the month grid, and the Event Risk Alert countdown - not just one 9px footnote. The Command countdown shows the importance word (high/medium) for calendar moments instead of a pseudo-precise "heat 88" that looked like the curated blended score. The community Ideas board badges demo content the way the Scout feed always did, and speculative IPO records for real private companies (Stripe, Databricks, SpaceX and eight more) are titled "(illustrative)" like their fictional siblings.
- Colour and copy stopped overclaiming. The track-record win rate is no longer tinted by a different metric (a sub-50% win rate could render green) - the sign colour sits on the average return it measures. Model Lab resemblance bars are scoped to positive drivers, so a score DETRACTOR can no longer draw as an innocent empty "0" bar. World Radar copy now says its theme scores are authored research updated with content releases, not live engine readings. The IPO explorer explains WHY its Return column is empty on live deploys and hides the Return sort instead of ranking on missing data; the unrendered fabricated indicator snapshot on the trading demo intent is deleted; the onboarding portfolio illustration drops its meaningless progress bars.
v0.127.02026-08-11
The honesty audit: every fabricated visual in the app, found and removed
- A full-app audit (8 parallel reviewers plus a manual sweep) hunted the same crime the ticker page had: invented data drawn as if measured. 47 findings, 13 of them critical, all triaged. The Comparison Lab was the worst - its entire 30-hour multi-ticker "history" was a Math.random walk regenerated on every server restart, with a hover scrubber over fabricated timestamps. It is rebuilt on real scanned signals: real current values per metric, ranked bars, and a full side-by-side table - no time series is drawn because none is recorded, and none is invented.
- Fabricated context could reach your REAL holdings, and no longer can. The Command page fed hardcoded demo headlines (fake Goldman/Reuters stories) into the "Across your names" orientation and the holdings intel slides on live deployments; the countdown hero ticked second-by-second toward sample earnings dates a trader could position around; the Live Wire substituted demo signal changes under a pulsing green "Live" pill and a footer claiming they came from the engine. All of it now follows one rule: live rows render as intelligence, sample rows render only on the demo tour (clearly chipped), and a live page with no feed says so instead of faking one. The paper-bot guided tour also stops writing its scripted $150 fill into your durable paper account - tour fills are display-only now.
- Dozens of smaller crimes fixed in the same pass: the DCA calculator no longer adds random noise to its price path (same inputs, same answer, every time); NaN can no longer render as a plausible "0.0"; future events read "in 10 hours" not "10 hours ago"; the Model Lab stops showing invented per-stage execution times and relabels its reveal as the staged replay it is; zero-count funnel bars draw nothing; fake community-member avatars, invented "Live" badges on unfetched quotes, and the dead fabricated-OHLC/score-history chart code are all gone. The IPO deep-dive now banners sample records. What could not be fixed without backend work is labelled honestly instead.
v0.126.02026-08-11
The ticker page stops faking history and shows the real decision
- The two big charts on a ticker page were fabricated. The "signal score history" bars (58, 57, 55 ... down to now) and the "momentum shift" MACD histogram drew six invented bars easing into a single real value - only "Now" was ever measured, the rest was a seeded ramp pointed in the right direction. That is the exact opposite of what Lyra is for, and it sat in the prime spot while the data a trader actually needs was buried below. Both are now deleted, along with the code that built the fake lead-in.
- In their place, real data. A "Setup read" scorecard shows the five score factors the server actually computed - RSI, MACD, price location, trend, volume - each annotated with its live metric and the band the oversold-recovery strategy wants (RSI 58.1 against the 35-50 reset band; 14.6% above the 60-day low against the ~10% target), so you can see WHY a name scores what it does and which factors are missing. A "Since last scan" panel shows the one time comparison Lyra genuinely has: the previous scan and the current one, two measured reads per metric, nothing interpolated between them.
- Also de-roboted the app chrome: the live-status, stale, and mute/alert pills in the header now render in the Apple system typeface instead of the monospace terminal font. Numbers and tickers keep their tabular mono; status and labels read like the rest of the OS.
v0.125.02026-08-05
A light theme, app-wide - dark stays the default
- Lyra is dark by nature, and stays that way by default - but you can now switch the whole app to a light theme from Settings > Appearance. It is a real app-wide theme, not a one-off surface: every panel, chip, chart, control and the Model Verdict re-theme together into a pearl-and-emerald light-glass palette, and the choice is remembered on your device. A tiny script applies it before first paint, so a light-theme user never sees a dark flash.
- Under the hood the design-token system (lyra-ux v1.1.0) was upgraded to carry both themes: every colour token gained an RGB-channel form so the Tailwind utilities reference `rgb(var(--token) / <alpha-value>)` - opacity modifiers keep working AND the whole utility layer re-themes when the light palette overrides the variables. The glass panel primitives got explicit light values (frosted white on pearl). The Model Verdict surface, previously a fixed light-glass card, now themes with the app: dark on dark, and the full light-glass render in light. Drift-checked (TOKENS.md / CSS / Tailwind agree across both themes), type-clean, 1186 tests green.
v0.124.12026-08-03
Bulk insider ingestion passes its acceptance gate
- The bulk insider store is complete and verified: 10,109 companies across 49 quarters (2014 to early 2026), against 991 companies for the entire twenty-hour per-document backfill. Agreement was measured properly - only on company-quarters where BOTH sources genuinely cover the window - and came in at 396 of 400, or 99%. Four disagreements are filed rather than waved through, one of them diagnostic: a company where both parsers report the same dollar magnitude with opposite signs, which is a sign-convention bug in one of them and would invert the feature for affected names.
- Storage was rewritten to compact columnar rows after the first attempt filled the disk - roughly 95 bytes per transaction instead of 278, since JSON key names were most of the weight. The whole market over twelve years now fits in about 250 MB, and the column order is recorded in each file so a future layout change is detected rather than silently misread.
v0.124.02026-08-03
The build path, and the ingestion that makes it possible
- Generation 3 refuted the thesis three generations had run on. Data volume was never the binding constraint: three generations of enrichment moved the deployed model by a statistically undetectable amount, while on IDENTICAL data a different model class went from failing every floor to the best result ever recorded. And the sharpest finding of all - 201,494 insider filings, 1.4 GB, twenty hours of downloading, reached the model as exactly TWO numbers. A new build backlog now orders the work by that evidence: statistical power first, then feature representation, then estimator class, then survivorship.
- Ticket one is built: bulk insider ingestion. The SEC publishes the same filings as quarterly pre-parsed bundles, and a single quarter covers 4,739 companies where the entire per-document backfill covered 991 - fourteen megabytes and two seconds against twenty hours and two rate-limit bans. The new source carries what the old path threw away: buy CLUSTERS across distinct insiders (the effect the research literature actually documents - 276 companies showed a three-or-more-insider cluster in one quarter alone), officer versus director versus ten-percent-owner roles, purchase size relative to the insider's own stake, and recency. Filing date remains the as-of key, open-market transactions only, eight new pins.
- This unblocks the real fix: widening the universe from 991 companies toward the full listing. That is what refused generation 3's challenger - not a weak model, but 6,165 test rows unable to separate a real margin from zero.
v0.123.12026-08-03
The audit corrects the release: "first ever" was false
- An adversarial audit of the generation-3 evidence checked 223 numeric claims against source and found 220 correct - every paired verdict reproduced bit-exactly, so the refusal decision stands unchanged. But three FRAMING claims were wrong and are now corrected everywhere they appeared (board, generation log, report card, in-app evidence pack, release notes): the challenger's separation from the volatility null was called "the first in any generation" when generation 2's champion had already done it at +0.48 - the true claim is the LARGEST on record (+0.67), and the first by a challenger. A claim that no prior model cleared both the chance line and the volatility null was also false (both generation-2 models did), and the boosted challenger ALSO missed the 1.5x lift floor, where only the linear model's failure had been stated.
- Smaller corrections: the champion's deployment restatement rounds to 5.5% not 5.6%; the reference scorecard is unproven this generation rather than refuted (its interval now spans 1.0); and "statistically unchanged across three generations" overreached to a leg that can never be paired, since generation 1 archived no per-row scores. One item is left open rather than papered over: the standing rule that any lift above 2x triggers a leakage decomposition fired on the 2.13x result and is only partially discharged - the three known leak classes are structurally impossible now, but no ablation waterfall was run. It is recorded as a generation-4 blocker.
- The append-only attempt ledger keeps its original entry; a correction record was appended beside it rather than rewriting history. Grades are unchanged - the errors were in superlatives, not measurements.
v0.123.02026-08-03
Generation 3: the system refuses its best-ever number
- Insider conviction reached the training history at last - 205,189 SEC insider-transaction filings covering 99.86% of training rows, plus federal contract flow for 207 companies. On the untouched generation-3 holdout, a nonlinear challenger scored 2.13x (interval 1.73 to 2.49): the highest honest number this project has produced, and the first model in any generation to separate from the volatility null with its confidence interval clear of zero. It was NOT promoted. Paired against the deployed champion on identical rows the margin was a statistical tie (+0.33, interval -0.09 to +0.84), and the rule written before the number existed keeps the incumbent on a tie. The refusal is logged with the same prominence a promotion would have received.
- The first cross-generation paired test ever run here retired two previously-reported movements as noise: the champion scored on generation-3 versus generation-2 features differs by -0.18 (interval -0.57 to +0.20), meaning the model is statistically unchanged across three feature generations - the earlier 1.72 to 1.94 "improvement" and this cycle's 1.94 to 1.69 "decline" were both within noise. Calibration was honestly downgraded (A- to B+) after the champion's error tripled on a pure feature change, a sensitivity the previous grade could not have known.
- Also learned: adding insider features to the linear model made it WORSE (it failed both floors at 1.23x) while the depth-2 trees reached 2.13x - the insider signal lives in interactions only a nonlinear model can read. Grades after generation 3: Accuracy C+, Calibration B+, Process A, Estimator C+ (up), Data C+ (up, nine of ten domains lit), Honesty A. The generation-3-versus-2 board is published with every number independently re-derived from the archived reports.
v0.122.02026-08-03
The verdict comes into the app: run a model, see whether it actually predicts success
- The post-run reveal is now a first-class surface. After a model runs (and on the Models & methods tab) Lyra shows the Model Verdict - a light-glass panel that answers "does this model genuinely predict success?" with the full backtest evidence: the deployed champion lift against the chance line with its confidence interval, what the top picks actually contained, calibration reliability, regime honesty quarter by quarter, the weight-flip that shows the intuitive bets were backwards, the leakage decomposition, and the six-dimension report card. The same information design as the modelling-space render, brought into the product and wired to live data.
- Every measured number is read from the generated model-evidence.json (regenerated by the backtest record step) - nothing numeric is hardcoded except the definitional chance line (1.0x) and the labelled NORTH-STAR target thresholds. Keyed to the current gen-2 evidence shape (the champion reads 1.94x holdout), dead data domains render as unbuilt rather than a faked bar, the survivor-bias caveat travels with the numbers, and surfacing stays shadow-live / Beta gated. The old collapsed dark evidence accordion is retired in its favour; 18 tests pin the honesty contract on the new surface.
v0.121.02026-08-03
The government domain lights up: federal contract flow, point-in-time honest
- A ninth data domain comes alive: USAspending federal-contract awards, bridged to public companies by CIK-anchored exact-name matching with the guards the feasibility probe ratified (UEI required, generic-name rejection, awards fetched by recipient id - never by fuzzy name search). Every aggregate is point-in-time disciplined (only transactions dated on or before the scoring date count), totals are documented as a floor (subsidiaries book separately), and an unmatched company stays honestly unavailable rather than guessed.
- Wired end to end with train/serve parity: the historical corpus assembler and the live scanner embed identical shapes, pinned by a test that fails if the two mappings ever drift. 30 new tests cover the source (as-of discipline, cache semantics, name-normalization traps like CELSIUS, truncation labelling) and the seams. The bridge cache for all 991 corpus companies is filling now against USAspending - a different host entirely from the throttle-sensitive SEC backfill - and generation 3 picks the domain up automatically if the cache lands in time, generation 4 otherwise.
- Live-verified before shipping: Lockheed Martin resolves to $1.16B in trailing-2-year obligations, Kratos rolls up its subsidiary bookings through the SAM parent hierarchy, and the Celsius Holdings control correctly refuses to match.
v0.120.12026-08-03
The threshold sweep lands: the model knows quality, not touches
- The pre-registered tier-by-barrier sweep (+10% to +300%, 27,007 rows, single holdout look) delivered its verdict: under a plain "did the price touch +X%" label, the model beats the jumpiness baseline NOWHERE - raw barrier-touching is volatility physics at every threshold. But yesterday's within-tier edge used the quality label (doubled AND stayed listed AND liquidity grew) - so the discovery is that the model's real skill is knowing which risers STAY REAL, not which prices spike. The flagship label survives; the slider UI must present touch probabilities as mostly-volatility and attach the skill claim only to the quality outcome. Two of three pre-registered predictions confirmed (+10% is a market-direction question at 81% base rates; +200/300% too thin to claim), one refuted (no +30-50% sweet spot exists under plain touch).
- Form 4 backfill: a second, harder SEC throttle wave was caught and stopped mid-burn (nearly all requests failing); the job resumed after a 45-minute cool-down at the 2 req/s multi-day tail pace, now recorded in code. Coverage ~89%, all failures retryable, generation 3 expected this evening.
v0.120.02026-08-02
The convergence completes: one visual language across the entire app
- Every remaining surface joined the lyra-ux design system: the signals stack and ticker detail (the densest data surfaces, ~770 class migrations), the full onboarding flow (three mixed styles unified, every animation preserved), trading, the paper bot and trade plan (with the simulated-money honesty framing diff-audited verbatim), and the floating feedback and chat widgets - which turned out to be live on every route, not orphans as inventoried. Across the whole sweep: zero raw hex and zero legacy opacity literals remain in component classnames; the only hex left is documented chart paint (SVG fills that cannot resolve CSS variables), each occurrence annotated in-file.
- Final gates on the finished convergence: token drift check green, zero type errors, clean production build, 1187 of 1187 tests passing, and every provenance string verified untouched - research-only labels, shadow-live framing, paper-trading disclaimers, AI-generated answer notices. The design-owner decision log (lyra-ux/notes/) records every judgement call the sweep made: nearest-token rulings, category-colour tensions in charts, deferred tap-target fixes, and one proposed new token (a distinct warn-orange) left as a future TOKENS.md version bump.
v0.119.02026-08-02
The convergence, round one: most of the app now speaks the Model Lab language
- The app-wide restyle landed its first big wave: the shell and chrome (P0 - navigation, drawers, badges, error pages, and the font conflict resolved in favour of the native SF stack), activation cinematics, discovery and thematic surfaces, intelligence feeds, market tools, the book views, account and community, and the marketing/legal pages all converged on the lyra-ux token system. 129 files migrated with zero test regressions - 1187 of 1187 tests pass, the build is clean, and the token drift check stays green.
- The old white-on-black opacity dialect is down to four straggler files, and the glass panel system now reads its colours from the versioned token variables with all accessibility fallbacks intact (reduced transparency, no-backdrop-filter, AA-safe solids).
- Operational honesty note: the Form 4 insider backfill drew SEC throttling after hours at the 10 requests-per-second ceiling (failures spiked, throughput collapsed) - backed off to ~4 sustained with failed documents automatically retried on resume; the pace comment in the code now records the empirical lesson.
v0.118.02026-08-02
The Model Lab becomes the design north star, and the design system becomes law
- The Model Lab is rebuilt to the founder-approved target: a three-panel command surface - configure on the left (archetype pills, data-source availability grid, one gradient CTA), live model execution in the centre (real engine stages with green completion rings, pulsing live dot, per-stage outputs and elapsed times, a four-cell stats strip), surfaced candidates on the right (expanded rank-1 card with probability, resemblance, confidence, strongest domains and the real risk-gate verdict). Every number binds to the real data flow; the reference mockup's illustrative values appear nowhere. Mobile stacks the panels with a sticky run button. A long-standing bug fell out of the rebuild: React StrictMode silently froze every dev run at "Queued" - fixed.
- Lyra now has a versioned design system: the new lyra-ux workspace carries TOKENS.md v1.0.0 - 26 named colour, shape and motion tokens extracted from the app's proven palette - mirrored into a CSS variables file and the Tailwind theme, with a drift-check script that fails the moment spec and mirrors disagree. A dead light-mode palette from an earlier design era was removed after verifying zero usages. PATTERNS.md defines the component vocabulary (panels, stat cells, chips, status pills, the one-gradient-CTA rule) plus design-level honesty rules: provenance banners are part of the composition, status colours carry meaning, and an empty state never fakes a number.
- An estate-wide inventory mapped all 273 view components across ~56 routes into 12 disjoint restyle packages with dependency ordering - the groundwork for converging the whole app onto the Model Lab's visual language.
v0.117.02026-08-02
The volatility null: the right chance bar arrives, and Accuracy is regraded under it
- A barrier label ("touches +100% in 12 months") is largely a volatility measurement - a jumpy stock hits any target more often with zero information involved - so comparing against random selection was too easy. A parameter-free jumpiness-sort now runs as a STANDING reference model in every eval: it scores 1.41x on the gen-2 holdout where random scores 1.0x. The champion beats it on identical rows (paired delta +0.48, CI90 from +0.05 to +0.92) - the first rigorous evidence the model finds something beyond wildness - and Accuracy is honestly regraded B- to C+ because the floor of that margin is thin. The bar moved, not the model.
- Within-tier verdicts are now part of every eval: each cap tier's picks are judged against that tier's own jumpiness-sort, paired, with thin tiers reporting "insufficient evidence" instead of fake numbers. First results: micro and small caps (the actual hunting ground) lean positive but unproven; the celebrated large-tier 2.84x was the null in disguise - pure jumpiness scores 6.15x inside that tier and the champion significantly loses to it there. Standing product rule: no tier is claimed until the model beats that tier's own jumpiness baseline.
- The government domain moved from designed to evidence-scoped: a USAspending feasibility probe confirmed exact-name matching works (15 of 15 known contractors matched with dated, point-in-time-safe award records) with the real risks documented - subsidiary booking means v1 award totals are a floor, and awards must be fetched by recipient id, never name search. Also: gen-3 pre-registers an explicit volatility feature - if the famous negative technical/liquidity weights collapse, they were volatility proxies all along; plus an overflow fix in the weak-calibration fit, found by feeding it raw sigma scores.
v0.116.02026-08-02
The cross-generation paired test exists before generation 3 needs it
- New versus-scores command: aligns two generations' archived per-row holdout scores on identical (symbol, entry-date) windows and runs the paired symbol-clustered difference test across them - turning "the improvement came from the data" from a side-by-side eyeball into a measured, paired claim. Honesty built in: one-sided rows are dropped and counted, label disagreements between archives are excluded and counted, and a mismatch rate above 0.5% invalidates the whole comparison out loud (a changed label definition kills paired claims). Every run logs itself to the trial ledger.
- Four pins cover the aligner before it matters: identical archives yield exactly zero delta, a consistent improvement is detected with the interval clear of zero, one-sided rows cannot silently vanish, and a label-definition drift refuses to produce a verdict. Generation 3 will run this against generation 2's archive on day one - the comparison generation 1 made impossible by never archiving scores.
v0.115.12026-08-02
Backfill at the ceiling
- Founder-approved: the Form 4 insider backfill now paces at the SEC's published maximum of 10 requests per second - the 0.1-second floor between requests makes exceeding the ceiling impossible by construction. Remaining backfill time drops to roughly 5-6 hours.
v0.115.02026-08-02
Tuning under discipline: a pre-committed sweep picks the gen-3 challenger config
- Boosted-family hyperparameters now thread through the whole lifecycle seam (train, walk-forward, frozen artifact, CLI) and are stamped into every artifact and ledger entry - no more anonymous configs. Passing knobs to the logistic is an error, never a silent ignore. Pinned by test.
- A four-config hyperparameter sweep ran on the development split with the selection rule written down BEFORE any result was seen: highest walk-forward lift, ROC tiebreak. Winner: 200 rounds with finer split thresholds, at 1.393x lift versus the default 1.34x - frozen as the generation-3 challenger config, with its weak spot (thinnest worst-quarter of the five) recorded next to the win. Every attempt is in the trial ledger; the 1.5x floor stays unmet, so nothing is promoted.
- The Form 4 insider backfill pace was raised from ~5 to ~8 requests per second - still comfortably inside the SEC's published 10 req/s fair-use ceiling - cutting the remaining backfill time by roughly a third. The generation-4 note is recorded: when the corpus widens beyond the current 991 names, the SEC's bulk Insider Transactions Data Sets are the right training source, with the raw-XML parser kept for live parity.
v0.114.02026-08-02
The evidence sprint: first estimator bake-off, calibration measured to its edges
- First real-data estimator bake-off, run on the development split only: the depth-2 boosted-trees family beat the linear retrain on the identical purged walk-forward (lift 1.34x vs 1.27x, ROC 0.585 vs 0.548, and no zero-hit quarters where the linear model had them) - but failed the 1.5x absolute floor and never threatened the frozen champion. Estimator sophistication regraded D+ to C- on that evidence; the seat is only winnable at generation 3's fresh one-shot holdout. The attempt logged itself to the new trial ledger, refusal included.
- Calibration measured to its edges from the archived per-row scores: level is near-perfect (calibration-in-the-large -0.05), the 3%-deployment-base restatement survives a 50-draw prevalence-shift stress test (median ECE 0.006, zero statistical rejections), but the recalibration slope is 0.755 with CI90 from 0.57 to 0.98 - the probability spread is mildly overconfident, a deficiency ECE cannot see. The fix seam shipped inert: artifacts can now carry a logit-linear calibration block (validated at load, monotone by construction so rankings never change, absent means byte-identical legacy behaviour) - whether generation 3 turns it on is a standing-loop decision, not a hot patch.
- The delisted-data probe settled a roadmap question with evidence: the free price source does NOT serve delisted histories (SVB Financial and First Republic return nothing, and recycled tickers are an identity trap) - so killing survivorship bias, the binding data constraint, requires a paid corpus source or a CIK-anchored EDGAR+OTC assembly. Recorded in the report card so the decision is made deliberately, not discovered mid-build.
v0.113.02026-08-02
Valid statistics for the fight: paired tests, weak calibration, an attempt ledger
- The champion-vs-challenger verdict now rests on a paired symbol-clustered bootstrap of the difference on identical rows, gated on the delta interval excluding zero - replacing the invalid habit of eyeballing two overlapping confidence intervals, which can silently block a genuinely better challenger. Applied retroactively to generation 2: delta-lift -0.02, CI90 from -0.24 to +0.28, no detectable difference - the refusal stands via the pre-committed must-beat rule, now on sound statistics. A pin constructs the exact failure case (marginals overlap, paired test detects) so the invalid comparison can never quietly return.
- Every metric block now reports weak calibration alongside ECE: recalibration slope and intercept plus Spiegelhalter's z with a p-value - the intercept is the corpus-prevalence-vs-deployment-prevalence problem measured instead of asserted. New behavioral pins test the model itself, not just the pipeline: identity invariance (a ticker can never move a score), batch invariance (no cross-row coupling can sneak into serving), and directional-expectation sweeps that assert sign-consistency with learned weights - with technical and liquidity explicitly excluded from positive expectations because their negative signs are validated findings, not bugs.
- A selection-bias ledger (lyra-evals/model-attempt-log.jsonl) now records every retrain, comparison, holdout scoring and promotion decision - including refusals - so the trial count behind any confirmed number is auditable. Per-row holdout scores are archived each generation from now on, enabling paired cross-generation tests that generation 1 never made possible.
v0.112.02026-08-02
Model evaluation operationalized: generation vs generation, forever
- Every model generation now ends with a head-to-head board: the new generation against the previous one on the same holdout discipline, so improvements and regressions are observed side by side instead of remembered. The first one is live - generation 1 vs generation 2 - and shows the deployed champion confirming higher on richer data (holdout lift 1.72x to 1.94x, calibration error down 61%, all seven holdout quarters beating chance) while the retrained challenger was correctly refused for failing to beat the frozen incumbent. The delta is stated honestly as directional: the confidence intervals overlap.
- A permanent generation archive now lives in lyra-evals/generations/: a narrative GENERATION-LOG (what changed, the biggest observed effect, watch-outs, grade movement - the retro that powers future tuning decisions) plus per-generation snapshots of the eval reports, since the working cache is disposable. Generations 1 and 2 are logged retroactively, including the gen-2 tier-story flip flagged as an open stability question, never a finding.
- Boards can no longer ship with empty chart panels: a pre-render gate (lyra-evals/boards/prerender-board.mjs) executes each board's own chart code and bakes the resulting SVGs into the HTML, failing hard on any empty or NaN chart - graphs are now visible even where JavaScript never runs. The whole procedure is codified as /model-generation-eval, and the retrain CLI gained the --estimator/--out flags the generation-3 logistic-vs-trees bake-off needs.
v0.111.02026-08-01
The estimator seam is real: a nonlinear challenger family joins the lifecycle
- The model lifecycle's long-promised "swap the estimator, keep everything else" seam now actually exists: training, walk-forward evaluation, floor gates, frozen artifacts, drift fixtures and serving all take an estimator choice. The first nonlinear family is boosted depth-2 trees (pure stdlib, deterministic, no new dependencies) - depth chosen deliberately, because depth-1 stumps are mathematically unable to represent interactions, and pairwise interactions (fundamentals with liquidity, dilution with momentum) are exactly what the winner hypothesis needs a nonlinear model FOR. Pinned by a test where the tree model cracks an interaction target that provably defeats the logistic.
- Every honesty property carries over: byte-deterministic training, per-name explanations (each tree is a two-level if/else; per-domain contributions reconcile exactly with the served probability, pinned to 1e-9), rare-positive guards (Newton steps with L2, capped leaf sizes, minimum samples per leaf), and drift fixtures that pin the frozen model to the serving path. Existing logistic artifacts load unchanged.
- Nothing is promoted by this release - deliberately. The nonlinear challenger earns a seat only through the standing loop on the generation-3 corpus (insider-flow fill in progress): dev walk-forward, a fresh one-shot holdout, absolute floors, and confidence-interval separation against the deployed real-v1 champion. The seam ships first so the bake-off is a data decision, not a code fork.
v0.110.02026-08-01
Evidence in the product, three dark domains lit, and the live loop finally closes
- The Models page now carries an "Evidence behind these numbers" section - the full backtest verdict rendered from a generated evidence pack (regenerated after every eval cycle, hash-bound to its corpus): per-model lift with confidence intervals against the chance line, what the model learned vs the hand-designed hypothesis, how the headline number was earned leak by leak, letter grades per dimension, and every caveat. Anyone reading a projection can now see exactly what stands behind it - and what does not.
- Three previously-dark data domains are built and flowing. Theme: each issuer's SEC SIC industry code maps deterministically into the hot-theme vocabulary (outcome-independent, so it is honest for history too - the curated map stays banned from training). Narrative: a real market regime (benchmark trend + drawdown, causal maths) reaches every scan and every corpus row. Sponsorship: real Form 4 insider net-buying, CIK-safe, live tonight (LUNR read -$160M of net insider selling on first scan) with the historical fill running.
- Generation-2 backtest on the richer corpus: the deployed champion improved to holdout lift 1.94x CI90[1.55, 2.29] with the worst quarterly cohort at 0.20 (no more zero-hit regimes) and ECE 0.017 - and the gates correctly REFUSED a freshly retrained challenger that failed its floors and did not beat the incumbent on the one-shot holdout. Fundamentals upgraded to quarterly EDGAR revenue growth (matching live semantics).
- The live learning loop closes: a nightly outcome-maturation job (migration 057) walks the predictions ledger and writes matured 12-month first-touch outcomes with the survival + liquidity conjuncts, sharing the exact label maths the backtest corpus uses - so the 20-pair live-calibration gate and the 200-pair live-training gate are finally reachable. A monthly scheduled re-eval workflow keeps the whole grading loop honest without anyone remembering to run it. Report card regraded on gen-2 evidence: accuracy B-, calibration A-, process A, data C-.
v0.109.02026-08-01
The models face real history - and the one trained on real outcomes takes the champion seat
- First genuine backtest: every scoring model was tested against 27,420 point-in-time rows across 991 US symbols (2016-2025) with matured 12-month outcomes, built from free sources with strict as-of discipline (EDGAR facts only count once FILED, prices split-reconstructed, no look-ahead by construction). The hand-designed scorecard and the synthetic-trained champion were REFUTED - their top picks contained fewer real winners than random selection. A classifier retrained on real 2016-2023 outcomes showed genuine skill and confirmed it on untouched 2024-2025 data: 23% of its top picks doubled within 12 months vs a 13% base rate (lift 1.72x, 90% CI 1.38-2.05, well calibrated). It is now the deployed champion, emerging-winner-classifier-real-v1, with the full promotion justification recorded inside the artifact. Still Beta: the corpus is survivor-biased, and surfacing stays gated on live calibration.
- The number was earned the hard way: the first run printed lift 2.77x and an adversarial review dismantled it before it was reported - a theme-label leak, hindsight-curated names, and a purge unit bug each gave back their share. A standing rule now triggers a mandatory leakage decomposition on any suspiciously high result.
- Feeding-the-right-data fixes across the live path, each with a regression pin: the volume-state vocabulary mismatch that silently killed a sub-signal on every real scan, word-level theme matching (the top-weighted domain scored a false 0 on real names), the curated-theme clobber, EDGAR concept discipline (no more cross-concept pseudo-YoY that sign-flipped dilution for ~1 in 5 companies; 52/53-week fiscal calendars handled), price-normalised MACD scoring for micro-caps, honest ADV over full windows, the ranker no longer fabricates neutral inputs for 25% of its priority weight, Stooq bot-wall detection, and pence never read as pounds.
- A standing testing + improvement suite ships with it: npm run worker:emerging-winner-backtest (build / retrain / compare / eval / one-shot holdout / promote / record), a metrics-over-time ledger in lyra-evals, a graded MODEL-REPORT-CARD, and a NORTH-STAR doc defining the most sophisticated stack this app can honestly carry - with earn-gates for every upgrade. 510 Python tests and 1,177 web tests green.
v0.108.02026-08-01
Plain English: the "Shadow-live" badge is now "Beta"
- The model-status badge that read "Shadow-live" now reads "Beta" - the same honest meaning, in a word everyone already understands. A model in Beta runs for real and logs every result to an immutable ledger, but is not trusted to decide yet; it is promoted to Live only once its track record earns it.
- Tapping "About this model" now spells that out in one plain line, so the badge is obvious at a glance and precise on a tap. The change is label-only - no model changed stage, and the honest four-state ladder (Live, Beta, Reference, Planned) is unchanged underneath.
v0.107.02026-08-01
Global ingestion - the dynamic pool goes multi-market, small caps to mega caps, still $0/mo
- The Emerging Winner universe is now multi-market. Alongside the SEC listing (~10k US names), the engine ingests the full ASX listing (~1,700 names, small-first) from the free FinanceDatabase reference data - Yahoo-suffixed symbols, delisted names excluded - with the LSE one flag away (EW_MARKETS). Every source is free and keyless, so the DATA-ECONOMICS cash line stays $0/mo.
- A rotating scan window replaces the fixed front-of-list slice. Each nightly run scans the curated emergence names first, then a deterministic 300-name window that advances daily through every enabled market's FULL pool - so small caps through mega caps ALL get scanned over a stated cycle (~6 weeks at current settings) instead of the back of the listing being unreachable forever. The worker logs "pool N (us=..., au=...), full-coverage cycle ~Nd" every run: coverage stated, never implied.
- Cross-market numbers made comparable. A new FX step (Frankfurter/ECB reference rates - free, keyless, cached daily) converts non-USD market caps and dollar volumes to USD before the USD-thresholded liquidity gates read them, with an honest degradation ladder: live rate, then cached, then stale, then a logged approximate pin - and when no rate exists at all the fields are dropped, never mislabelled.
- A second free price source. A Stooq daily-OHLCV provider implements the existing market-data protocol and chains as "yfinance+stooq", so a Yahoo throttle degrades to a fallback fetch instead of a blind scan. Honestly limited: daily bars only, covered markets only - an unmapped market returns an empty miss, never a guess.
- Coverage honesty held everywhere: EDGAR stays US-only by nature (suffixed names simply have no CIK), a dark market is logged and skipped rather than failing the run, offline still falls back to the curated real names, and the whole path ships with 29 new no-network worker tests (74 total in the touched suites, all green, TZ-safe).
v0.106.02026-08-01
Coverage-honesty fixes from an adversarial audit - a data gap never reads as a low value
- An adversarial audit of the new visualisations (each dimension a skeptic reading the code, then verifying its own findings) came back clean on the things that matter most - no fabricated values, no mis-attributed data, no over-claimed feature - and caught two places where a data GAP could visually read as a low VALUE. Both are now fixed.
- The 10-domain radar no longer folds unavailable domains into the filled shape. Previously an unmeasured domain was plotted at the centre (radius 0), so a name with, say, 7 of 10 domains not-yet-sourced collapsed to a small wedge that read as broadly-weak. Now only covered domains form the shape; a gap is drawn as a dashed spoke with a dimmed label - explicitly "not measured", never a zero.
- The opportunity map no longer draws a name whose market cap is not sourced at the smallest-bubble size (which read as "smallest company" against a legend that says bubble = market cap). Unsourced-cap names are now drawn hollow at a neutral size, with a "hollow = cap not sourced" note in the legend.
- Regression tests pin both: the radar plots no value vertex for an unavailable domain, and a null-cap bubble renders hollow. The honesty rule the whole app runs on - an unavailable value is shown as an explicit gap, never a low number - now holds across every chart.
v0.105.02026-08-01
Real SEC EDGAR fundamentals - the first deep-data domain, built without faking it
- The first "coming soon" deep-data domain is now real, not illustrative. On a live run the Emerging Winner engine pulls real SEC EDGAR company facts (data.sec.gov, free, no key) and derives the two trend fields a single market-data snapshot cannot honestly give: real share-count dilution (year-over-year change in shares outstanding) and gross-margin trend. These light up the capital and business-quality domains with real filings.
- Why this one first, and why it is safe: filings are attached by the SEC's own authoritative ticker-to-CIK map (already in the listing the engine scans), so there is zero fuzzy name matching and no risk of pinning one company's filings to another. Dilution also happens to be the single signal in the whole model with grade-A, internationally-replicated asset-pricing evidence, so making it real matters most.
- Coverage-honest by construction: a field is emitted only when EDGAR actually has two or more comparable annual (10-K) points for it. Quarterly noise is ignored, and a missing concept stays unavailable rather than being defaulted - the derivation is a pure, fully unit-tested function separate from the network fetch.
- The remaining deep domains (insider Form 4 / 13F flow, government contracts, and the delisted-inclusive point-in-time history) are still the honest data gate and read unavailable rather than a guessed value. They are the next real builds, sequenced by identity reliability, not faked.
v0.104.02026-08-01
Model Lab depth - more outcomes, inspectable step logs, a fuller board, and the small-cap universe made real
- Three new outcomes for the Emerging Winner model: Double (2x) within 12 months, Lowest ruin risk, and Fastest to catalyst. The 12-month double is a new horizon threaded through the engine (a nearer horizon is always rarer than the 24-month double by construction, never a looser claim in less time); ruin and catalyst rank by fields the engine already computes. All reference-v1 illustrative, labelled as such.
- Every step is now inspectable. The six-model stack (and the recovery-score drivers) carry high-level logs you can open per step - what each model actually did with the real data, from average domain coverage to which names a risk gate blocked. They show both while the run animates and in the collapsed "How this run was computed" section, so the pipeline is legible without being noisy.
- A fuller, mobile-safe visualisation board. Alongside the conviction funnel, opportunity map and 10-domain heatmap, the board now shows the run's average domain profile (its fingerprint across the 10 domains, coverage-aware) and a risk-gate breakdown (how the whole batch cleared each gate, with insufficient-data drawn as its own segment). Every chart scrolls or scales on a phone; the page never scrolls sideways.
- The "Small + micro caps" universe is a real filter now, not a placeholder - it keeps names under $2B on the real market cap the engine carries (unknown-cap names are excluded rather than guessed).
- Honesty held throughout: unavailable domains still draw as explicit gaps, the new outcomes are flagged reference-v1, and the deep-data domains (SEC filings, insider flow, government contracts, delisted history) and non-US markets remain the honest data gate rather than being faked.
v0.103.02026-08-01
Model Lab gains its visual half - see the data go in, read the results come out
- Visualise every run. Results now open in a Board view with four honest visualisations built on the numbers each result already carries: a conviction funnel (universe to reviewed to risk-cleared to surfaced to strong, with the forward stages - watchlist, position, realised - drawn as explicitly open), an opportunity map (resemblance x risk headroom, bubble size = market cap, colour = risk verdict), a 10-domain heatmap across every surfaced name, and a per-company 10-domain radar in the finding drawer. A List/Board toggle keeps the ranked detail one tap away.
- Choose your market. A global-market selector lets you point the scan at a market - the US (SEC) universe runs live today; the rest (ASX, LSE, Europe, Tokyo, Korea, India) are selectable so the roadmap is visible, and a run against them returns an honest empty set with a note rather than a faked foreign scan.
- Choose your size and your domains. A market-cap band (micro / small / mid / large / mega, with real dollar ranges) filters on the real market cap now threaded through the engine, and focus-domain chips let you prioritise the fundamentals you care about so results re-rank to lead with strength in those domains.
- Curate and inspect. The ticker box is now a curated list - enter a comma-separated set to compare exactly the names you want side by side. The drawer surfaces the real fundamentals the engine inspected (market cap, revenue growth, debt, liquidity sub-signals) with a score for each, so every run is legible end to end.
- Honest by construction, and covered. Unavailable domains are drawn as explicit gaps, never coloured as a low score; active market/cap/focus scope and what each filter did are shown as notes on every result set. The change threads a real market_cap field from worker to UI and adds a filter + visualisation test suite (all green).
v0.102.02026-08-01
The Emerging Winner engine now scans the real SEC-listed universe with real fundamentals
- Real universe, dynamically. The Emerging Winner engine scans the real SEC-listed universe - every US company that files with the SEC (~10,400 tickers, small-caps included), fetched live so new listings are picked up automatically - using free public data (the SEC company listing + market data). This replaces the hardcoded illustrative 3-candidate set; the illustrative set remains only as an honest offline fallback.
- Real fundamentals light up the quality domains. Market cap, float, revenue growth and debt/equity from the market-data provider now feed the liquidity, business-quality and capital domains, so quality companies are rated correctly - a name with 85% revenue growth and near-zero debt scores high on those domains, while the trend/delta fields a single snapshot cannot honestly provide are left unavailable rather than guessed.
- Coverage-honest by construction. The engine populates the domains real data can support and marks the deep domains it cannot yet source (SEC filings, insider flow, government contracts, delisted history) as unavailable - so it ranks quality directionally on real data today without fabricating conviction it has not earned.
- Validated + guarded. The pump-blocking and quality-vs-junk separation hold on fully-populated data, and a new property/fuzz behaviour contract plus a real-universe scan eval bring the worker suite to 436 green tests. Enable a live run with EW_REAL_UNIVERSE=1; the Model Lab and README now carry an honest note explaining the scan and the remaining data gate.
v0.101.02026-08-01
Model Lab made minimal - clean selectors, a collapsed catalogue, and every vertical on
- The Model Lab configuration is now minimal by default: Model and Outcome are clean dropdown selectors above one big Run button, and the complexity (verticals, universe, optional ticker, plus the model detail and its data sources) tucks into collapsible Refine and About sections. Simplicity of a complex thing.
- Every vertical and archetype is selectable - nothing is greyed out, so all features are available. A vertical with no matches in the current universe simply shows a 0 rather than being hidden.
- Models & methods is now a collapsed, scannable accordion. Each model is a one-line row you tap to deep-dive its answer, provenance and surface, instead of a wall of expanded cards.
- Polish: the last card on the models page now has proper breathing room above the bottom nav, and the AU Macro tape honesty chip is compact ("Partial") - meaning some rows (AUD/USD, ASX 200) are live from the hourly snapshot while the cash rate, CPI and jobs rows stay seeded until their RBA/ABS feeds land.
- Owner and comp accounts can be granted indefinite hosted AI (via the AI_INCLUDED_EMAILS allowlist or the profiles.ai_included flag), so they never lapse to bring-your-own-key when the 14-day trial ends.
v0.100.02026-08-01
The Models page is now Model Lab - choose the question, watch it run, inspect why
- Model Lab replaces the static model catalogue with a real run experience. Pick a model and outcome, narrow by vertical/sector, universe and an optional ticker, then Run. Three tabs - Run, Previous runs, and Models & methods (where the technical catalogue now lives), so you are no longer asked to read a wall of architecture before you can do anything.
- Watch it work. Pressing Run reveals the real pipeline stage by stage with a live timer and real counts - the six Emerging Winner models (domain scorecard, classifier, historical analogue, archetype ranker, risk gates, timing) or the deterministic score drivers. It never fabricates a universe: counts are what the engine actually produced, and the run states plainly whether it is a live computation or a replay over an illustrative reference set.
- Inspect why each name surfaced. Results are a ranked list plus a finding drawer with the domain breakdown, drivers, modelled outlook, resemblances, risks and provenance. Honest by construction - a Live model returns real numbers, a Shadow-live model is loudly labelled illustrative, and a Planned model can never arm a run.
- Four unambiguous availability states everywhere - Live, Shadow-live, Reference, Planned - and your runs are saved on-device under Previous runs so you can reopen any configuration.
v0.99.02026-08-01
Run a model - pick an outcome, narrow the market, and rank your tracked universe
- The Models page now opens with a "Run a model" panel. You pick what you want to predict, optionally narrow by market segment and the tickers you care about, and hit Run - it ranks Lyra's tracked universe on the spot. No wall of static cards before you can do anything.
- Every outcome wears its true stage, so you always know how real the answer is. The oversold-recovery score is Live and returns real deterministic numbers with the full five-driver breakdown (RSI, MACD, price location, trend, volume). Emerging-winner resemblance is Shadow-live and ranks the illustrative reference queue, loudly labelled "not trained on real winners yet".
- "Segment of the market" adapts to what you are running: it filters by sector for the oversold-recovery radar, and by winner archetype for the Emerging Winner stack.
- It refuses to fabricate. Pick a model that is only built-on-synthetic-fixtures or designed-not-built, and Run is disabled with a plain explanation of why there is nothing honest to score yet - never an invented number.
v0.98.02026-07-31
Emerging Winners is now list-first, plain-English, and honest about what it is
- Every Emerging Winner is now a scannable row you tap to expand - no more one-dense-card-per-screen. Start simple (symbol, resemblance, risk, data completeness), then open it up section by section into drivers, the full 10-domain scorecard, the modelled outlook, resemblances and risks.
- The jargon is decoded. "P(2x·24m)" now reads "Doubles (2x) within 24 months"; "winner similarity" is a labelled 0-100 resemblance score; "(ref)" is explained as an illustrative reference archetype, not a real company. Every term has a tap-to-explain "?" with the exact plain-English definition one tap away.
- Provenance is loud, before the score. Each card says what it is at the very top - "Illustrative example" or "Shadow-live", and "not trained on real winners yet" - so you always know where the numbers came from before you read them.
- A new "What is this model trained on?" panel tells the truth plainly: today the engine scores against a reproducible synthetic reference set, not real historical companies; you can inspect the deterministic driver math yourself; and a real point-in-time dataset (with delisted names and SEC filings) is what would make it real. It cross-links to the model registry so Emerging Winners (the output) and Models (the explainer) are one clear home.
v0.97.02026-07-31
The signal detail view now has the chart in it - inspect a setup without leaving the drawer
- Tap into a setup and the chart is right there: the signal detail drawer now embeds the full setup chart (candles with Bollinger Bands, RSI and MACD - the same studies the full-setup view opens with), so you can inspect the price action that drives the read without navigating away.
- The quick actions (Full setup chart, Open ticker) now sit at the TOP of the drawer as well as beside the embedded chart at the bottom, so a strong setup opens straight into what you want to look at first.
v0.96.02026-07-31
AI-written answers are now labelled as AI-generated, everywhere the AI writes
- Every AI-written narration - the Daily Brief phrasing, the signal explainer, and the Ask Lyra chat - now carries an explicit "AI-generated" label, so it is always clear which words came from an AI model and which are the deterministic engine's own numbers. The engine still owns every number; the AI only phrases them.
- The Ask Lyra chat identifies itself as an AI copilot and marks its answers as AI-generated research, not financial advice.
- This makes the AI-transparency disclosure explicit for the EU AI Act Article 50 obligation that takes effect on 2 August 2026. The substance was already there - Lyra explains, it never advises or trades - this makes the labelling unmistakable.
v0.95.02026-07-31
The winner label learns from the evidence: durable-emergence definition, honest domain provenance
- The training label migrates to its quality-winner definition (Decision B option 4): a winner is now a name that not only doubled but also survived and grew its liquidity - not just any +100% first-touch spike. The published finance research is explicit that bare "biggest move" labels reward pump-and-dumps and lottery-like names that are subsequently priced DOWN (the MAX effect, Bali/Cakici/Whitelaw JFE 2011), so the model should learn durable emergence instead. Doing this now, before real labels exist, costs nothing; doing it later would mean a relabel and retrain.
- The change is an inert seam today and proven so: the reproducible bootstrap does not use this labeler, and live outcome rows do not yet carry the survival/liquidity fields, so the shipped weights, metrics and drift fixtures are byte-identical (ROC-AUC 0.828 unchanged, drift guard still exact to 1e-8). The label tightens automatically the moment the maturation job writes those fields.
- The domain weights now carry honest evidence provenance: capital/dilution is flagged as the one weight backed by a robust, internationally-replicated anomaly (and best used as a risk gate), theme is labelled as a deliberate bet on differentiation rather than dressed as established fact, and technical is flagged as a timing signal rather than an archetype trait. Bets read as bets. Full reasoning in lyra-modelling/MODEL-SELECTION-AND-OSS-STACK.md.
v0.94.02026-07-31
The Emerging Winner model gets honest: leak-proof validation, per-cohort scoring, a floor gate, and a truthful headline
- The training validation is now leak-proof: a purged and embargoed walk-forward means a name's 12-month outcome window can never bleed across the train/test boundary and flatter the score - the canonical financial-ML fix (Lopez de Prado, AFML Ch. 7). On the reproducible bootstrap this correctly changes nothing (its rows have no timeline, so there is nothing to purge); on real point-in-time ledger data it will.
- It now reports the numbers that actually decide whether to trust a pick: average precision (PR-AUC) as the primary metric instead of a flattering ROC-AUC, precision among the top picks measured per quarter with the worst quarter surfaced (not a pooled average that hides a bad regime), and an adaptive equal-mass calibration error that does not understate error at a rare base rate.
- A bad retrain can no longer ship silently: a pre-publish floor gate refuses to overwrite the deployed champion unless the new model clears a floor and does not regress against the current one - a deliberate override stays possible, but never accidental.
- The drift guard is hardened with engineered boundary fixtures (all-missing, all-floor, all-ceiling, coverage-transition corners) on top of the random ones, so the frozen model and the served model are proven identical (to 1e-8) at the edges where a future tree-based model would be most likely to diverge.
- The headline is honest: the bootstrap result is labelled a machinery proof - it draws its labels from a logistic and recovers them with a logistic - and explicitly not evidence about real winners. The model stays shadow-live until real matured outcomes and live calibration earn surfacing (founder-gated). Full research + runbook in lyra-modelling/TRAINING-PIPELINE.md and MODEL-BUILD-TRAIN-HOST.md.
v0.93.02026-07-31
The Emerging Winner model earns its way: a full training + deployment + monitoring lifecycle
- The Emerging Winner classifier is now a real model lifecycle, not a static heuristic: a training-ready dataset, a trainer that learns and backtests out-of-sample, a frozen deployed model, a nightly monitor, and inference that serves it - all shadow-live, all research-not-advice, no number invented.
- The dataset is honest by design: the immutable shadow-live ledger IS the point-in-time feature store - each prediction records the exact domain state before its outcome exists - and a first-touch +100%/12-month labeler turns matured price paths into winner labels. Until real outcomes mature it trains on a reproducible reference dataset that encodes the winner hypothesis, and it upgrades itself to real ledger rows automatically.
- The trained model learns and generalises: walk-forward backtesting (out-of-sample) reports the metrics that matter for a rare winner - precision among the top picks, lift over the base rate, and calibration - not a single vanity number. The current reference training run surfaces winners at nearly 5x the base rate out-of-sample.
- It cannot silently drift: the frozen model ships drift fixtures the deployed inference must reproduce exactly (proven to 1e-8), and a nightly monitor reports the live model health and keeps every prediction behind the shadow gate until calibration and lift honestly earn surfacing (founder-gated).
- Built to swap: the estimator is a transparent, dependency-free logistic today; the deck's CatBoost/LightGBM ordinal classifier is a drop-in that keeps the exact dataset, export, deploy, monitor and inference contract. Full runbook in lyra-modelling/TRAINING-PIPELINE.md; the loop is documented in LOOPS.md (loop 13).
v0.92.02026-07-31
The modelling stack steps into the light: intro scene, landing section, README gallery
- The activation primer before onboarding grew a sixth scene, "Models that earn their way": the six-model pipeline animates in, a real candidate scorecard fills its domain bars, the risk gates pass one name and block a pump, and the shadow-live promise is stated plainly - all using the engine's own demo numbers, nothing invented.
- The landing page now shows the modelling stack: six model tiles in the light brand surface, the honest shadow-live framing, and a straight path into the in-app /models catalogue - the landing never promises more than the app states.
- The README gained section 6, The Modelling Stack: the full six-model deck, the five designed event-model families, and both end-to-end architecture posters, with the same research-not-advice framing as everywhere else.
- Under the hood: the primer scene data is now test-pinned (contiguous steps, agreeing totals, the models scene cannot silently fall out) and the landing section render is pinned to all six models and the /models route.
- The copilot's knowledge layer learned the modelling stack (the new README section is in its grounded corpus, with a labelled eval case to match) - and this surfaced a real ranking bug, now fixed: the hybrid retriever rounded scores before sorting, so near-ties fell to an alphabetical tiebreak that could demote the genuinely best doc.
v0.91.02026-07-30
A Models page: every model in Lyra, with its honest status, in one place
- A new Models surface (Learn & set up drawer) cataloguing the whole modelling stack: the always-on deterministic backbone, the six-model Emerging Winner Engine, and the five designed event-model families - each card stating what the model answers, how far it has actually shipped (Live / Shadow-live / Built / Designed), and exactly where its numbers come from.
- Honesty is the design: the stage chip and the provenance line render together on every card, so a reference heuristic can never pass itself off as a trained model, and models with no surface yet say "no surface yet" rather than pretending. Tests pin the registry - complete fields, resolvable links, and zero advice language.
- The Emerging Winner Engine roadmap (phases 0-6) is shown plainly, including the gate: until the point-in-time winner dataset exists, the learned models stay reference v1.
v0.90.02026-07-29
The Emerging Winner Engine goes shadow-live: a research queue for small caps that resemble past winners
- A new Emerging Winners research surface: small caps scored end to end by a six-model pipeline - a 10-domain scorecard, a winner classifier, historical winner/failure analogues, an archetype classifier, a learning-to-rank queue, and a five-gate risk stack - then ranked for research. Research only: it shows a resemblance score and what is missing, never a buy call and never a price target.
- Shadow-live and honest by design: every prediction is logged to a new immutable, append-only ledger (it can never be quietly rewritten), and the surface says plainly that the engine is reference-v1 - not yet trained on a real point-in-time winner dataset - so nothing is presented as truth before it is earned.
- The risk gates do real work: a speculative pump with a tiny float, heavy dilution and thin liquidity is caught and excluded from the queue, with a modelled downside shown honestly rather than smoothed away. A domain with no data is marked "not yet assessed", never counted as a weak trait.
- The sixth model, Timing & Network Intelligence, runs as a strict shadow challenger: it annotates each finding with a timing read (dormant, accumulating, confirming, or crowded) and a network read (insider buying, institutional flows, supply-chain centrality, government links) but by design contributes nothing to the ranking - and when attention runs ahead of evidence, it says plainly that the crowd likely arrived first.
- Under the hood: a new Python worker scores the universe nightly, a new Supabase schema (migration 056) stores the runs, predictions and outcomes, and 41 new tests pin the classifier, analogues, risk gates, timing challenger and the full pipeline.
v0.89.02026-07-28
Audit remediation wave 7: the last three verticals cleared - save safety, gate self-checks, and a fully accessible landing
- The onboarding "Finish" step is now proven to never fake success: the exact rule that decides a save really landed (a 401 or server error must keep your entries and let you retry, never show "You're all set" on a dropped book) is pinned by tests, alongside the flow-navigation logic.
- The database schema-drift check now catches a column whose live TYPE has diverged from the migration (on top of the missing-column and NOT-NULL checks), and its own new detection logic is now self-tested - conservatively, so it never false-alarms on a custom type.
- The landing page fine print now clears accessibility contrast everywhere (a few sibling captions were missed last pass), and the stack section is now covered by a render test that proves the account-only tools are correctly hidden in the no-account Solo build.
- Under the hood: the shared quality-gate logic gained tests for its version, migration, and schema parsers, so a gate can never silently rot into always-passing.
v0.88.02026-07-28
Audit remediation wave 6: the onboarding flow logic is pinned, and the quality gates now guard themselves
- The onboarding navigation and completeness logic - which beats you see, the never-traded skip, the 0-to-100% progress math, and how your alert choices map to a mode - is now covered by tests, so a regression that dropped a step or swallowed your preferences would be caught before it shipped.
- The quality gates that keep the app honest now have their own tests: they prove the version guard catches an unversioned or backwards release, and the migration guard catches a duplicate version or a table redefined with clashing columns - so a gate can never quietly rot into always-passing.
- The schema-drift check got two new eyes: it now catches a column the migrations require to be filled but the live database left optional (the exact bug that silently broke an hourly job), and it now guards user-owned tables whose owner column is not literally named user_id.
- Post-deploy smoke checks now also run when a change touches only the workers, content, database setup or notification contracts - shippable areas that previously deployed with no live verification.
v0.87.02026-07-28
Audit remediation wave 5: the radar is honest about its timeframe, and the numbers behind it are finally pinned
- The Signal Radar now says plainly that its scores are computed on daily bars - so if you get an intraday alert and open the radar to a slightly different number, you know why, instead of seeing two figures that seem to disagree.
- The math that produces every number on the shipped scanner (RSI, moving averages, distance-from-low) is now covered by tests that pin it to its definitions, so a silent bug in the display path would turn the board red instead of shipping wrong figures.
- The paper-trading benchmark chart no longer implies a head-to-head return: your live session line and the 30-day market lines share a shape, not a calendar, and the caption now says so.
- The full paper-trade path - propose, approve, fill - is now driven end to end by a test through the real deterministic engine, and the Explain, Approve, Submit and tour controls are all a comfortable 44px.
v0.86.02026-07-28
Audit remediation wave 4: your data fence is now provably closed, and the AI can't dress a score up as a return
- The privacy fence that keeps your portfolio, watchlist and paper trades visible only to you is now proven by an automated test on every build: it seeds two users and confirms one can never read the other's rows, so the leak class we fixed before can never quietly come back.
- The AI copilot's number guard got sharper: a made-up figure like "up 82%" is no longer waved through just because 82 happens to appear elsewhere as a score - a percentage or multiple now has to be genuinely in the evidence, closing a subtle way an invented number could slip past.
- The iOS app's offline screen now has a Retry button, so a brief drop-out recovers with one tap instead of a force-quit - and the app's shell config is now guarded by a test so it can't silently ship pointed at the wrong place.
- The landing page fine print now meets accessibility contrast, its footer links are a full tap target, and the chat composer, send button and quick add-holding inputs are all a comfortable 44px.
v0.85.02026-07-28
Bigger tap targets on mobile + a hardened, tested nav bar
- The Live Wire and What's New buttons in the top bar are now a full-size 44px tap target on phones (they were a cramped 36px), so they are easier to hit without a mis-tap - unchanged on desktop.
- Your customised bottom nav bar is now hardened and tested: a corrupted or over-long saved bar can never render an unknown link, repeat a shortcut, or overflow the rail. Under-the-hood robustness, no change to your setup.
v0.84.02026-07-28
Second remediation wave: more truthful defaults, hardened layout, deeper test coverage
- A watch rule you add with just a ticker is now proven at the engine level to wait for a real strong setup, not fire on every scan - the safeguard is pinned by tests so it cannot silently regress.
- Your saved command-centre layout is now hardened: a corrupted or duplicated saved order can never render the same card twice or lose a newly-added one.
- A notification-relevance setting now falls back to the correct default (40) instead of a stray 75 when cleared, so what you set is what you get.
- Added another batch of behavioural tests covering the live news mapping, the layout engine, the watch-rule floor, and the AI "add your key / allowance used up" messages, and corrected a stale scanner-schedule comment. Under-the-hood quality, no change to how the app looks.
v0.83.02026-07-28
Honesty + polish pass: real search, truthful data labels, and controls that actually work
- The header search is now a real ticker search - type a name and jump straight to it. A ticker Lyra has not scanned lands on an honest "not in the current scan" page with the names it does cover, instead of a dead end.
- Market data is now clearly labelled live vs sample everywhere. The news feed, hype meter, fundamentals and government-awards pages tell you when you are looking at illustrative samples versus a real feed, and the awards page now surfaces live federal-contract data when available.
- Watchlist rules no longer show a false "triggered": a rule you add with just a ticker now waits for a genuine strong setup (score 60+) instead of firing on every scan.
- Portfolio: you can now remove a holding straight from the portfolio page, Solo profit/loss includes your brokerage fee to match the real cost basis, and Solo positions now surface the same protect-capital exit prompts the account-backed view does.
- Notifications: the Custom quiet-hours you set now actually apply to delivery (they used to save only on your device), and dead frequency/scope dropdowns that did nothing were removed.
- New public AI transparency page (the System Card) - a plain readout of what Lyra's AI may and may never do, its guardrails, and live evaluation results.
- Dozens of smaller honesty fixes: the momentum lead-in chart is now labelled as an illustrative reconstruction, the landing page states plainly that Lyra finds beaten-down names turning up (not breakouts), and the paper-bot tour uses a realistic $5k balance instead of a $100k fantasy.
v0.82.02026-07-27
A clear heads-up when you land: your first 2 weeks of AI are on us
- New accounts now get a one-time welcome in the command centre that spells out the deal up front: Lyra's AI is free for your first 2 weeks, then it switches to your own key (bring-your-own-key). It shows exactly how many days are left, so there are no surprises.
- When the trial ends, a one-time nudge points you to add your key - and reassures you that the scanner, portfolio, watchlist and notifications keep working regardless. Only the AI chat needs a key.
- Shown once each and never nags. Accounts granted hosted AI, and the Solo build, never see it.
v0.81.12026-07-26
An always-there way back: keep your demo setup with a free account
- While you explore the demo, the command centre now carries a persistent "keep what you build" prompt - so if you wander deep into the console you always have the one-tap path to create a free account in front of you, instead of having to find your way back to sign-up.
- It shows only during the accountless demo and disappears the moment you have an account, and because your whole setup carries over on sign-up, keeping it costs you nothing.
v0.81.02026-07-26
Explore the demo, then keep it - your whole setup now follows you into an account
- If you try Lyra from the read-only demo and then create an account, the ENTIRE setup you built - strategy, watchlist, holdings, capital and alert preferences - now comes with you. You land on a one-tap "Welcome back, save your setup" screen instead of replaying the whole questionnaire. Previously only holdings and the watchlist carried across; everything else had to be re-entered.
- Fixed a trap in that handoff: the demo-tour cookie is set for a week and used to linger after sign-up, which could make a brand-new account look like a demo session - skipping every cloud save and looping you back into onboarding. Signing in now clears it immediately, so your first save always lands.
- You can still change anything before saving - "Review & edit" drops you into the normal setup steps, fully pre-filled.
v0.80.12026-07-26
A one-image "How Lyra Works" explainer, for sharing at a glance
- Added a single-image explainer (assets/how-lyra-works.png) that puts Solo and Full account side by side - what each one is, how each one gets its data, and what they share - so you can send one picture instead of a paragraph.
- Linked from SHARE.md and the top of the README so the graphic travels with the two-link share kit.
v0.80.02026-07-26
Two ways to try Lyra, made official - Solo now points you to a Full account when you need one
- Solo (the no-account build) now offers a one-tap path to create a Full account at the exact moments it has to say "not here" - background notifications and hosted AI. It only ever shows on the accountless build; the full app, which already has accounts, never sees it.
- New share kit. SHARE.md carries the ready-to-send two-link blurb (Solo vs Full account), and DATA-FLOW.md explains, with a file-and-line citation behind every step, exactly where each side gets its numbers: Solo recomputes signals live from Yahoo on the spot for a curated list, while the Full account reads an hourly-scanned, stored universe with a live overlay and your own portfolio and watchlist layered on top.
- The README now leads with the two live links and what each one is for, so sharing Lyra is a copy-paste, not an explanation.
v0.79.02026-07-26
AI is now free for your first two weeks, then it is your own key - and the whole app works either way
- New accounts get Lyra's hosted AI included free for 14 days. After the trial, AI switches to bring-your-own-key - you add a provider key in AI Settings and nothing else changes. The countdown shows in AI Settings so it is never a surprise.
- This is now a per-user decision, not a whole-deployment one: the hosted key is handed only to users inside their trial (or a standing grant), so we never pay for AI for someone who is past their trial. The scanner, portfolio and notifications never use AI, so a lapsed trial costs you nothing but the chat.
- Under the hood it is enforced at the one credential chokepoint every AI route already passes through, pinned by tests: an anonymous caller, and now a signed-in-but-lapsed caller, can never reach the house key.
v0.78.02026-07-26
A "How Lyra Works" page in Settings - see the decision process for yourself
- New Settings tab, How it works: a plain-English walk through exactly how Lyra decides - how a stock is scored 0-100 from five indicator blocks, how alerts are ranked by relevance (with your own holdings weighted highest), why the ranking is auditable (every number is measured against its real forward outcome), and precisely where AI is allowed (explaining) and forbidden (scoring, ranking, orders, notifications).
- It is grounded in the code, not a pitch: a companion root document HOW-LYRA-WORKS.md carries the same explanation with a file-and-line citation behind every claim, plus Mermaid diagrams of all nine subsystems, so anything stated can be traced to source.
- Also sketches the roadmap: telling Lyra your goal in plain words to reshape what it surfaces - the AI authoring a ranking policy the deterministic engine then runs for free on every brief.
v0.77.02026-07-26
The Ideas board now records where each idea came from - Solo or Community
- Every new idea is tagged with the deployment it was posted from - Solo (the accountless build), Community (production), or other (a self-host) - so we can see how much of the board is driven by free Solo users versus signed-in ones.
- It reads the request origin server-side, which cleanly tells Solo (cross-origin) from Community (same-origin); it is provenance for us, never shown on the public board and never tied to a person.
- Safe either way: the tag writes best-effort, so an idea still posts fine whether or not the new column has been applied yet. Existing ideas stay honestly unlabelled rather than back-guessed.
v0.76.02026-07-26
AI Settings tell the truth about hosted vs your-own-key on every deployment
- The AI copy now keys off whether a hosted key actually exists on this deployment - not off whether you have an account. So a build with full accounts, cloud sync and notifications but no hosted AI key correctly says "add your own key to switch AI on" instead of promising a hosted model that is not there.
- This makes a clean third shape first-class: the whole product (accounts, database, notifications) with AI as bring-your-own-key only - run your own Lyra without anyone footing your AI bill.
- The setting page, the model picker labels and the "Turn on your AI copilot" card all read from the same honest signal the chat already uses (GET /api/ai/status). BYOK keys stay in your browser, never server-side.
v0.75.02026-07-26
A Solo-to-account upgrade path, built behind a control and held dark
- Groundwork for the Solo upgrade path: at the moment a Solo user goes looking for notifications - which Solo cannot deliver on its own - a one-tap prompt can offer a free Community account (push, Telegram, WhatsApp, scheduled digests, plus cloud sync across devices), deep-linking to signup on the accounted deployment.
- It ships behind a control (NEXT_PUBLIC_SOLO_UPGRADE_CTA) that is OFF by default, so nothing is visible yet - the prompt is built and tested, ready to switch on per-deployment when we choose to.
- Honest by construction: the prompt only ever appears on Solo, only for the capabilities that genuinely need an account (never for AI, which Solo already runs on your own key), and the accounted build never shows it.
v0.74.12026-07-26
A features-per-build table in the README, generated so it can never drift
- The README now carries a "features per build" table - every shipped build and its headline theme, newest first - generated straight from this version log on every build, so it can never fall out of step with what actually shipped. The full per-build highlights still live in CHANGELOG.md and in-app at /whats-new.
v0.74.02026-07-26
One codebase again - the Ideas board reaches Solo, and Solo's device-local polish reaches everyone
- The Ideas tab is now purely community ideas: what you want built inside Lyra. The AI scout's external signals (news themes, funding drumbeats) moved to the Scout tab as "Scout proposals" - the two questions never mix again.
- Post and vote without an account: ideas and votes work signed-out and in Lyra Solo, keyed to your device. One shared board for everyone - a Solo user sees and votes on the same list as a signed-in one.
- Two standing example ideas seed the board - deliberately things we may never build - so you can see what an idea looks like before adding your own.
- Scout proposals keep everything they had: evidence links, AI reads, confidence, votes, and the maintainer promotion flow - just on the tab where perception belongs.
- Solo and the accounted app are now one branch and one codebase again, switched only by deployment env - so every fix ships to both.
v0.73.22026-07-24
Solo now behaves like one truthful device-local product from first run onward
- A completed Solo setup is now a one-time journey: returning users enter their console directly, and even a stray onboarding URL redirects home unless an explicit replay was requested.
- Every personal board now uses only this browser’s saved watchlist, holdings and cash. Seeded demo portfolios, alerts and overlay counts can no longer impersonate the user on charts, radar, simulation or planning surfaces.
- Solo trade logging is now one atomic local transaction across the trade log, holdings and saved cash balance. A failed write rolls the whole action back, and Undo restores all three.
- The Solo/Community boundary is explicit throughout setup and settings: no sign-in, hosted AI or background-delivery claims in Solo; BYOK remains optional and device-held.
- AI provider failures now produce actionable user messages plus bounded, secret-free operations codes. Successful and failed runs emit hash-only structured telemetry with provider, model, latency, usage and cost.
- Alert worker deduplication no longer stores skipped attempts as sent alerts, preventing false cooldowns and unbounded alert-table growth.
v0.73.12026-07-24
Solo BYOK credentials can be removed without wiping the console
- AI Settings now has a dedicated Remove key action whenever a browser-held provider key exists, so a Solo user can revoke that credential without deleting their watchlist, portfolio, trade log or other device settings.
- Returning Solo users who revisit the welcome page now see Open my console and go straight to their existing console instead of accidentally restarting the first-run setup.
v0.73.02026-07-24
Solo first-run, install and BYOK grounding now tell one consistent truth
- Solo now has one clear front door: Enter my console, no sign-in action, an explicit SOLO status in the app, and account-free Home Screen instructions.
- Installability is fixed for first-time visitors: the web manifest and service worker bypass the onboarding gate and return as real PWA assets instead of redirecting to the welcome page.
- Bring-your-own-key chat now receives a validated, transient snapshot of the holdings, watchlist and operating context stored on this device, so sample portfolio data can no longer impersonate the Solo user. Anonymous questions are excluded from raw question-signal capture; AI audit metadata remains hash-only.
- Solo portfolio and trade-log behavior is truthful at the edges: an empty local book stays empty instead of restoring sample holdings, and fractional shares are displayed instead of rounding a real position down to zero.
v0.72.02026-07-20
Lyra Solo - the no-account, bring-your-own-key mode is now first-class
- Solo deployments (no Supabase configured) no longer lose your work: the add-watch-rule form and quick actions save to a browser-local watchlist, and a new "Your watch rules - on this device" panel on the Watchlist page shows them back to you.
- Trades you log in chat now persist on this device in Solo mode, with real fill prices from the live quote lookup, holdings that actually move, and undo that unwinds in reverse order per symbol - exactly the server contract, browser-local. The Trade Log page reads and undoes the same store.
- Refusals are honest: a trade with no live quote or no amount is refused rather than logged with a made-up price.
- Copy now tells the truth about where you are: Solo mode says "no accounts here, your data stays in this browser" instead of asking you to sign in to accounts that do not exist, and the AI settings say plainly that Solo has no hosted key - bring your own to turn AI on.
- The welcome page states the Solo promise up front: no account, no cloud, AI on your own key.
v0.71.02026-07-20
Support and Terms pages, reachable without signing in
- Added a Support page with contact details, how to report a problem, common questions, and how to get your data deleted.
- Added a Terms of Service page stating plainly that Lyra is research software, not financial advice, and is not connected to any brokerage.
- Fixed the real defect behind both: /support and /terms were not in the middleware public list, so every visit was redirected to /welcome. A legal page behind a sign-in is the same as no legal page, and App Store Connect requires a working support URL.
v0.70.22026-07-18
Notch fix, without double-padding the ears
- The welcome screen no longer pads the landscape notch ears twice - the page owns the top and bottom insets, the document body owns the left and right ones.
v0.70.12026-07-18
Welcome screen clears the notch
- The signed-out welcome screen now respects the iPhone safe areas - the Lyra header no longer collides with the status bar clock inside the iOS app (and landscape ears are padded too).
v0.70.02026-07-18
First-class inside the iOS app
- The site now knows when it is running inside the Lyra iOS app (one shell-detection module, invisible to browsers) and adapts: external links open in Safari instead of trapping you in the app, and the onboarding Home-Screen step becomes a simple confirmation.
- Edge-to-edge safe areas: headers, drawers, sheets, the tour card, and the launchers all clear the iPhone notch and home indicator - in the app, the installed web app, and Safari landscape.
- New Share button on ticker pages and the Track Record page - opens the system share sheet where the browser supports it, with a copy-link fallback.
- Phase 2 native push (APNs) is designed and documented in docs/product/native-app.md - web push cannot reach the app shell, so alerts there stay on Telegram/Slack/WhatsApp until it ships.
v0.69.12026-07-18
Home-Screen walkthrough polish
- The Safari-menu screenshot in step 1 is now compact and centered instead of full-width, and the Lyra icon in the final payoff shot is dead-centered. Reviewed live on the iOS simulator.
v0.69.02026-07-18
Your phone stops buzzing: a real rate cap, and Quiet mode that means it
- Alerts are now capped at 6 per hour (adjustable, 0-60). Anything over the cap is held and delivered later as the window frees - late beats lost - so a fresh watchlist plus an hourly scan can never again fire one notification per minute. Approval requests, kill-switch notices and your scheduled digests are never rate-limited.
- Quiet mode is now enforced on the server, not just painted in the menu. Switching to Quiet really does mean only portfolio risk, strong setups and your digests get through - everything else stays silent. (It used to live only in your browser while the server kept sending everything.)
- The Add-to-Home-Screen step no longer skips silently when you are already running the installed app - it shows a short "already on your Home Screen" confirmation instead, so the journey never feels like it lost a step. Plus a heads-up that the installed app runs its own session: create your account first and everything carries over.
- Review tools: /onboarding?beat=homescreen deep-links straight to the Home-Screen step.
v0.68.12026-07-18
A replay switch for the onboarding journey
- Visit /api/demo?fresh=1 to replay the full onboarding journey from the very first beat - it clears the toured stamps and the resume checkpoint, so the reveal, primer, questionnaire and Home-Screen walkthrough all play again. For reviewing the flow, showing it off, or taking screenshots - repeatable forever.
v0.68.02026-07-18
Onboarding now teaches you to put Lyra on your Home Screen
- A new final beat in onboarding walks you through installing Lyra on your phone - on iPhone with a real four-step screenshot walkthrough (menu -> Share -> Add to Home Screen -> done, with the Lyra icon on your Home Screen as the payoff), on Android with the Chrome steps. This is functional, not cosmetic: on iPhone, the alerts you just configured can only reach your phone once Lyra is installed to the Home Screen.
- Smart about context: if you are already running Lyra from your Home Screen the step skips itself, and on a computer it points you to open Lyra on your phone. Skippable either way - it never blocks the console.
v0.67.12026-07-18
Demo journey unblocked for everyone who tried the demo before
- Anyone who tapped "Explore the demo first" before today carried a leftover cookie that made the app think they had already completed the new onboarding journey - so it skipped them straight to the console. The "already toured" check now keys on a marker that only finishing the journey can set, so earlier demo visitors (and your own phone) get the full experience on their next tap.
v0.67.02026-07-18
The demo now takes you through the full onboarding journey
- "Explore the demo first" no longer teleports you into a dense dashboard. A first-time visitor now gets the complete experience: the Lyra reveal, the feature primer, and the full setup questionnaire - strategy, watchlist, portfolio, capital and alert preferences - before landing in a command centre personalised by their answers. Everything persists locally in the read-only tour; nothing needs an account.
- Fixed alongside it: a demo visitor who reached onboarding could never actually FINISH it - every cloud save requires a sign-in, so the finish button surfaced a permanent retry error. The tour now skips cloud writes cleanly and completes.
- Returning demo visitors who already finished the tour skip straight to the console - tapping the demo button twice never repeats the questionnaire.
v0.66.02026-07-18
Paper Bot page rebuilt from panels - same surface, half the moving parts
- Under-the-hood: the Paper Bot page was one 970-line component; it is now a small orchestrator composing four focused panels (how-it-works, paper account, alerts feed, command line) with shared types in one place. Nothing changed visually or behaviourally - every class and interaction is byte-for-byte - but each panel can now be read, reviewed, and changed on its own.
v0.65.02026-07-18
The motion map - every loop, mapped and measured
- New LOOPS.md at the repo root: all 12 loops in the system mapped end to end with ASCII diagrams - the hourly scan, outcome learning, digests and reviews, notifications (both directions, including chat commands), the scout, macro and calendar, the horizon-2 workers, the AI copilot, the paper bot, data economics, releases, and the agent-learning ledgers. Each loop names its trigger, its ledger, who reads it back, what closes it, and the gate that keeps it honest. Every claim was adversarially verified against the code.
- DATA-ECONOMICS.md now carries audited retention benefit horizons: every reader of every growing table traced to its exact lookback window, then independently re-verified. Headlines: candles are needed for 380 days (the yearly review baseline - a naive 180-day prune would silently corrupt it), alerts for 31 days, indicators are read by nothing at all, and the learning tables are keep-forever. With horizons enforced the database plateaus around 130 MB and the free tier holds to ~2029+.
- A standing nightly gate (npm run check:data-economics) now measures the database against those budgets: size vs the 250/300 MB tripwires, each table vs its declared budget, and how many rows sit past their benefit horizon. It reports and pages - it never deletes. Pruning ships per table only after founder ratification.
- The agent harness map (/harness-map.html) refreshed with the new gate, and README / CLAUDE.md / AGENT-ONBOARDING.md all point at the three-legged doc set: ARCHITECTURE (structure), HARNESS (enforcement), LOOPS (motion).
v0.64.02026-07-18
Thumb-sized tap targets everywhere, and the alert API contract is pinned
- Every remaining small control now meets the 44px mobile touch floor: settings toggles, modal close buttons, the product-tour skip, table filters, and the community feed actions. Desktop keeps its dense look - the tap target grows only where fingers need it.
- The notification API is now contract-tested: the mute settings you save are proven to land in the database (with symbols normalised and a bad snooze timestamp failing open, never muting you forever), and the dispatch route's authorization boundary - who may send alerts to whom - is pinned so it can never silently regress.
v0.63.02026-07-18
Mute genuinely mutes, alerts never double-send, and reviews read right on WhatsApp
- The Mute button is now real. The "Muted" mode and timed snoozes ("Mute 1h/4h/tomorrow") used to live only in your browser - the server kept sending to Slack, Telegram, WhatsApp and push regardless. Mutes now sync to the server and every delivery path honors them, including per-symbol and per-theme mutes. One deliberate exception: an approval request or kill-switch notice still gets through - a mute asks for silence, not for a decision to stall.
- The same alert can no longer arrive twice. Two background schedulers could overlap and both deliver a held or retried notification; each delivery is now claimed atomically before sending (backed by a database unique index), so exactly one sender wins - and if a claimer crashes mid-flight, the nightly sweep recovers the alert instead of losing it.
- Monthly, quarterly and yearly reviews on WhatsApp now carry their actual content - portfolio return, best and toughest movers, benchmark comparison. They were being squeezed into the signal-alert template, which dropped the entire review body and dressed it up as a score. Macro and CGT notices had the same bug; all fixed.
- Turning off the weekly digest now actually turns it off. The Friday weekly report was gated on a preference column that never existed, so the opt-out was silently ignored and the report fired for everyone.
v0.62.02026-07-18
Every AI call now shows its token cost
- The AI Ops dashboard now shows what the AI actually costs: total estimated spend, average $ per run, and tokens in/out. Token counts come straight from each provider (real, not estimated); the dollar figure is calculated at list price and clearly labelled as an estimate.
- Honest by design: a call where the provider did not report usage, or a model with no price on file, is counted as "unpriced" and left out of the total - never guessed into a wrong number. Priced and unpriced runs are shown side by side so the figure you see is trustworthy.
- This closes the last cost gap in the AI posture scorecard: resilience/cost moves from A++* to a clean A++.
v0.61.02026-07-18
Paper-bot approvals are tamper-proof, and your bot feed is private
- The paper trading approval gate is now a signed, server-verified capability. Before, the approve and execute steps trusted whatever the browser sent - so a crafted request could have skipped the AI-evidence and risk checks and booked a paper fill outright. Every step is now cryptographically bound to you and to the exact order, so a fabricated, tampered, or replayed approval is refused. Paper only, as always - no real money is ever involved.
- Your paper-bot notification feed - approvals, fills, position moves - is now private to you. It used to be one shared feed, so on a multi-user deployment one signed-in person could see (and clear) another's bot activity. Flags are now scoped per user and can only ever be read or marked read by their owner.
- Under the hood: the capability is stateless (it survives serverless restarts) and portable - a clean pattern any request/response API can reuse to make a multi-step approval unforgeable without server-side session storage.
v0.60.02026-07-18
Retrieval quality: the right doc wins again
- Fixed a measured retrieval regression: asking about going live with Supabase could rank a "where to next" pointer from another walkthrough above the actual go-live guide. The semantic reranker now also weighs which doc a section belongs to, so the doc that covers your topic beats a doc that merely links to it.
- The retrieval quality gate (recall@1/@3/MRR vs the lexical baseline) is green again - the hybrid reranker measurably beats or matches lexical on every labelled question.
v0.59.02026-07-18
The accumulator wave: five loops that store learnings and compound
- Alerts finally learn from you: every alert deep link is now tagged, and opening one records an engagement - the first behavioral signal the notification layer has ever kept. Over time Lyra can show which alert types YOU actually act on, and whether relevance scores predict behavior instead of just claiming to.
- The scoring engine gains its evidence ledger: every night, each score component's values are joined to the real labeled outcomes and rebuilt into a component-efficacy table (win rate and average return per component band at 5 and 20 days). The engine stays deterministic - the ledger arms the humans who retune it.
- The copilot's unanswered questions become the content backlog: recurring topics asked by multiple users that match nothing in the vertical map are filed as content-gap cards on the Ideas board - aggregate counts only, never a quote, never an identity.
- Scout mis-attaches are correctable now: a maintainer-recorded exception (that tritium wastewater story is not fusion news) is enforced on every future run - the same accumulate-and-enforce shape as the verdict stop-list.
- The repo itself keeps ledgers too: every incident that earned a gate lives machine-readable in harness-incidents.jsonl, and every rule the adversarial verifiers learned drafting content lives in a content-rules ledger that seeds future drafts - both gate-checked so a ledger that stops parsing goes red.
v0.58.02026-07-18
Prompt-injection fence on live news, resilient middleware pinned, honest copy
- The live "smart money" feature reads market news headlines and asks the AI to extract backing events. Those headlines are untrusted outside text, so a hostile headline could try to smuggle instructions into the model. They now pass through the same injection fence the chat uses - stripped of known injection patterns and wrapped as data, never instructions.
- The resilience fix that ended last session's outage (middleware fails safe instead of crashing the whole site) is now locked in by tests, so it can never silently regress.
- Copy cleanup: replaced em dashes with plain hyphens across the interface to match house style, and corrected the site description that implied a market-timing edge ("before the crowd catches on") - Lyra is research, not a promise to beat the market.
v0.57.02026-07-18
The copilot can finally answer the macro questions it suggests
- The AI chat is now grounded in the live market snapshot: regime, VIX, Fear & Greed, yields and index moves flow into its context, so "what regime are we in?" - a question the UI itself proposes - gets answered from measured data instead of inviting a guess.
- The honesty carries through: when only sample values are available the grounding says so explicitly and instructs the model to disclose it, so demo numbers can never be presented as today's market.
v0.56.02026-07-18
Fabricated demo data can no longer masquerade as real
- Closed a data-honesty gap in the nightly workers: when a data source was unavailable (no market-events API key, or every scout feed down), the worker fell back to built-in SAMPLE data - and then wrote that sample data into the live tables the product reads. So demo earnings, demo IPOs and demo story cards could appear in the calendar and on the community board as if they were real. They no longer do: a source is either live or demo, and demo output runs the loop for shape and logging but is never persisted.
- Pinned with tests that assert nothing is written on a demo/fallback night, and that a real source with a rejected write still fails loudly (the two are now correctly distinguished, where before they were conflated).
v0.55.02026-07-17
The middleware can no longer take down the whole site
- Hardened the auth middleware so a single failed network call can never 500 the entire app again. It checks your session on every request; that check used to run with no safety net, so if the auth service blipped or the edge could not reach it, every page and API returned a server error at once - a total outage from one throw. It now fails SAFE: if auth is momentarily unavailable, public pages and APIs pass straight through (they enforce their own auth) and app pages fall back to the signed-out landing, never a crash.
- This is the kind of resilience a gate should have: it degrades to the safe, signed-out experience instead of taking everything down, and it never serves protected content when it cannot verify you.
v0.54.02026-07-17
The news intelligence layer can finally save, and the macro tapes stop showing frozen numbers
- Diagnosed the nightly "fetched 25 news items but persisted 0" failure to its roots: the database tables for news, ticker-news mapping and hype scores were built in a different shape than the worker writes - one table did not even exist on a fresh install. Migration 049 aligns all three (apply it in the Supabase SQL editor; the nightly schema-drift check will remind you until you do), and 8 new drift tests pin the worker and the schema together so they can never silently split again.
- The Markets tape now tells the truth: the risk regime appears as a word next to the dot, and a Sample badge shows whenever the numbers are the bundled demo rather than the live hourly snapshot - which the app can now actually read, for the first time, from the archive the worker builds every hour.
- The AU Macro tape - the only sample surface in the app that never admitted it - gets the same honesty chip, and AUD/USD and the ASX 200 now display live from the hourly snapshot while the seeded rows (cash rate, CPI, jobs) say so plainly until their RBA/ABS feeds land.
- The Daily Brief stops narrating a fabricated market regime: it reads the same live snapshot as the tape, so what it says about the day is what the engine actually measured.
- Small honesty fix: the calendar drawer no longer claims an unknown ticker trades on NASDAQ - it says "US listing" unless it actually knows.
v0.53.02026-07-17
AI spend controls that actually hold on serverless
- The guardrails that stop the shared AI key being run up - the per-caller rate limit and the daily token budget - now live in one shared store (Redis) instead of each serverless instance keeping its own count. On Vercel every request can land on a different instance, so the old in-memory limits reset constantly and were mostly decorative; now the ceiling is a single counter that holds across the whole fleet, and it falls back to in-memory locally without ever failing a call open.
- Three AI paths that were skipping the budget entirely - the GenUI composer, the research agent, and the paper-bot command - now charge the house budget like the chat does. An oversized single call is blocked before it spends anything, and a blocked call is rolled back so it is never double-counted. BYOK requests keep spending only the user's own key, untouched.
- All of it pinned with tests, including the fail-safe: if the shared store is unreachable, the budget still enforces via the in-memory path rather than waving calls through.
v0.52.02026-07-17
The scout loop closes: accepted cards queue a build, and your verdicts teach the machine
- v2 - Draft-a-vertical: accepting a scout card now queues real creation. Set a scout card to Planned and it enters the drafting queue (npm run scout:queue lists it, evidence attached); the /draft-vertical playbook turns it into a reviewable pull request - theme, companies, chain nodes, backing events, and the attach keywords that make the scout start MAPPING that news instead of banking it as unmapped. Agents draft, humans merge - the vertical map never changes without your review.
- v3 - Your verdicts stop evaporating. A nightly stamping pass reads every decided card exactly once: accepted cards credit the sources whose evidence backed them, declined cards debit them - an earned source leaderboard now lives on the Scout tab. Declined entities join a stop-list, so a signal you rejected can never re-file or reappear as a drumbeat. All counts, no model opinion.
- Shipped verticals get measured, not assumed: the Scout tab's theme chips now show attach volume over the trailing 14 nights - whether a vertical is actually attracting news is a number you can watch, and a scout-born vertical that goes quiet shows it.
- The full loop, end to end: noticed -> drumbeat -> card -> your verdict -> either a drafted vertical PR (and the news starts attaching) or a stop-listed entity (and the noise never returns) - with every verdict sharpening which sources earn trust.
v0.51.02026-07-17
Track Record: the real numbers, and one score that cannot silently drift
- New Track Record page (in Practice) shows how Lyra's signals have ACTUALLY resolved - win rate, average and median forward return at 1, 5, 20 and 60 days - measured from real labelled outcomes, not a backtest and not an estimate. It leads with the sample size and the exact date window, gates any group under 20 resolved signals as "still measuring", and when there is no history it says "not yet measured" rather than showing a decorative number.
- This replaces invented statistics. The strategy presets carried hardcoded win rates (the flagship claimed 67%) with a code comment saying they came from simulation - they did not, and the real measured win rate for the high-conviction signal is closer to 44%, with a roughly break-even median. Showing the humbler truth is the whole point of a research tool; the preset numbers are now clearly labelled illustrative everywhere they appear.
- Under the hood: the deterministic score now has ONE canonical implementation instead of three near-copies, and a cross-language parity contract (shared golden vectors) makes the TypeScript and Python scorers prove they agree on every commit - if either drifts, its own tests go red. Building the contract already caught and corrected the documented numbers.
- Also fixed: the onboarding strategy recommender silently recommended nothing on its main path because it matched by a display name that had been renamed - it now matches by stable ID.
v0.50.02026-07-17
Scout gets its own tab - perception and proposals, cleanly separated
- The What's New page now switches between three surfaces: Updates (the changelog), Ideas (the community board, where scout cards land as proposals), and Scout (the perception stream - what the AI scout read, per-vertical counts, and the drumbeats building toward promotion). The feed no longer pushes human ideas below the fold, and it has room to grow.
- The tab is named Scout deliberately, not "AI Signals" - in Lyra, "signals" means the deterministic trading signals the engine computes, and that word stays reserved for them. The scout reads news; it never generates trading signals.
- A one-line bridge on the Ideas tab ("Scout: 8 signals building toward promotion") keeps the story walkable in one tap - the board explains its own sparseness. Deep-link with ?tab=scout.
v0.49.02026-07-17
One doctrine for the copilot: research that checks your fit, never a trade to place
- Resolved a contradiction that had lived inside Lyra's own instructions: when you had a saved profile, the copilot was told to "size every idea" and say how many shares or dollars fit - while the same prompt's non-negotiable rule says Lyra never tells you to buy, sell, hold or size a position. Research-only is the line, and it wins.
- The copilot now CHECKS ideas against your goal, cash and risk comfort - flagging when a name sits outside your comfort or would breach your max position size - but never prescribes a share count or dollar amount. It describes the fit and leaves the decision with you, which is the whole point of a research tool.
- Pinned with a test so the contradiction cannot quietly return.
v0.48.02026-07-17
See what the scout sees - the live feed, self-verifying evidence, and an AI read
- The Ideas board now opens with "What the scout saw": last night's read counts per vertical, the freshest items with their sources, and - the best part - the drumbeats still BUILDING toward promotion ("Commonwealth Fusion Systems - 2/3 items, 1/2 sources, needs 1 more independent source"). The bar stays hard; the patience is finally visible instead of looking like an empty board.
- Scout cards are self-verifying now: every evidence link names its source and date, and long evidence lists expand in place - "2 independent sources" is something you can check at a glance, not something you have to trust.
- Each scout card gains an optional AI read: 2-4 plain sentences on what the evidence collectively suggests, grounded STRICTLY in the attached headlines, guarded against invented facts and advice, and cached so one generation serves everyone. If AI is off or the guard rejects, the deterministic summary simply stands - the card never depends on a model.
- Under the hood: the nightly scout writes a run ledger (scout_runs) the product reads, drumbeats are computed by the same Python that promotes ideas so the surface can never drift from the real bar, and this release also carries the cluster-side code the previous two releases referenced.
v0.47.02026-07-17
Honesty hardening: workers that store nothing now go red, and two privacy holes closed
- A full audit found four surviving pockets of the "green step that stored nothing" bug the last wave was meant to kill - and closed every one. The events worker's persist failures were being caught by an outer handler that reported success anyway; the intelligence worker had the whole pre-fix shape (swallow the write error, claim success); the fundamentals worker exited cleanly on a total crash because its fatal status was spelled differently from what the exit check looked for; and the scout's idea board could never save a card because its upsert key was a partial index Postgres refuses as a conflict target - the same class of bug fixed for two other tables last week, missed on a third.
- Each fix ships with a test that reproduces the exact failure and would go red if it ever came back - proven by running them against the old code first. A worker that fetches data and stores none of it now fails loudly instead of decorating a green nightly run.
- Closed a cross-user privacy hole: on a fresh install, the setup script re-opened a read leak that a prior migration had fixed, making every user's simulated paper trades readable with the public key. The reconcile step now senses the real table shape and keeps owner-only reads - verified closed on production.
- Closed a privilege-escalation hole: the community ideas board trusted a role column any signed-in user could write to their own profile, so anyone could self-promote to moderator and rewrite others' ideas. A database trigger now blocks role changes outside the server - live on production.
v0.46.02026-07-17
The macro fleet: RBA decisions in your channels, a live calendar, CGT radar, and your return in AUD
- Lyra now watches the Reserve Bank. On each of the 8 decision days a year (seeded from the RBA's published 2026-27 schedule, verified at the source), a dedicated job fires minutes after the 2:30pm announcement: it reads the official statement, extracts held / cut / raised and the new cash rate from the Board's own words, measures the AUD/USD move since just before the announcement, and tells you what that does to your US holdings in AUD terms. If the statement cannot be read, the alert still fires - it just refuses to quote a number it never saw.
- Morning companions ride the nightly run: a pre-brief on decision mornings, a note when the Board minutes drop two weeks later, a heads-up when the RBA Chart Pack updates the morning after each meeting, and an FOMC morning-after brief the day the Fed moves overnight.
- The calendar is finally alive end to end: 56 seeded macro events (every RBA decision, minutes and Chart Pack date for 2026-27, every 2026 FOMC decision) now flow into the events table nothing had ever written to, and the calendar drawer stops being four bare facts - macro events show what the event is, why it matters, the announcement's local time, and a link to the primary source. Earnings for names you hold or watch, and imminent IPO listings, now alert the morning before they land.
- The Command page countdown ticks to real instants now - the next RBA decision counts down to 2:30pm Sydney and the FOMC to 2:00pm New York, timezone-correct across daylight saving, fed live from the calendar instead of a hand-curated list.
- CGT radar: every position with a purchase date now shows where it sits against the Australian 12-month CGT discount - a quiet held-duration badge that turns amber inside 30 days of the anniversary and green past it - and gains get a notification at 30 and 7 days out. Date math from your records, general information not tax advice.
- Your reviews now benchmark honestly: the monthly, quarterly and yearly reviews add a you-vs-S&P-500 line, and the Friday weekly report translates your USD return into AUD terms using the week's actual currency move. Both lines are measured from stored market snapshots and are silently omitted until enough history exists - never estimated.
- Found and fixed along the way: the hourly market snapshot (regime, VIX, AUD/USD) had been failing to store since the table was created - a NOT NULL column the insert never supplied, swallowed by a catch-all guard. The macro history archive starts accruing for real tonight.
- Macro alerts are ON by default from this release (they were silently off) - 8 decision days a year is signal, not noise. One toggle in notification settings turns the whole pillar off.
v0.45.02026-07-17
The harness learns from its own gaps
- The version guard now blocks a release that would move the app version backwards. Two agent sessions can ship from one shared tree, and the version counter they share had no direction check - a real regression this week proved it.
- Scout hardening: live and demo mode now share one clustering pipeline (the forked path caused a real crash), the 14-day drumbeat window announces loudly if it ever saturates instead of silently weakening, and scout items older than 90 days are pruned so the table cannot grow without bound.
- The lessons behind every gate are now written where people actually read them: a new "How this repo stays honest" section in the README, hard rules in AGENT-ONBOARDING, and two new earned-lesson entries in HARNESS.md.
v0.44.12026-07-17
Scout demo-mode fix, proven by its first production run
- Fixed a crash in the scout worker when running with no database configured (the demo promise): a refactor left the keyless path referencing a value only computed on the live path. Pinned with a test that runs the whole orchestrator keyless.
- The scout completed its first production run tonight: 400 broad-signal items read from 36 live feeds, attached across all ten verticals, with 110 unmapped items banked into the 14-day window where emerging-vertical drumbeats accumulate. No idea cards yet - the bar (3 items from 2 independent sources) is deliberately hard to clear on night one.
v0.44.02026-07-17
Your reviews now actually arrive - monthly, quarterly and yearly, with your real return
- The periodic reviews finally have a scheduler. On the last trading day of every month, quarter and year, Lyra now measures your portfolio and sends the review to your channels - and if a run is missed, it self-heals: the review arrives a night late instead of never, and can never double-send.
- The performance number is real, not narrated. Your return is measured from the same stored prices the scanner scored: positions you held at the start of the period are measured from the period-open price, and positions you bought during the period are measured from what you actually paid - so nothing is credited or blamed for price action you never held. Positions with no price data are skipped and the skip is counted, never hidden.
- Each review names your best and toughest position for the period with its measured move, so you can really see how you did at every zoom level - week, month, quarter, year.
- The Friday weekly report now carries your measured weekly portfolio return too, and Slack reviews show the same cash-with-wings performance tiers as Telegram (5% / 10% / 15%), with losses shown honestly in red.
- Under the hood the measured number now survives the whole pipeline: it rides the dispatch API, is stored with the event, and is rebuilt correctly when a review held by quiet hours is released later - previously the renderers supported a performance badge that nothing could ever feed.
v0.43.02026-07-17
Deploys verify themselves now - and a fresh clone is proven to build, on every push
- Every push to main now gets a deploy smoke check: a workflow waits for the live site to actually serve the version that was just pushed, then probes the health endpoint, the landing page content, and the sign-in gate - and pages Telegram and Slack if any of it fails. CI proves the build; this finally proves the DEPLOYMENT, which is where six past bugs slipped through behind green tests.
- A fresh install is now a guarantee, not a hope: CI builds the ENTIRE database schema from empty on every push - all 43 migrations in order plus the reconcile script, against a throwaway Postgres. The class of bug where a new clone could not build the schema at all (it shipped once) now turns the build red before it merges.
- The new gate paid for itself on its first run: it caught a demo seed writing against a constraint that no longer exists and 8 stale indexes referencing columns from pre-multi-user table shapes - all of which would have broken every fresh install following the documented setup path. All repaired, with guards that stay correct on both old and new installs.
- Both gates are registered in the harness enforcement map (HARNESS.md) with the one rule every Lyra gate must obey: a green must be able to go red.
v0.42.02026-07-17
A background job that stores nothing now says so, instead of reporting success
- The nightly jobs can no longer claim success while saving nothing. Both the events and fundamentals jobs caught their own database errors, logged a quiet warning, and reported "success" - so for months the dashboards showed a healthy green run while the tables sat completely empty. A job that fetches 21 events and stores none of them has failed, and it now says so loudly enough to trigger an alert.
- The per-stock log no longer lies either: it used to print "snapshot + metrics persisted" for every company regardless of whether the write actually succeeded. It now reports the real number stored.
v0.41.02026-07-17
The calendar and fundamentals are storing real data for the first time
- Company events and fundamentals now actually save. The nightly jobs had been reporting success while writing nothing at all: the upsert key was built as a partial index, which Postgres cannot use as a conflict target, so every single write was rejected and the jobs logged a warning and carried on. Both tables were empty. They now hold real rows, which means the market calendar reads live events and fundamentals have somewhere to land.
- This was caught by watching a real run persist zero rows rather than by trusting a green tick - the job had been "succeeding" the whole time.
v0.40.02026-07-17
The new reviews could never have been delivered - the API was rejecting them
- Fixed a gap that would have made the weekly, monthly, quarterly and yearly reviews impossible to send. Every renderer supported them, but the endpoint that actually accepts an alert kept its own hand-written list of allowed types - and the reviews were not on it. They would have been turned away as "type is invalid" and never reached you.
- Closed the whole class of bug rather than the one instance: the list of valid alert types is now generated from a single source that the compiler forces to stay complete, so adding a new kind of alert can never again leave the door shut behind it.
v0.39.02026-07-17
The AI scout: Lyra now reads the wide world nightly and files evidence-linked ideas on the board
- Lyra can now NOTICE. A nightly scout reads a curated registry of 100 broad-signal sources - 36 open feeds (NASA, DoE, DoD, SpaceNews, SemiAnalysis, World Nuclear News, IEEE Spectrum, mining and quantum trade press) plus the Finnhub general-news firehose - and deterministically attaches every item to the vertical map. All 36 feeds were verified live before shipping.
- Signal with NO home vertical is the interesting part: when an unmapped entity recurs across at least 3 items from 2 independent sources inside a 14-day window, the scout files an idea card on the SAME Ideas board humans use - marked Scout, with the evidence links attached and a confidence that is pure breadth math, never a model opinion.
- Humans stay in charge by construction: the scout only ever writes cards. It cannot touch the vertical map, and moving a card (planned, in progress, shipped, declined) is maintainer-only, enforced in the database, with one-tap status controls on the board for the maintainer.
- The registry also encodes where the scout will grow: 22 crawl targets (pages with high signal but no feed, like the DoD daily contract announcements) light up the moment a Firecrawl key lands, and 41 niche voices on X - from Dylan Patel to fusion and uranium specialists - are registered for when X API access exists. Gated honestly: registered intent, not pretended coverage.
- Fully harness-owned from day one: a new /scout-intel skill chain owns the worker, 17 new tests pin the honest behaviours (two-letter tickers never match bare text, one outlet drumbeating is never signal), and the nightly job reports failures loudly instead of green-ticking.
v0.38.02026-07-17
Weekly, monthly, quarterly and yearly reviews - see how you are actually doing
- Lyra can now deliver a weekly, monthly, quarterly or yearly review, so you can finally see how you are doing over a period that matters instead of only what fired in the last hour.
- A good period looks good before you read a word: your return rides in the header with a cash badge that escalates as you climb - one at +5%, two at +10%, three at +15% and above.
- A bad period is never dressed up. A losing review carries a red marker, not a softer emoji - if the cash badge could show up on a loss it would tell you nothing.
- Reviews are written to land a finding, not dump statistics: what changed, what it cost or earned you, and the one habit behind it.
- Delivery only for now. Nothing generates these on a schedule yet, and the return figure is not yet computed from your real positions - the jobs that do both are next.
v0.37.02026-07-17
Telegram alerts are readable now: colour-coded relevance, real formatting, no more wall of text
- Telegram alerts have been rebuilt. Slack had a purpose-built layout while Telegram fell back to a plain-text format meant for the wire - one dense paragraph, no formatting, capped at 399 characters on a channel that allows 4096. Alerts now arrive with a proper header, bold title, scannable body and a tappable link.
- Your relevance score is now a colour-coded meter you read at a glance - green for a strong 70+, amber in the middle, red below 40 - instead of a number buried in a sentence.
- The engine's reason for firing now sits in its own quoted block, so the provenance reads as a citation and never gets lost in the narrative.
- Your chosen alert personality (Analyst, Coach, Minimal or Narrator) now applies to Telegram too. Previously only Slack honoured it.
- An alert can no longer be lost to a formatting bug: if the rich layout ever fails to parse, the message is re-sent as plain text rather than silently dropped.
v0.36.02026-07-17
The Ideas board can actually save your ideas now - four migrations had never reached production
- Your ideas and upvotes now save. The Ideas board shipped without its two database tables ever being created in production, so every suggestion and vote was writing into nothing. The tables are in place now - along with three other database changes that had silently never been applied: your goal target can persist, activation tracking records again, and the digital twin has its consent switch.
- Fixed the ordering bug that caused it. A migration that adds columns to the calendar table was numbered to run AFTER the one that indexes those same columns, so setting up a database from scratch failed outright with "column ticker does not exist". The reconcile now runs first, and a fresh clone can build the whole schema in one pass.
- The nightly jobs are now writing to a database that matches them: the calendar, fundamentals and event-risk tables all have the columns their jobs have been trying to fill.
v0.35.02026-07-17
The chain explorer: every vertical traced end to end, and the chains are finally deep
- The end-to-end value chain is now an interactive explorer on Small Caps: chip tabs switch between all ten verticals - AGI Infrastructure, Quantum, Robotics, Space, Power Grid, Nuclear, Semiconductors, Critical Minerals, Defence and Cybersecurity - and selecting a shortlist name snaps the explorer to its vertical with the name highlighted where it sits in the chain.
- The chains got deep. Nine verticals had only 2-4 supply-chain tiers mapped while AGI had 16 - every vertical now carries 8-12 nodes spanning end demand down to raw materials, with 120 companies and 95 capital events across the map (was 45 companies and 48 events). Every new row passed an adversarial fact-check before landing, and the ones that did not were struck.
- Backing integrity held: every small cap on the map now connects to at least one DISCLOSED backing source - 16 real capital events landed (DOE loans, US Navy contracts, NASA agreements, an Nvidia partnership), 5 names were honestly resized out of small-cap (Argan and MYR Group outgrew it), and 6 names with no defensible backing were removed rather than propped up.
- The chain is no longer hidden below the fold: a "Trace the full chain" action on every selected name jumps straight to the explorer, the shortlist cards are one-line compact instead of four stacked rows, and a verticals strip in the page header shows all ten focus areas with their tracked small-cap counts.
- AGI Infrastructure now wears a robot instead of a brain (a brain read as biotech), and Robotics & Automation takes the mechanical arm - every vertical has a distinct mark.
v0.34.02026-07-17
The nightly jobs were failing silently every night - your digest, calendar and fundamentals are fixed
- Your daily digest is fixed. It had been crashing every single night before a single message went out: a market-wide digest was being filed against a made-up ticker called "MARKET", and the database rejected it outright. A digest is not about one stock, so it is now filed with no ticker - which is the honest answer and what the schema always allowed.
- The market calendar reads live events again. The events table had been defined twice with two different shapes, and the version the app actually reads never took effect - so every calendar lookup asked for a date column that was not there. The two definitions are now reconciled into one.
- Company fundamentals are being saved again. Every nightly snapshot, for every ticker, was silently rejected because the table was missing thirteen of the columns the job writes - including cash, debt and the P/E ratios. Nothing had been stored.
- Event risk actually works now. The nightly job was reading a table that has never existed, so every ticker came back "inactive" and no event risk was ever raised. It also kept the OLDEST reading per stock instead of the newest.
- Added a build gate that blocks this whole class of bug: it fails the build if two migrations share a version number or define the same table with different shapes - the exact traps that let all of the above fail quietly for so long.
v0.33.02026-07-17
Product updates and Ideas get the premium glass treatment
- The Product Updates page has been rebuilt around a single glass header with a sliding Product Updates / Ideas switch, replacing the stack of boxed panels that repeated the same sentence three times over.
- Releases now read as a proper timeline: one continuous rail threading every version, with the build you are on marked by a lit amber node.
- The Ideas board is cleaner and easier to scan - a functional toolbar showing how many ideas there are and how they are sorted, roomier upvote controls, and a friendlier empty state.
- Glass surfaces now degrade gracefully: if your browser cannot blur, or you have asked your device to reduce transparency, every panel falls back to a solid, readable fill.
v0.32.02026-07-17
Settings split into three focused pages instead of one long scroll
- Account settings are now three separate pages with a tab switcher at the top: Account (your profile, a device PIN lock, and your data), AI Settings (the model that powers Lyra), and Notifications (push, Telegram, WhatsApp, Slack). No more scrolling one long page to find the setting you want.
- Every link that used to jump to a section of the old page - the account menu, the AI prompts in chat, the setup checklist and product tour - now opens the right page directly.
v0.31.02026-07-17
Lyra listens to your onboarding: the copilot now tailors itself to how YOU answered
- The AI copilot now reads your full onboarding profile. If you told us you are new and want step-by-step explanations, a few-months horizon, or just the signal with no lecture, Lyra tailors its depth, tone and framing to exactly that - instead of treating every beginner the same.
- Lyra sizes ideas against your own money goal now - suggestions relate to the target you actually set, not a generic milestone.
- Hardened the profile read so a not-yet-applied database change can never blank out your whole personalisation. At worst one optional field falls back to a sensible default; the rest of your profile always reaches the AI.
- Added a deterministic build gate that proves every onboarding answer is saved, read back, and reaches the AI - so this personalisation can never silently drift if the code changes later.
v0.30.02026-07-17
The floating button gently nudges Feedback into view now and then
- The floating Ask Lyra / Feedback control now brings Feedback forward for a couple of seconds every so often, then slides back - a quiet reminder that the same button is where you tell us what to fix or build, so you never have to go looking for it.
- It never interrupts: the nudge is skipped while a panel is open, and it stays completely still if your device is set to reduce motion.
v0.29.02026-07-17
Product Updates gets an Ideas board: suggest features and upvote what we build next
- The Product Updates page now has a two-tone switch - Product Updates (the release history) and a new Ideas board where you can suggest a feature and upvote the ones you want most, so what gets built next is driven by what you vote for.
- Each idea shows its date, title and description with a one-tap upvote and a live vote count, ranked most-wanted first. One vote per person per idea - tap again to take your vote back.
- The in-app feedback box now links straight to the Ideas board when you pick "Idea", so a suggestion can become something others rally behind.
- Fixed a confusing double changelog: the product-updates timeline is now generated from one source of truth (the version log) and is searchable, instead of a version list sitting next to a separate feed that had drifted out of date.
v0.28.02026-07-17
Clearer notifications: an honest per-device push badge, real Telegram and WhatsApp logos, and sharper alert copy
- The push badge now reflects THIS device, not just your account. Before, it showed a green "on" whenever any device you own was subscribed - so an iPhone that had never granted permission still looked done. It is now green only when this device has actually enabled push, and shows an amber "Not on this device" otherwise, so the one tap that matters is obvious.
- Telegram and WhatsApp now show their real brand logos beside their fields and save buttons, matching Slack - no more generic placeholder icons. Nothing ships unbranded.
- Sharper alert copy: the test push and the service-worker fallback no longer repeat "Lyra" in the headline (your phone already shows the app name), so the title reads as one clean line instead of wrapping onto two. The test message now confirms push is live and previews how a real alert will land.
v0.27.02026-07-17
Make it yours: a customisable bottom bar, a colourful Explore, cleaner type - and an honest goal bar
- Your bottom bar is now yours to arrange. Open Explore, tap Customise, and drag your daily surfaces into any order, remove the ones you never touch, and add any surface from the app - placed wherever you want. Your layout is saved on your device.
- The Explore drawer now reads in Lyra colour, grouped by the job it does: amber for Your desk, cyan for Discover, purple for Research, green for Practice, pink for Learn - so the eye finds things by colour instead of scanning a grey wall.
- Cleaner bar by default: Portfolio and Watchlist are spelled out in full, and Paper Bot now rides the bar (Trade Plan moves one tap into Explore). The bar also sits a little higher so it clears the phone home indicator.
- Fixed a confusing goal reading: the progress bar now runs straight from zero to your target, so "X of Y", the percentage, and the amount to go all agree - no more 6% sitting next to "$26.6k of $50k".
- A more premium, consistent typeface across the app (the native Apple system font) with crisper rendering - and the Settings form no longer bounces between monospace and sans: placeholders and fields now read in one clean face.
v0.26.02026-07-17
Error monitoring verified live in production - and the setup scaffolding is removed
- Confirmed Sentry is armed in production: the DSN is inlined in the deployed client bundle, so a real crash - a browser error, a server exception, or a 500 in an API route - is now captured with a stack trace instead of vanishing. It stays optional and privacy-safe: with no DSN set (demo mode, self-hosting, forks of this repo) it sends nothing at all.
- Removed the two temporary example routes the Sentry setup wizard created - a public page and API that deliberately throw an error. They existed only to prove reporting worked; with that confirmed, the app no longer exposes any deliberate crash endpoint.
- No behaviour change for users: the monitoring runs silently in the background and only ever reports genuine errors, never usage or content.
v0.25.02026-07-17
Error monitoring: Sentry now catches crashes and server errors in production - optional and off by default
- Wired Sentry across all three Next.js runtimes (browser, server, edge) so a real crash - a frontend error, an unhandled server exception, a 500 in an API route - is captured with a stack trace instead of vanishing. Until now the only production signal was /api/health plus the scanner paging on failure.
- Optional and privacy-safe by design: it reports only when a Sentry DSN is set in the host environment, so demo mode, self-hosting, and forks of this repo send nothing at all. No session replay, no user data - just errors and a 10% trace sample in production.
- The root error boundary now reports the crashes that reach it, and source maps upload on production builds so a real-user stack trace points at real code instead of minified noise.
v0.24.02026-07-17
Your Activity: a private, on-device dashboard of how you use Lyra - time, sessions, AI questions, and a surface heatmap
- A new Your Activity page (in Explore under Learn & set up) shows how you actually use Lyra: total time on the app, number of sessions, active days, average session length, and how many AI questions you have asked.
- A surface heatmap shows which parts of Lyra you live in - every surface you visit, tinted brighter the more you use it, with a ranked most-used breakdown (visits, share, and time on each). Click any tile to jump straight there.
- Private by design: it is computed entirely from your own browser storage and never leaves your device - no account needed, no server, nothing tracked about you anywhere. A one-click "Clear my activity" wipes it whenever you want.
- It also quietly powers the owner-side Vercel analytics that was already wired, so the same navigation now feeds both your personal page and the aggregate dashboard - without double-counting or sending any content.
v0.23.02026-07-17
Global rate limits: the abuse guard now counts across every serverless instance, not per-instance
- The three unauthenticated endpoints (per-symbol signal refresh, ticker lookup, and in-app feedback) now enforce their rate limits across every serverless instance at once, using the shared Upstash counter instead of a separate in-memory bucket per instance. Before, a burst spread across instances could get several times the intended allowance; it is now one exact global budget per IP.
- Fail-safe by design: with Upstash unconfigured (demo mode, self-host) or briefly unreachable, the limiter degrades to the in-process guard rather than failing open - it always does something, and the app still runs with zero keys.
- Proven, not assumed: a new test clears the in-memory buckets between calls to simulate a request landing on a fresh, cold instance and shows the shared counter still blocks an over-budget request - the exact gap this closes.
v0.22.02026-07-17
One clean rail and an Explore drawer: the daily-drivers up front, the deep research one tap away
- The navigation no longer shows all 34 surfaces at once. The rail (and the mobile bar) now carry just the daily-drivers - Command, Portfolio, Watchlist, Plan - so the goal cockpit owns the screen instead of competing with a wall of icons.
- Everything else lives in a new Explore drawer, grouped by the job it does: Your Desk, Discover, Research, Practice, and Learn. One tap opens it, one tap gets you anywhere, and it closes on Escape, a tap outside, or when you navigate.
- Nothing was removed - all 34 surfaces are still there, just organised by what you are trying to DO rather than listed flat. The Explore control highlights when you are inside one of its surfaces, so you always know where you are.
- On mobile this replaces a 34-item horizontal scroll with five evenly-spaced tabs, so the thing you need is no longer three swipes away.
v0.21.02026-07-17
True orientation: both sides of every name you hold and watch, and a goal target that is your own number
- The cockpit now shows a two-sided orientation across the names you hold AND the names you watch: what is good (opportunities) and what is bad (risks), side by side, from the live news flow. Not just downside and not just holdings - a balanced read of both sides at once, weighted toward the names where your money is on the line.
- Bad news on a name you own no longer hides in a feed you have to go find. If something breaks on a holding, it surfaces as a risk right in the cockpit; if something good lands, it shows as an opportunity - each one links straight to the ticker.
- Your goal is now YOUR number. Set a target like $50,000 and the whole cockpit re-anchors to it - the progress bar, the amount to go, and the pace all track the goal you actually stated. Leave it unset and it still climbs a sensible milestone ladder so there is always a next number to reach.
- The target is saved to your profile (owner-scoped, private to you) and editable inline from the cockpit in one click - no digging through settings.
- As always: every read is deterministic and two-sided by design - it shows the good and the bad, and never turns either into a buy or sell instruction.
v0.20.02026-07-17
The goal cockpit: your target, your progress, and the exact moves your money needs - exits first
- The home screen now LEADS with your goal, not a wall of data. A cockpit at the very top shows where you stand - your account value, your return on invested capital, and a progress bar climbing to your next milestone (or your own target) - so you never have to hunt for whether you are winning.
- Under it sits "what needs you now": a short, ranked list of the actual moves your book needs, built deterministically from the engine reads on YOUR positions. Protecting capital comes first - a broken thesis or a position through its loss line is the loudest row, ahead of any new idea.
- Downside and exits are first-class. It flags when a setup that put a name in your book has invalidated (the get-out signal), when a position is past the loss line for your risk profile, when risk is rising, when a winner is extended enough to bank some, and when one name has grown too large for the book.
- It is personalised: your risk comfort widens or tightens the loss and profit lines, your cash and holdings drive the standing, and idle cash and behind-pace nudges only surface when nothing more urgent is competing.
- Honest by construction: every read is deterministic math on your own positions and goal - risk framing, never a licensed buy/sell call. The app prompts the decision and points you to size it in the Trade Plan; the trade is yours, placed at your broker.
v0.19.12026-07-17
Landing polish: the alert-channel pills get their own line
- On the landing page, the Telegram / Slack / WhatsApp pills now sit on their own line below the "Alerts, where you live" label instead of wrapping unevenly beside it on narrow screens.
v0.19.02026-07-17
Quantified upside and honest freshness: the high-upside shortlist finally puts a number on the payoff, the live scanner covers the small caps, and stale boards say so
- The emergence shortlist now QUANTIFIES upside instead of only ranking it: each name carries a deterministic bear/base/bull re-rate estimate, a base-case upside %, and an asymmetry ratio (upside vs downside), plus a tier - Asymmetric, Balanced, Limited, or Lottery. It is a model estimate of payoff shape from disclosed factors, clearly labelled as such - never a price target or a promised return.
- The live scanner now covers the 14 small-cap emergence names it never touched before. Previously the scan universe was 100% large-cap, so every high-upside name fell back to a neutral momentum reading and the "market is turning" signal was structurally dead for the exact list the app exists to surface - that leg is now wired to real momentum.
- Honest catalyst freshness: the Catalyst Radar and the countdown are hand-curated editorial lists, and when every event passes they used to silently render nothing - reading as "all quiet" when it meant "nobody refreshed the list". They now show the curation date and an explicit "refresh due" state so an empty board can never masquerade as a calm calendar.
- The position-size calculator now links straight to the Trade Plan, so working out a size flows into sizing it against a real name, your own cash, and the round-trip cost and expectancy - the decision-moment surface is one click from the math.
- Every new upside and conviction number ships with the same discipline: it is a deterministic estimate of shape, it says when no measured track record stands behind it, and it never reads as a proven return.
v0.18.02026-07-17
Portfolio-aware, honest about capital: no more fantasy $100k account, real small-account costs, and win rates that never masquerade as a track record
- The paper account no longer starts from a fantasy $100,000 balance: a new account begins from the cash you actually have on file (or a realistic small-account example when none is set), so you practise the position sizes you can really take instead of ones that only work on paper.
- Simulated fills now charge a realistic fixed commission floor instead of a flat 0.05% - the cost that most distorts a small account, where a $3 minimum is a real slice of a $500 trade but a rounding error on a $30k one. Your paper track record is now honest about the drag a beginner actually pays.
- The Trade Plan is now portfolio-aware, not just single-position: it reads your open positions and flags when adding a name over-deploys the whole account (little dry powder left) or piles too much into one correlated theme - the concentration risks that sink small accounts even when each trade looks fine alone.
- Onboarding honesty fix: the strategy picker used to show win rates like "68% win" with no label, reading as a measured fact on the very first screen. Those figures are now clearly marked illustrative - what the strategy aims at, not proof of what it returns.
- The signal-intelligence board now says plainly that its conviction score has no measured track record yet: high agreement between signals today is not a proven hit rate. No number in the app should feel more certain than the evidence behind it.
v0.17.02026-07-17
Honest edge and a real trade plan: sizing to your own capital, netting costs against the signal, and never dressing up a guess as history
- A new Trade Plan surface (/plan) sizes one name against YOUR real capital, not a fantasy account: it floors to whole shares, tells a small account when an entry price is simply out of reach, and shows the worst-case dollar loss if the stop is hit - the position-size math finally lives at the moment of decision instead of a separate calculator page.
- The plan models the costs that actually hurt a small account: a fixed commission floor (which is a big slice of a $300 trade), the AUD-to-USD FX spread you pay twice on a US ticker, and wider slippage on thin small-caps - then shows the break-even move you need just to cover the round trip.
- Every win rate now travels with its expectancy, so a high hit rate on tiny wins and large losses (the classic mean-reversion trap) can no longer read as edge - and the plan flags when friction wipes out an otherwise-positive edge for your account size.
- Honesty fix: illustrative outcome numbers are now labelled "illustrative, no measured history yet" wherever they appear, the live signal drawer needs a real 20-sample floor (not 5) before it shows a measured win rate and caveats small samples, and a break-even move no longer counts as a win.
- The AI research assistant can now build the same cost-aware, expectancy-aware plan on request (read_trade_plan) - it presents the risk flags honestly and, as always, never turns them into a recommendation to trade.
v0.16.02026-07-16
The calendar tells the truth and every dialog behaves: live events, a real clock, and one shared focus system
- The calendar was frozen in time - a hardcoded "today" of June 3rd meant every countdown in the app was weeks wrong. It now runs on a real clock, reads the nightly-synced event tables when configured (bounded to the 30-day board window so earnings season cannot truncate it), and honestly labels live vs sample data.
- IPO listings now appear on the live calendar too: they live in their own table, so the live board synthesizes their entries with importance scaled by valuation - previously flipping to live mode silently deleted the entire IPO event class the sample set had.
- The sample calendar can never age out: demo events re-anchor to today on every request (not once at server start), so a self-hosted demo deploy that has been up for a month shows the same fresh month of events as a cold start - pinned by a test.
- Every dialog now behaves like a dialog: focus moves in on open and returns on close (screen readers were being stranded behind the backdrop), Tab is contained with hidden elements filtered out, overlapping overlays negotiate via a shared dialog stack instead of fighting over keystrokes, and the feedback sheet joins the same system with Esc-to-close.
- Esc in a deep investigation now steps back one level - matching the on-screen Back button - instead of throwing away the whole trail, and the event drawer shares the exact clock and event set as the board that opened it, so the two can never disagree near midnight.
v0.15.02026-07-16
On the move: fresh IPO data, live-refreshing drawers, and a console that respects your thumb
- The IPO radar now serves the live calendar: the nightly Finnhub sync (which was filling a table nothing read) feeds the page hourly, a past-dated "upcoming" IPO can no longer pretend it has not happened, the date sort finally puts the soonest listing on top, and the page says honestly whether you are looking at the live calendar or the sample set.
- The signal drawer refreshes itself the moment you open it - current engine numbers for that one symbol instead of the page-load snapshot, a "how setups like this resolved" line from measured outcomes, an optional AI read grounded on exactly the figures shown (server-side, fabrication-guarded), and a shareable link: /radar?signal=NVDA opens straight to the setup.
- Drawers behave like drawers now: the page behind stops scrolling on every overlay (the #1 mobile scroll leak), Esc closes the chat sheet, focus moves in and returns on close with proper dialog semantics, content clears the iPhone home indicator, and the IPO drawer rides the same shared shell as everything else.
- Mobile screens got their space back: the watchlist no longer renders your entire list twice, the radar caps its card stack with "show more" paging, the nine catalyst cards fold to headline + heat until tapped, the intelligence filter wall collapses behind a Filters toggle, and the home "strongest setups" table - the last one without mobile cards - got them.
- Honesty and thumbs: pulsing "Live" badges on last-scan data now say "as of last scan", sample data is labeled as sample, and the primary controls (IPO filters, panel pickers, chart toggles, refresh) meet the 44px touch floor on small screens.
v0.14.02026-07-16
Signature onboarding: a branded terminal splash, gate micro-delight, a private commissioning card, and a live nervous-system map
- npm run dev now opens with a branded first-run splash - the Lyra wordmark in the tri-gradient with "by Vivacity.ai" - printed right before the localhost URL. Truecolor, gracefully plain on a non-TTY, and it can never block the dev server.
- The Setup Companion celebrates progress: the moment a stage clears, its card gets a one-shot tri-gradient shine sweep, plus an opt-in soft tone. Transitions are baseline-seeded so opening the page mid-setup never bursts, and prefers-reduced-motion is fully respected.
- A private commissioning card: once a fresh clone reaches a healthy deploy, npm run commission writes a branded receipt (commission/card.svg + COMMISSIONED.md) into the clone - a local keepsake, read from /api/health, gitignored and never shared anywhere.
- A new nervous-system map at /harness-map.html renders SKILL-CHAIN.md + HARNESS.md as one interactive page - click a chain to focus the sections it owns, filter by path, and see every deterministic gate. Generated on the content pipeline so it can never drift from the rails it describes.
- The README now spells out how to share Lyra by audience - a live link for humans, a fork for builders, AGENT-ONBOARDING.md for agents - and the onboarding ledger records every new asset.
v0.13.02026-07-16
Your digital trading twin: Lyra now learns your interests, habits, and risk posture - and reflects them back
- New "Your Twin" surface (/twin): a private, research-only mirror of how you actually trade - your top themes, the signal kinds you trust, your stage lean, and the gap between the risk posture you stated at onboarding and the one your paper trades reveal. A mirror, never advice - the deterministic engine still owns every signal.
- A real deterministic preference model computes your affinities and revealed-risk stats (average position size vs your stated cap, sizing up after a losing close, late-stage chase, theme concentration) from data Lyra already holds - no LLM, fully unit-tested.
- Opt-in, inspectable, portable, deletable: a consent switch gates all behavioural capture (default off), with server-side inspect (GET /api/account), export (a versioned JSON snapshot of your profile + twin), and true delete (wipes every server row) - and the old "nothing is uploaded" copy is now honest.
- The copilot can cite your twin (a read-only read_trading_twin tool) and remembers you across sessions (opt-in conversational memory), and the command centre now surfaces equally-scored names you care about first - with an enforced anti-bubble duty so risk is never hidden.
- Row-level-security hardening: tightened the read policies on the paper-trading tables so your simulated trades are strictly owner-only, plus a migration-scanning test that fails the build if a future change ever re-opens them.
v0.12.02026-07-16
The agent harness: every section of the codebase now has an owning maintenance chain, enforced in CI
- New HARNESS.md maps the full enforcement system - deterministic gates (scripts/check-*.mjs), git hooks, CI jobs, the test harness, runtime guards, and scheduled loops - so any agent (or human) can see exactly what keeps this repo honest and how to work inside it.
- New SKILL-CHAIN.md registry assigns every code section an owning skill chain via a machine-checked coverage map: 254 sections, 12 chains, zero orphans - an unowned section now fails CI (npm run check:chains).
- Seven new skill chains join setup, production-keeper, feedback-loop, onboarding-parity, and logs-to-genui: /signal-quality (evidence-backed scoring), /ai-quality (evals + guardrails + system card), /notification-health (delivery + template completeness), /onboarding-funnel (activation drop-offs + the demo promise), /data-integrity (migrations, RLS, demo parity), /security-sweep (secrets, fail-closed authz, abuse limits), and /ux-surface (one surface to premium per loop).
- Every chain carries the same contract: staged gates, execution over advice, and explainability - each run ends with shipped, verified work and a plain-language report backed by engine-owned numbers.
- The harness is wired into onboarding: AGENT-ONBOARDING.md, the ONBOARDING.md ledger, CLAUDE.md, and the /setup wrap-up all route new agents through HARNESS.md and the coverage map.
v0.11.22026-07-16
Onboarding stays honest: a parity gate + skill chain across the human, in-app, and agent surfaces
- The three onboarding surfaces - the human walkthroughs, the in-app Setup Companion, and the agent front door - now have a deterministic parity gate (npm run check:onboarding) that runs in CI, so they cannot silently drift from the stack, costs, routes, or walkthroughs the code actually ships.
- A new /onboarding-parity skill chain (with per-surface skills for human, companion, and agent docs) restores parity in one pass and proves it with the gate.
- The in-app Setup Companion copy is now generated from its source at build time, so the served page can never fall behind the authored one.
v0.11.12026-07-16
The loop closes: measured outcomes, real digests, follow-up coaching + a console that cannot silently fail
- Every setup now gets its outcome measured: a nightly job computes forward returns (1d/5d/20d/60d, max upside, max drawdown) from the same stored candles that scored the signal, and once the 5-day horizon resolves you get a follow-up alert - "your NVDA setup from Jul 9 is +8.2% after 5 days, cohort median +3.2%" - so the scanner finally answers whether its signals work.
- The daily digest is real: an end-of-session summary (setups found, top scores, alerts sent) lands on your channels every trading night, with a weekly report on Fridays. Quiet-hours alerts are held and released when your window ends - never dropped - and a failed delivery retries once instead of dying silently.
- Published scores can no longer repaint: the in-progress hourly bar is discarded before scoring, so every number an alert cites stays reproducible forever. The three dormant data workers (events + IPOs, fundamentals, intelligence) now actually run nightly, and provider hiccups retry with backoff.
- Console you can trust: the side rail scrolls with visible groups (nothing clipped at 1080p any more), branded error and 404 pages replace the white crash screen, every tab carries its own title, the What's New dot only lights for releases you have not seen, and "Explore the demo first" walks a visitor through the real console read-only before sign-up - while demo-entered holdings and watchlists now survive into a new account.
- Locked down and self-watching: the research tables are read-only under RLS (they were writable with the public anon key), version bumps are enforced in CI so nothing ships undescribed, a failed scan pages Telegram/Slack and the cron keeps itself alive past GitHub's 60-day auto-disable, and /api/health reports when the scanner last ran.
v0.11.02026-07-16
Security hardening: SSRF fences, tenant isolation, founder-gating
- Web Push endpoints are now fenced to the real push services (Chrome, Apple, Firefox, Windows) over https, at both save and send time - a subscription can no longer point the server at an internal address, and failed sends no longer echo the remote response.
- The founder-only insights view is now authorized, not just authenticated: it reads cross-tenant question text, so it is gated to a FOUNDER_EMAILS allowlist and fails closed when unset.
- The paper-account view returns an empty account for an unauthenticated request on a live deploy, instead of ever falling back to the shared in-memory store - no cross-tenant positions can leak.
- The post-login redirect only accepts same-origin paths, closing an open-redirect that could bounce a visitor off the trusted domain.
- All four hardened by an adversarial security audit; the SSRF allowlist and the redirect guard are pinned by tests.
v0.10.02026-07-16
AI you can measure: quality evals, a learned recovery model, hybrid retrieval, AI-ops
- Lyra now proves its AI is good, not just safe: a labelled question-and-answer test set scores every answer for whether its numbers are grounded, its citations are real, it covers the facts it should, and it refuses questions it should not answer - so a fabricated or advice-y answer turns the build red.
- A learned, calibrated recovery-probability model sits alongside the deterministic score: trained and backtested out-of-sample (it beats a naive baseline), it attaches a research-only probability band to a setup. It informs, it never decides - the engine still owns the action, and the model card is public.
- Smarter in-app doc answers: retrieval now blends exact keywords with a fuzzy character-level match (so "deploying" finds the deploy doc), measured with real retrieval metrics and gated so it can never get worse - all still offline, no embeddings, no new services.
- Stronger safety: new guards block secrets (API keys, tokens, connection strings) and flag personal data in any answer, plus an adversarial red-team test set (jailbreaks, injection, exfiltration) - and a structural check that no AI screen can reach the model without passing the guards.
- New AI Ops dashboard (/ai-ops) surfaces how the AI layer is behaving: throughput, latency, refusal and guard-block rates, circuit-breaker state, and the model card - plus a public AI System Card (/api/ai/system-card) that reads live from the code.
v0.9.12026-07-16
Review hardening: honest copy, fresh fill prices, smarter doc answers
- The BYOK copy now tells the exact truth: your AI key is held by your browser and sent only with your own requests to your own deployment - never stored server-side.
- Logged trade fills are priced fresh: the trade-confirm path bypasses the 60s quote cache, so a recorded fill price can never come from a cached preview.
- In-app doc answers got sharper and safer: natural questions ("what is lyra?", "how much does this cost?", "how do I set this up?") now find the right doc, while market and advice questions can never pull doc examples into the prompt.
- /api/health now verifies the Redis cache with a real PING (reports upstash-unreachable when it is down), and cache writes are awaited so serverless deploys cannot silently drop them.
- Goal-card accessibility: only the visible face is read by screen readers, keyboard focus survives the Setup Companion refresh, all animation respects reduced-motion - and cost badges no longer wrap broken on phones.
v0.9.02026-07-16
Continuous intelligence + a robust agent harness
- New Signal Intelligence board on Small Caps: it scans every independent signal across the universe - government backing, big-tech capital, smart money, supply-chain bottlenecks and turning momentum - and ranks the names where several converge at once. Convergence of independent signals is the highest-conviction "look here," and it is scored deterministically, never guessed.
- The government-backing signal is now LIVE, not static: Lyra pulls real US federal contract awards for the small-cap watchlist from USAspending.gov (a free, keyless source), caches them, and shows exactly whether each award is live or an illustrative sample - so official spend, an early pre-consensus read, is continuously fetched rather than hand-curated.
- The AI co-pilot can now reason over that convergence intelligence as a first-class, read-only tool - it finds and cites the most effective data points instead of narrating a single fixed snapshot, while still only explaining what the engine computed.
- A hardened safety layer around every AI answer: one unified guardrails verdict (blocks trade advice, prompt-injection echoes, and ungrounded numbers; flags predictive overclaims) is enforced at the answer boundary, backed by an eval-gate - a safety test set that turns the build red if any guard is ever weakened.
- Under the hood, the AI gateway is more resilient: transient provider failures are retried with backoff, and a concurrency limiter plus spend budget stop a burst of requests from running away. Plus a new roadmap pitch - your private Digital Trading Twin (docs/strategy + README).
v0.8.02026-07-16
Setup Companion, agent onboarding, Redis cache + a knowledge layer
- Running /setup now opens a live Setup Companion in your browser - a premium spec of the whole stack (real logos, honest cost badges) plus a stage-by-stage progress board your agent updates as it builds. Also served in-app at /setup-companion.html.
- Six animated "ultimate goal" cards - punchy on the front, tap to flip for the detail - on the companion AND the landing page, alongside the full stack grid with per-technology costs.
- Agents get a front door: AGENT-ONBOARDING.md (mission, setup contract, security ground rules, verification gates) plus ONBOARDING.md, the ledger of every onboarding asset and experience.
- The AI co-pilot now answers questions about Lyra itself with citable sources: a deterministic knowledge layer compiles the reference docs at build time and retrieves the relevant sections into chat - no embeddings, no new services, works in demo mode.
- Optional Redis caching (Upstash REST) for market quotes and hot reads - a pure optimisation with an in-process fallback, so nothing new is ever required. /api/health reports the active cache backend.
- Deploying is agent-friendly: walkthrough 04 and /setup include the full Vercel CLI path (login, link, env, deploy) so an agent can put Lyra online end to end.
v0.7.02026-07-16
Replicate it: walkthroughs, /setup agent, Docker/Coolify, full costs
- Share the repo link and anyone can run their own Lyra: six adversarially fact-checked walkthroughs (docs/walkthroughs/) cover what it is, running it in 5 minutes, going live on your own Supabase, deploying, reading the score, and getting alerts on your phone.
- Claude Code users can skip the manual path entirely: run /setup in a fresh clone and the bundled agent playbook (.claude/commands/setup.md) sets everything up end to end, with a verification gate at every stage and costs shown before anything paid.
- Self-hosting is now first-class: a production Dockerfile (Coolify/Docker), a public /api/health probe that reports the running version and mode, and a Coolify deploy runbook (docs/runbooks/coolify-deploy.md).
- COSTS.md itemises every service in the stack with prices verified on provider pages - demo is $0, a fully live always-on setup runs on free tiers, self-hosting is about US$13/mo.
- Setup truth fixes: supabase/migrations/ is documented as the canonical schema (with the one sql/ reconciliation script that follows it), and the README quick start now matches the real dev port.
v0.6.02026-06-27
TradingView Copilot + Pine strategy export
- Export any name as a TradingView strategy - click "Pine" on the chart toolbar to copy a backtestable Pine v5 strategy that reproduces Lyra's exact oversold-recovery score. Paste it into TradingView and backtest the same logic that surfaced the setup.
- The generated Pine is a faithful, drift-guarded mirror of the scanner engine (signal_engine.py): same RSI reset band, MACD-histogram recovery, 60-period-low distance, trend and volume rules, capped at 100.
- New TradingView Copilot runbook (docs/tradingview-copilot.md): drive your TradingView Desktop from Claude over the Chrome DevTools Protocol - read the live chart, switch symbol/timeframe, inject + backtest the Lyra strategy, run replay, and screenshot back into a Finding. All local, research only.
v0.5.12026-06-20
Brand + UI polish, Find/Graph fixes
- Fixed Find and Graph: push-test and system notifications were showing up as "findings" (and left the graph blank). Those are now filtered out, so Find shows real setups (or the demo set until the scanner surfaces yours) and the graph is never empty.
- Find and Graph moved down the navigation - they were over-promoted to the #2/#3 mobile slots; your daily surfaces (Portfolio, Trades, Watchlist) now come first.
- New Lyra logo - the app-icon arrow (a white up-right arrow on the gradient square) is now the in-app logo, the loading screen and the browser-tab icon, matching your home-screen and email icon.
- The Getting started checklist is now collapsible (and renamed from "Get started").
- The app version and its release date are now visible on the landing page and in the account menu, both linking to this changelog.
v0.5.02026-06-20
Dogfooding gap-closers
- Investigation Graph at /graph now builds from your live findings (demo map until the scanner surfaces setups).
- Findings now have promote / dismiss lifecycle controls - move a finding to Watchlist, Deep research, Paper-bot queue or Review risk, or dismiss it as noise.
- Your account currency is captured in onboarding (defaults AUD), so AUD and .AX trades log immediately instead of being rejected.
- A two-week "Has Lyra helped you trade?" rating prompt, so feedback shapes what gets built next.
- /findings and /graph now render your per-user data at request time, not a build-time snapshot.
v0.4.02026-06-18
Currency-safe trades + the Investigation System
- Currency-aware trade logging: a cross-currency trade is rejected with a clear message instead of silently corrupting your cash pool and average cost.
- The Investigation System at /findings - every surfaced setup is an Opportunity Finding you can peel back: finding -> evidence -> source record -> entity -> connected pattern, with "what it does not prove" on every piece of evidence.
- Investigation Graph relationship map at /graph - shared bottlenecks, themes and buyers across findings on one map.
- Live findings projected from your own alerts.
- Generated views in the drawer - the AI composes the layout, every number stays owned by the deterministic engine.
v0.3.02026-06-18
Dogfooding-readiness pass
- Notifications actually deliver now - web push / Telegram / WhatsApp, with quiet hours evaluated in your timezone.
- Persistent Trade Log with per-row undo at /trades.
- Conversational buy logging previews the live quote - shares, fill price, cash left - before you confirm.
- Jargon defined in context across the analytical surfaces, linked into the academy.
- The strategy was renamed momentum -> oversold-recovery end to end, so the words match the math.
v0.2.02026-06-12
Thematic intelligence + research platform
- World Radar - 10 secular themes, each with a first-principles supply-chain map and ranked companies.
- Small-cap discovery engine, Investor Radar (tracked 13F moves), and a deterministic signal-events engine.
- Paper trading with realistic fees + slippage, and Bot Readiness - the pre-trade risk engine that refuses unsafe orders.
- Independent Bollinger / RSI / MACD chart studies, plus security + messaging foundations.
v0.1.02026-06-08
Initial release
- Deterministic 0-100 oversold-recovery score from RSI, MACD, price location, trend and volume, on an hourly cadence.
- Command centre, Signal Radar and Live Wire.
- Portfolio, Watchlist and a Comparison Lab.
- Research surfaces, a beginner-to-advanced Learn path, and three run modes (demo / live / AI).