# Annual budget and recurring-payment semantics release pattern

Use for vertical FinanceManager work that combines recurring-payment review, annual planning, forecast coverage, spreadsheet intake, schema evolution, and release gates.

## Architecture contract

- Extend the existing recurring, budget, category, ledger-effect, forecast, and Chart.js paths. Do not create a parallel recognition, forecast, or budget engine.
- Keep `Plan`, `Ist`, and `Forecast` distinct:
  - Plan = immutable, explicitly confirmed user target.
  - Ist = canonical financial effect of confirmed ledger rows.
  - Forecast = Ist through cutoff plus remaining confirmed plan positions.
- Reuse one canonical cadence calculation for weekly, monthly, quarterly, semiannual, yearly, one-time, irregular, planned, and undetermined positions.
- Calculate remaining forecast from due months when available; otherwise use the cadence-derived remaining fraction. Feed immutable annual-plan snapshots back into the existing category forecast matrix.

## Conservative recurring semantics

- One transaction never proves recurrence. A single observation is `undetermined` or `one_time`; a semantic yearly hint must remain an editable proposal.
- Unconfirmed periodicity must not produce a factual next due date.
- Candidate edits must include name, category, type, payment/range, cadence, and due months. Recalculate annual effect and monthly reserve immediately.
- Confirm must bind candidate ID, current data version, normalized user choices, action, and preview fingerprint. Persist the user choice—not the heuristic—and audit the financial projection.
- Preserve confirmed periodicity during later edits unless the user explicitly changes it. Validate the selected active category server-side and check optimistic-update row counts.
- Build one actionable warning card per contract and bundle missing-payment and amount-change reasons. Include observed facts, expected period, data-through date, forecast effect, and available actions; omit raw confidence and generic priority labels.

## Coverage and spreadsheet rules

- Known unresolved duplicates and partial card settlements are coverage gaps. Do not silently correct their values or expose a precise free/investable result while they remain open.
- Show only a grouped coverage hint on Today; keep individual contract notices on the recurring-payment surface.
- Treat XLS/XLSX as read-only input evidence, never calculation truth. Profile source cells directly, recompute annual/monthly controls, flag cadence conflicts, and expose Preview without enabling productive Confirm during analysis-only sprints.
- Regression controls should include quarterly payments not multiplied by 12, annual payments not multiplied by 12, source monthly-rest errors, and exact annual-total reconciliation.

## Additive migration pattern

When legacy CHECK constraints cannot represent the new cadence model, avoid a destructive table rebuild:

1. Add canonical semantic columns while retaining legacy compatibility columns.
2. Backfill active legacy rows conservatively.
3. Add immutable version and version-item snapshot tables with update/delete blocking triggers.
4. Keep operational tables for backward compatibility; make readers prefer the latest immutable snapshot.
5. Take one SQLite online backup, restore it to an isolated path, migrate only the restore through the same CLI/connection path used in production, run `PRAGMA foreign_keys=ON` and verify it is active before migration, then run `PRAGMA integrity_check`, `PRAGMA foreign_key_check`, and compare all persistent pre-existing table counts. A raw `sqlite3.connect()` rehearsal with foreign keys left at SQLite's default `OFF` is not production-equivalent and must not satisfy the release gate. Ignore only known migration shadow tables, never business tables.

## Canonical product documents and repository safety

- Save an authoritative product document in the existing canonical documentation tree and update existing baseline/status/runbook files instead of creating parallel roadmaps.
- If the repository blocks binary documents by default, add an exact-path exception in both `.gitignore` and the Git-safety scanner. Never allow an entire suffix or directory. Add a regression proving the canonical file is allowed while another file with the same suffix remains blocked.
- Keep runtime databases, spreadsheets, exports, backups, account details, and secrets outside Git.

## Release discipline

- During development run only tests for changed modules.
- Before PR: targeted regressions, one typecheck, one production build, Ruff on changed production surfaces, compile/diff/safety gates, and responsive read-only browser UAT.
- Perform one focused final-head review after all implementation changes. If it finds a defect, fix it and rerun only invalidated targeted gates before declaring a new final head.
- Use one PR and one final complete CI run for the final candidate. Merge only with P0/P1/P2 = 0, then deploy and verify the exact merge SHA via the canonical systemd worktree.
- Deployment permission never implies permission for financial confirms.