## Review outcome: **Not release-ready** ### P0 1. **Unconfirmed crypto transactions can produce a “complete” confirmed valuation** - `src/jarvis_finance/services/performance_activation.py:153-158` - `src/jarvis_finance/services/daily_valuations.py:102-109, 233-270` - Both activation evidence and quantity reconstruction read every `crypto_transactions` row without filtering `confirmation_status='confirmed'`. A pending/imported transaction can therefore satisfy activation evidence, alter holdings, and be materialized as a complete account valuation. - **Remediation:** Filter canonical transaction inputs to confirmed rows in both preview and valuation paths. Add tests proving pending/rejected rows neither qualify activation nor affect quantities. 2. **Transaction-mode crypto holdings are truncated at `coverage_from`** - `src/jarvis_finance/services/performance_activation.py:153-158` - `src/jarvis_finance/services/daily_valuations.py:82-109` - Activation permits `first_activity <= period_from`, but valuation starts from zero and replays only transactions on/after `coverage_from`. Holdings acquired earlier disappear. If later transactions exist, the resulting incomplete quantity can still receive `quality_status='complete'`. - **Remediation:** Replay the complete confirmed transaction history from an evidenced inception anchor through `as_of`; alternatively require `period_from` to equal first activity and prove a zero opening balance. Bind that anchor/history to the preview fingerprint. ### P1 3. **Canonical-day handling remains incomplete across accounts** - `src/jarvis_finance/services/portfolio_performance.py:462-466, 563-570` - `_load_valuations()` selects one version per scope/day, but preserves the original timestamp. `_aggregate_account_valuations()` then groups by the exact `valuation_at`. Two accounts valued on the same calendar day at different times are treated as separate incomplete portfolio points. - **Remediation:** Normalize account valuation keys to `valuation_at[:10]` throughout daily aggregation, while retaining the original timestamp only as provenance. Add a multi-account, same-day/different-time regression test. 4. **Backfill can commit financial writes without a top-level confirmation audit** - `src/jarvis_finance/services/performance_activation.py:454-505` - Child valuation runners commit each day independently: - `src/jarvis_finance/services/daily_valuations.py:309` - `src/jarvis_finance/services/portfolio_analytics.py:777` - The confirmation audit is written only after the entire loop. An exception on a later day leaves earlier valuation writes committed with no `performance_backfill_confirmed` audit. Retrying the original preview may then fail as stale because completeness changed. - **Remediation:** Durably reserve the confirmation with fingerprint and `running` state before child writes, record each child outcome, and finalize as complete/partial/failed. Retries must resume the same confirmation safely. 5. **Confirmation IDs are not payload-bound or concurrency-safe** - Activation: `src/jarvis_finance/services/performance_activation.py:194-201` - Backfill: `src/jarvis_finance/services/performance_activation.py:429-442` - Reusing a confirmation ID with a different source, period, or fingerprint silently returns the earlier audit as idempotent. Concurrent requests can also both pass the initial lookup. - **Remediation:** Compare the stored audit fingerprint and canonical request payload on replay; return 409 on mismatch. Serialize lookup/reservation with an immediate transaction or equivalent durable unique reservation. ### P2 6. **A partial provider run hides the previous confirmed date** - `src/jarvis_finance/services/performance_activation.py:37-50` - `last_confirmed_date` is populated only when the latest run itself is complete. A newer partial/provider-failure run changes it to `null`, despite the prior confirmed valuation remaining intact. - **Remediation:** Query latest run status and latest complete run date independently. ## Verified - Schema remains **49** (`MIGRATION_VERSION = 49`). - No second scheduler/engine was introduced; the existing systemd → CLI path remains. - Checked systemd opt-in guard: committed service defaults `JARVIS_FINANCE_DAILY_VALUATION_ENABLED=0`. - Focused backend tests: **37 passed**. - Focused Ruff: **passed**. - Full verification after adding `.venv/bin` to `PATH`: - Python: **913 passed** - Frontend: **222 passed** - Typecheck/build/git-safety: **passed** - `git diff --check`: **passed**. - **Files modified by reviewer:** none. - Initial `make PYTHON=.venv/bin/python verify` could not locate bare `pytest`; rerunning with `.venv/bin` on `PATH` passed completely.