**BLOCK** - **P1 — Crypto/FX provider replays can still create false wealth snapshots.** `src/jarvis_finance/services/asset_price_refresh.py:226-240` maps `PriceRefreshResult.updated_count` directly to the economic update count for crypto; `src/jarvis_finance/market/providers.py:297-303` increments it for every fresh provider response after inserting another retrieval row, even when price and provider timestamp are unchanged. FX similarly increments on every `status == "ok"` at `asset_price_refresh.py:273-295`. These counts feed `total_updated` and snapshot creation at `asset_price_refresh.py:363-388`. The new `economic_updated` distinction only protects equities. Add economic identity/hash no-op detection for crypto and FX and use only those economic-change counts for wealth snapshots. - **P1 — Jobs report `complete` while known stale assets remain.** Source failure and final job status depend only on `failed_count` at `src/jarvis_finance/services/asset_price_refresh.py:348-355,386-414`; `stale_remaining_count` does not affect either. A deterministic probe with one stale candidate, `stale_remaining_count=1`, and no provider error returned source status `complete` and job status `complete`, while the payload simultaneously reported `stale_assets: 1` and advised retrying. Treat unresolved stale/missing candidates as at least partial, and add this counterexample to the job tests. - **P1 — Canonical observation identity and persistence do not satisfy the stated economic-observation contract.** `src/jarvis_finance/market_data/prices.py:518-525` includes `provider_symbol` and `price_type` in source identity, so a symbol/mapping correction at the same provider/instrument/precise timestamp starts a separate lineage rather than versioning its predecessor. Additionally, `quality_status` and derived `source_reference` are hashed as economic payload at `prices.py:468-480`, and observation storage is unconditional at `prices.py:595-612`; the existing refresh path calls it for missing/stale/error responses at `prices.py:705-718`, producing “economic” observations with an empty close. Define identity from the required stable source coordinates, restrict the economic hash to actual quote economics plus stable provenance, and do not create canonical economic observations for failed/non-price responses. - **P1 — Observation idempotency is not concurrency-safe.** The duplicate/predecessor reads and version calculation at `src/jarvis_finance/market_data/prices.py:526-540` are followed by a plain insert at `prices.py:541-555`. Concurrent identical requests can both observe no row and one then fails a uniqueness constraint instead of becoming a no-op; concurrent corrections can both choose the same next version and lose one correction. Make insertion/version allocation atomic—e.g. serialize by source identity in a write transaction and retry/re-read on the unique constraints—and add concurrent duplicate and concurrent-correction tests. - **P1 — A GET route still invokes a provider and writes.** `src/jarvis_finance/api/routers/market.py:91-93` exposes `GET /equity/{instrument_id}/candles?refresh=true`; `src/jarvis_finance/services/market_service.py:565-582` calls yfinance, upserts candles, and commits. This directly violates “GET no provider/write.” Remove refresh behavior from GET and expose any explicit refresh through a guarded POST. - **P1 — Wealth UI presents derived calendar/component data as truthful quote metrics.** `frontend/src/components/wealth/WealthCockpitPanel.vue:34-36,109` labels `modelled.current.date` as **“Verwendeter Kursstichtag”**, although the backend advances model points by calendar day and carries independently dated components (`src/jarvis_finance/services/modelled_wealth.py:642-665`); it can therefore display today as the quote cutoff while prices are older. The same computed value counts five aggregate components—not asset valuations—and can double-count unavailable components plus `unknown_accounts`. Expose actual valuation/quote cutoff and quality counts from the backend, or relabel the UI honestly as model date and component counts.