v1.0.0
[1.0.0] - 2026-06-29
The first tagged release. A hardening milestone: a coherent, honest,
installable product where every advertised feature works or is explicitly
labelled degraded. All release buckets are complete — integrity (A), de-India
defaults (B), robustness (C), the single-source version contract (D), and
ship-with docs (E). See docs/wiki/Roadmap.md → Release plan for the full
gate and docs/wiki/Limitations.md for the honest keys/limitations map.
Added
- Private second brain (RAG) — flagship: ask-anything research grounded only
in your own writing (journal, theses, position/transaction notes), with inline
citations; provider-agnostic embeddings (Ollamanomic-embed-textdefault,
sentence-transformersfallback) and a dialect-aware vector store (pgvector on
Postgres, numpy cosine on SQLite).POST /api/brain/ask|reindex,GET /api/brain/status+ a Second Brain page. - Generic notes capture — one-step note capture anywhere (stock/crypto detail,
watchlist rows, news, Portfolio Lab, Notes hub) feeding the second brain. - Crypto fundamentals — tokenomics + on-chain TVL/fees (CoinGecko + keyless
DefiLlama);GET /api/v1/crypto/fundamentals/{symbol}. - EUR display currency — cross-rates-driven, instrument-currency-aware display
engine (USD/EUR/INR) with correct per-currency symbol/locale/compaction. - Dividend calendar (real data) — market-agnostic calendar/history/aristocrats/
income via the corporate-actions service (Yahoo chartevents=div+ FMP), with
labelled next-ex-date projections for regular distributors. - Scheduled reports + PDF generation backend; provider-agnostic LLM layer
(OpenAI-compatible, Ollama default); economic data terminal (calendar +
macro dashboard).
Changed
- Postgres-first persistence (SQLite opt-in); pgvector Postgres image
(pgvector/pgvector:0.8.3-pg16-trixie, no migration). - De-India data layer — unified
instrument_master(US/EU/crypto sources),
accent-insensitive search, EU Yahoo-suffix routing; market-overview/ticker-tape
show US indices. NSE/BSE F&O stays supported. - External-client robustness (1.0 bucket C). A shared retry-with-jitter +
per-client circuit breaker (backend/shared/http_resilience.py) backs off on
429/5xx instead of hammering a depleted provider, and response caching now
covers Finnhub and Yahoo as well as FMP (the shared multi-tier cache
incl. the persistent SQLite L3) to stop free-tier quota burn; 429/5xx never
cached. Finnhub no longer force-appends.NSto bare symbols.
Fixed
- Silent-mock integrity sweep (1.0 bucket A, part 1). Audited the backend for
code that fabricated plausible market data when a real source was unavailable
and presented it as live. Established a standarddegraded: {reason, source}
marker (backend/shared/degraded.py) + a reusableDegradedBannerso the UI
always flags non-live data. Fixed the 7 critical sites:- Market status (
/reports/market-status): removed the hardcoded
index/commodity values +randomjitter (NIFTY/SP500/gold/silver/crude…);
missing quotes now stay null and the response is flagged degraded. - Heatmap treemap: stopped seeding synthetic price/change/volume per tile;
tiles with no live quote render neutral and the response is flagged degraded. - Tape (
/tape/*): removed synthetic bars and invented buy/sell order
flow; only real trade-feed data is shown, otherwise empty + degraded. - Historical OHLCV (
historical_data_service): removed the synthetic
random-walk fallback so backtests/charts never run on fabricated history. - Macro indicators: the no-
FRED_API_KEYfallback is now flagged degraded
(previously only the calendar carried asampleflag, the macro dash didn't). - Yield curve / 2s10s (
fixed_income): no-key/error paths return empty +
degraded instead of a hardcoded curve. - Bonds (
/bonds/*): replaced the hardcoded India-only bond universe,
spreads, and ratings with empty + degraded (no live source wired yet).
- Market status (
- Silent-mock integrity sweep (1.0 bucket A, part 2). Extended the audit to
the high-severity sites and a few the first pass missed:- Hotlists (
/api/hotlists): the page 401'd because it used a rawfetch()
that bypassed the bearer-token client — now routed through the authedapi
client. The endpoint itself was 100% fabricated (hardcoded prices + seeded
sparklines) → now empty + degraded; default market de-India'd toUS. - Insider (
/api/insider/*): removed the auto-seeded fabricated India
insider universe (source="SEEDED"); serves only ingested trades, else
empty + degraded. Deleted the dead, mock-onlyinsider_monitor.py. - ETF (
/api/etf/*): removed the hardcoded screener (incl. NIFTYBEES),
the AAPL/MSFT holdings placeholder, and therandomfund-flows; empty +
degraded instead. ETF FE components routed through the authedapiclient
(same latent 401 as hotlists). - Shareholding: the no-source fallback no longer fabricates a "100%
public" cap table — returns zeros + degraded. - Sector rotation (RRG): removed the hashed-seed synthetic price series;
empty + degraded when the price source is unavailable. - Charts (
/chart/{ticker}+ indicators): removed the synthetic
random-walk fallback; empty + degraded instead of a fake series. - Crypto correlation: drops assets without real return history rather than
back-filling a synthetic sine/cosine series; flags degraded when partial.
- Hotlists (
- Silent-mock integrity sweep (1.0 bucket A, part 3) — real Binance crypto
microstructure + derivatives. Replaced the last synthesized-crypto sites with
real Binance public-REST data (newbackend/core/binance_client.py+
backend/services/crypto_derivatives_service.py):- Crypto heatmap depth (
/v1/crypto/heatmap):depth_bid/ask_notional+
depth_imbalanceare now the real best bid/ask from the spot order book
(bookTicker, one call, cached), notvolume*price. Symbols Binance doesn't
list read as empty depth; no order-book coverage at all flags degraded. - Crypto derivatives (
/v1/crypto/derivatives):funding_rate_8his the
real last funding rate (futurespremiumIndex) andopen_interest_usdis
real (openInterest× mark price), no longer derived fromchange_24h.
24h liquidations have no Binance REST endpoint, so they are read only from the
liveforceOrderWebSocket stream (BinanceDerivativesState); until that
runner is wired they read 0 and the response is flaggedno_live_source
instead of being fabricated.DegradedBannerwired into both crypto tabs.
- Crypto heatmap depth (
- Silent-mock integrity sweep (1.0 bucket A, part 4) — real order-book depth.
The/api/depth/{symbol}REST route and the/ws/depthstream returned a
fully synthetic order book for every market — prices, sizes, spread and
imbalance were all derived from asha256(symbol:market:levels)hash (a site
the earlier audit missed). Both now serve real depth viaunified_fetcher. fetch_depth:- Crypto → real Binance spot order book (
/api/v3/depth, new
BinanceClient.get_order_book); the FE panel detects crypto symbols so a
crypto detail page no longer requests depth as an equity market. - India → already had real Kite/NSE depth in
fetch_depth, but the route
bypassed it; it's now wired through (real). - US / EU equity → no free Level-2 source, so the book is empty +
degraded(no_live_source) instead of fabricated;OrderBookPanelshows
the degraded banner. Real US/EU L2 is a roadmap item (Interactive Brokers). - Depth quantities widened to floats (crypto books are fractional); the
syntheticorderbook_servicegenerator was deleted.
- Crypto → real Binance spot order book (
- De-India defaults (1.0 bucket B). Western-oriented defaults across the app
(India markets stay supported, just not the default): watchlist symbol search
passes the selected market through instead of forcing NSE; home/sidebar F&O
widgets default toSPY(sidebar label → "EQUITY ANALYTICS"); the portfolio
risk/attribution/lab benchmark defaults toS&P500(FE + backend route &
service defaults) and the default risk-free rate is0.04(was0.06).
NIFTY50/SENSEXremain selectable benchmark options. The F&O heatmap's
empty/error copy is now market-neutral ("F&O options data feed") instead of
hard-coding "Kite API key required". - Relative Strength stub de-India'd + degraded (1.0 bucket A). Every
/rs/*
endpoint (rankings, sector-rs, chart, new-highs) previously returned hardcoded
fake Indian rows (RELIANCE/TCS/INFY…) presented as live; they now return emptydegradedand the FE defaults the universe to S&P 500. The real RS
computation is a tracked post-1.0 follow-up.
- Scheduled-report 422 on missing email (1.0 bucket A).
POST /api/reports/scheduledrejected a blankemail; it now defaults to the
authenticated user's account email and only errors when there's genuinely no
address. - Index detail page (1.0 bucket A). Navigating to a market index (
^GSPC,
^NSEI, …) rendered the full equity tab set — Financials/Peers/Valuation/
Earnings/Shareholding — all blank, since an index has no issuer fundamentals.
An index now shows only the chart-backed overview + notes, with an explicit
"fundamentals don't apply to an index" note; price/chart/performance (which do
apply) are unchanged.isIndexSymbolalso keeps^NSEIfrom being treated as
an NSE equity. - FMP corporate-actions migrated to
/stable.corporate_actions.pywas
missed in the original/stablemigration and still used legacy/api/v3
path-segment URLs that 404'd (dividends/splits/IPO calendar). Now uses the
stable/dividends,/splits,/ipos-calendarshapes, skips crypto, and
caches 404s as empty to stop log noise. - Portfolio asset classification for crypto (1.0 bucket A). Crypto holdings
(BTC-USD, ETH-USD, …) previously fell through the market classifier to the
NASDAQ/US default — rendering a wrong US flag and collapsing into the "Unknown"
sector. The classifier is now crypto-aware (is_crypto_symbol/
crypto_quote_currencyinbackend/shared/market_classifier.py): crypto pairs
classify as a global, 24/7 asset (exchangeCRYPTO, 🌐 flag) whose display
currency is the pair's quote leg (so BTC-EUR reads EUR, …USDT → USD), and
portfolio sector allocation/attribution bucket them under "Crypto" instead of
"Unknown". EU ETPs were already classified correctly via the deterministic
foreign-suffix map. - Full FE↔backend API audit (
/v1/...path/shape mismatches; unmounted economics
router; shadowed watchlist-items route). - Ticker tape: real commodity values (GC=F/SI=F/CL=F were missing from the fetch
list → permanent mock), clickable duplicate scroll segment, correct index/Nikkei
link symbols. - Economic calendar always-empty (FE read
data.items; backend returns a bare
array) + de-India macro config and labelledsamplefallback. - Portfolio: correlation 500 on duplicate-ticker lots; display-currency on the
movement axis and holdings table;BTC-EURresolved as EUR (not USD) by reading
the crypto pair's quote leg.