# FinanceManager release consolidation & UAT pattern

Use this reference after the user accepts a FinanceManager feature/development sprint and asks to consolidate the branch into a stable release basis. This is a **release/UAT workflow**, not a feature sprint.

## Scope guard

- Do not implement new features, new import sources, analytics, reports, OCR, provider integrations, or broad cleanups.
- Do not commit runtime DBs, raw financial files, real CSV/XLS/PDF/DOCX data, secrets, generated reports, `frontend/dist`, `frontend/node_modules`, `.pytest_cache`, `.vite`, or `__pycache__`.
- Do not report real amounts/rows in chat or docs.
- Do not perform productive mass confirms or write actions without explicit current-turn approval.

## Branch and remote preflight

1. Verify current branch and clean working tree.
2. Fetch/compare `main`, `origin/main`, and the accepted feature branch.
3. Check whether known predecessor branches are contained, e.g. with `git merge-base --is-ancestor <branch> <feature>`.
4. Count commits ahead/behind and dry-run conflict risk:
   - `git rev-list --count main..feature`
   - `git merge-tree $(git merge-base main feature) main feature` or a temporary/no-commit merge if needed.
5. If GitHub API/`gh` PR lookup is unavailable, say so; do not block a user-authorized direct merge if branch status and remote hashes are otherwise verified.

## Pre-merge verification on the feature branch

Run the full gate before merge:

```bash
source ~/jarvis_runtime/finance-system/venv/bin/activate
unset JARVIS_FINANCE_DB_PATH
python -m compileall -q src tests
pytest -q
cd frontend
if [ ! -d node_modules ]; then npm ci; fi
npm test -- --run
npm run build
cd ..
```

Then perform scoped safety checks:

- Source secret scan; treat known synthetic Git-safety fixtures as false positives only after confirming they are test fixtures.
- Frontend build secret scan before deleting `frontend/dist`.
- Remove generated artifacts before Git-safety: `frontend/dist`, `frontend/node_modules` if needed for scanner cleanliness, `.pytest_cache`, `.vite`, `frontend/node_modules/.vite`, and all `__pycache__`.
- `python -m jarvis_finance.cli.main git-safety-scan .`
- `git diff --check`

## Browser/Tailscale sanity

Verify the browser-visible Tailscale frontend origin, not just localhost. Minimum routes for v0.3-style FinanceManager releases:

- `/`
- `/crypto`
- `/portfolio`
- `/equity`
- `/positions/add`
- `/wallets`
- `/planning/budget`
- `/planning/budget/expenses/review`
- `/planning/budget/expenses/actual`
- `/planning/budget/income/actual`
- `/planning/budget/analysis/budget-vs-actual`
- `/planning/budget/rules`

Also check backend health and frontend proxy such as `/api/runtime/status` through the frontend origin. If stale listeners block restart, kill the processes bound to ports 8000/5173 and restart from the current checkout.

## Runtime backup and restore test

Before merge/tag:

1. Create a runtime DB backup under `~/jarvis_runtime/finance-system/backups/` or another external runtime path.
2. Write/verify SHA256 checksum.
3. Copy the backup to a separate test path, e.g. `~/jarvis_runtime/finance-system/restore-tests/<timestamp>/finance.sqlite3`.
4. Open the copied DB with SQLite; verify schema version and central tables are readable.
5. Confirm the productive runtime DB was not overwritten or mutated by the restore test.
6. Report only statuses, paths, checksum OK/failed, schema version, and aggregate table-read success — no real values.

## Merge, tag, push

If all gates are green:

```bash
git checkout main
git pull origin main
```

Choose the narrowest merge path from containment results:

- If the latest accepted feature branch already contains predecessor branches, merge only that final branch into `main` with `--no-ff`.
- If not, merge predecessor branches first in dependency order, verifying after each merge when risk is non-trivial.

```bash
git merge --no-ff <final-feature-branch> -m "Merge release <version> <scope>"
```

If conflicts occur, list them and stop unless the resolution is obviously mechanical.

After merge:

1. Run at least critical/full verification again on `main`.
2. Update/commit release docs or UAT matrix on `main` before tagging.
3. Run `git diff --check` after doc edits; Markdown two-space line breaks will be flagged as trailing whitespace in this repo, so fix/amend before tag.
4. Run Git-safety after deleting generated artifacts (`frontend/dist`, `frontend/node_modules`, `.pytest_cache`, `.vite`, `__pycache__`). If `npm install` was used to restart the dashboard, remove `frontend/node_modules` again for the final Git-safety gate and reinstall only after push if the dev server needs it.
5. Tag only after final `main` is green, Git-safety is green, backup exists, browser sanity passes, and release docs are committed.

```bash
git tag -a v0.3.1 -m "Finance MVP budget import and analytics release"
git push origin main
git push origin v0.3.1
```

If normal remote access requires the FinanceManager GitHub token from runtime secrets, use temporary `GIT_ASKPASS` or a temporary authenticated URL for the one command/verification only. Never print the token and never persist a token-bearing remote URL.

Verify remote hashes for both the branch and annotated tag:

- `git rev-parse HEAD`
- `git ls-remote <remote> refs/heads/main`
- `git rev-parse <tag>` — local annotated tag object
- `git rev-parse <tag>^{}` — local commit target
- `git ls-remote <remote> refs/tags/<tag>` — remote annotated tag object
- `git ls-remote <remote> refs/tags/<tag>^{}` — remote commit target

Update local `origin/main` if necessary after authenticated push so `git status` shows synced.

## UAT matrix and small UAT

Create `docs/uat/uat-finance-mvp-v0.3.md` or the release-appropriate successor. Include checklist rows for Core, Crypto, Aktien/ETF, Cash, Budget, Reports. For each point include: test status, expected result, passed yes/no, note, and no real values.

For the small UAT:

- Prefer a separate test-runtime copy for write flows.
- Test Budget candidate confirm, ignore/reopen, Merchant/Alias apply, Rule test/apply, Split, and Cash correction on the copy.
- Verify audit IDs exist for writes.
- Verify rule apply did not create productive transactions.
- Verify productive runtime size/mtime or another non-invasive fingerprint did not change.
- If a real productive UAT is requested, require explicit current-turn approval for each write and never do mass confirm.

## Status document update

Update the repo status/roadmap document with:

- release branch
- source branch
- merge commit
- release tag
- date
- UAT result
- known open points
- next recommended sprint

Keep the next recommendation conservative after a release: usually controlled production UAT before Reports/Analytics/Fixkosten/import expansion.

## Pitfalls from v0.3/v0.3.1 consolidations

- If a later accepted branch contains an earlier accepted branch, do not merge both blindly. Prove containment (`git merge-base --is-ancestor`) and merge only the final branch unless the user explicitly wants separate merge commits.
- `git diff --check` treats Markdown two-space line breaks as trailing whitespace; prefer normal line breaks in committed docs or run/fix before commit. If a doc commit accidentally lands with whitespace warnings, fix and amend before push/tag.
- `npm install` for browser/UAT can repopulate `frontend/node_modules` after a clean Git-safety pass. Remove it again before final Git-safety/tag/push, then reinstall after release only if the running dev server needs dependencies.
- For annotated tags, verify both the tag object hash and the peeled commit target hash locally and remotely. Reporting only `refs/tags/<tag>^{}` misses whether the annotated tag object itself pushed correctly.
- `scripts/start_vue_dashboard.sh --kill-existing` relies on PID files; if a stale uvicorn/node process was started another way, clear port listeners explicitly before restart.
- A harmless shell heredoc terminator typo can appear after a successful push/merge script; verify actual git/hash outcomes rather than treating the trailing shell error as proof the git operation failed.
- Cash confirmation requests may require the preview ID; Budget candidate confirm needs a `budget_accounts.budget_account_id`, not a generic portfolio `accounts.account_id`.
