Eight in-flight commits targeting v0.41.0 (Track A money integrity,
Track B reconciliation tests, Track C API response typing across
auth/snowball/subscriptions/spending/bank-ledger, Track D 500
handler code:'INTERNAL_ERROR') are not yet pushed. Documenting them
in the manual so it stays current with the code that will land next.
Section updates:
- Header: keep package version 0.40.0, note v0.41.0 is the in-flight
target; 'Last Updated' 2026-07-05.
- Notable changes: 4 new bullets summarizing Track A/B/C/D.
- API client (7): list Track C response typing and Track D error shape
with cross-references to the sections where each is detailed.
- Domain types (7): expand to include User, SnowballProjection,
SnowballSettings, Subscription*, Spending*, BankLedger*, CategoryGroup,
CopyBudgetsResponse. Note single-consumer non-money casts left in
place as a deliberate Track C stop.
- Auth state (7): User moved to @/types, re-exported from useAuth.
- client/lib/ (7): add paymentActions.ts (createPaymentOrConfirm).
- Response conventions (5): add 'INTERNAL_ERROR' for 500s; note
409 DUPLICATE_SUSPECTED on POST /payments.
- Payments (5.5): Track A notes — transactional balance mutations,
409 allow_duplicate flag, 409 DUPLICATE_SUSPECTED response shape,
new tests/paymentsRoute.test.js and tests/reconciliation.test.js.
- Verification checklist (11): list 8 unpushed Track commits with
one-line summaries and 19-file diff stat (813+/415-).
- Added [migration] logging for each migration step (applying, completed, timing)
- Added [migration-error] logging with elapsed time on failures
- Added [migration] All migrations completed in Xms total timing
- Added lazy getLogAudit() for audit logging of migration failures (avoids circular dep)
- Changed DB path log to basename only (Hudson rec: reduce info disclosure)
- Version bumped to 0.23.0
- Reset default admin password when INIT_ADMIN_PASS is set on legacy DBs
- Added run() functions to all legacy migration entries (reconcileLegacyMigrations)
- Migrations that aren't present in legacy DB now actually execute
- v0.40 ownership migration assigns to first admin (not first user)
- Removed username from password reset log (info disclosure fix)
- must_change_password enforced after legacy password reset
Added ErrorBoundary component wrapping all routes in App.jsx.
Shows friendly fallback UI with Try Again and Reload buttons
instead of white screen crash. Logs component stack to console.
CRITICAL fix: Users upgrading from pre-migration-tracking databases
(now get 'invalid username/password' because schema_migrations table
doesn't exist. Added handleLegacyDatabase() and
reconcileLegacyMigrations() to detect and reconcile legacy DBs.
Security fixes:
- Path traversal: replaced sanitizePath() with ALLOWED_FILES allowlist
- Public /about bypass: added admin route guard in App.jsx
- Sensitive info exposure: expanded redactSensitiveContent() patterns
- Error message path leaks: generic error messages only
- Race condition: wrapped in db.transaction() in server.js
- Password validation: INIT_REGULAR_PASS min 8 chars with process.exit(1)
All verified by Bishop (build + runtime) and Private_Hudson (security).
- Added schema_migrations table for explicit version tracking (CRITICAL fix)
- Refactored runMigrations() to use versioned migration objects
- Added hasMigrationBeenApplied() and recordMigration() helpers
- Migrations now skip already-applied versions and log progress
- Updated FUTURE.md with migration system issues and criticality ratings
- Updated Engineering_Reference_Manual.md with migration system docs
- Added DEVELOPMENT_LOG.md for agent work tracking