# Sprint 12 — TrueWealth source gate

Status: **passed on 2026-07-27; mapping confirmed; release verification in progress**

## Verified source

The original customer export was retrieved read-only from the confirmed Drive location and archived outside Git with owner-only permissions. The protected release evidence records its exact filename, byte length and SHA-256; none of those customer-source identifiers are committed to the repository.

The source is an official TrueWealth tax statement with:

- portfolio label `Freie Anlagen`;
- statement and period end date 2026-07-27;
- seven security positions;
- four currency cash rows;
- a provider-reported CHF portfolio total;
- Swiss number formatting and a selectable text layer.

The production parser was exercised against this immutable source before release. It parsed all seven positions and all four cash rows and reconciled their components to the provider-reported total within the document's whole-franc rounding tolerance.

## Confirmed reconciliation

The portfolio is mapped to the already-existing managed TrueWealth account selected by the user's confirmed reconciliation. No production account identifier is stored in Git or exposed in the user interface. Runtime resolution is deterministic:

1. use the persisted `Freie Anlagen` mapping after the first confirmed import;
2. otherwise use an explicit runtime-only override if configured;
3. otherwise require exactly one active TrueWealth account with an existing historical account valuation.

Ambiguity fails closed.

The two other existing records remain separate:

- the historical review account remains an audit-only review record;
- the empty legacy placeholder remains unchanged.

No account is deleted or silently merged.

## Historical manual valuation

The pre-existing manual valuation remains physically present and audit-visible. A confirmed official import adds a newer account valuation; it does not overwrite the historical row. Current-value selection is date-aware and gives an official import priority over a manual value on the same date, so the historical value no longer determines the current total after the confirmed source import.

## Manual values between official imports

A new manual total is stored as a separate `truewealth_manual_provisional` history row. It has Preview → Confirm, a valuation timestamp, optional note, audit trail and reversible active status. It never changes imported positions, quantities, currencies or prices.

Selection rules:

- newer valuation dates win;
- on the same date an official import wins;
- an older late-arriving official source cannot displace a newer manual value;
- a same-date or newer official source automatically supersedes the provisional value as current;
- disabled manual rows remain in history and are not hard-deleted.

When a manual total is current, the UI separately labels the total timestamp and the date of the last official position details. Allocation/performance usability is false, and provisional totals are excluded from generic performance-input selection.

## Source and integrity controls

- PDF-only, bounded input with magic-byte validation.
- Parser identity and version persisted.
- Source SHA-256 and immutable archive reference persisted.
- Digest-level idempotency for an identical source.
- A different source for an already-imported snapshot date is a blocking conflict.
- Preview is side-effect free.
- Confirm uses an atomic database transaction; a newly created archive is removed if the database transaction rolls back.
- Immutable source, snapshot, position and cash tables reject update/delete.
- TrueWealth official/manual account-value rows reject hard deletion; only the manual active state can change.
- GET endpoints are side-effect free.
- Git fixtures are synthetic and anonymized.

## Release gate

Production remains unchanged until local verification, review, PR, green CI and merge are complete. Before deployment the production database must be backed up, restore-tested, integrity-checked and compared with a business digest. The real source is then previewed, confirmed only if reconciliation remains green, and re-submitted to prove idempotency before responsive UAT.
