Skip to content

1.4.1

Released: TBD

Compared to 1.4.0. Hotfix release — ledger audit chain verification.

Highlights

  • Audit integrity badge goes green for every tenant. ledgerAuditChainVerify was wrongly returning isValid: false for all non-UTC tenants (e.g. Panama) even though the data was intact. Fixed, and existing audit rows are repaired by migration.

Added

  • Nothing — bug-fix only.

Changed

  • The ledger audit row_hash formula now normalizes the timestamp to UTC and also covers sequence_number, entry_id, line_id and operation, so those fields are tamper-evident too. See Ledger audit hash timezone fix. The GraphQL surface is unchanged.

Fixed

  • Ledger audit chain verification on non-UTC tenants. record hashed the at timestamp in the tenant's local timezone while verify_chain recomputed it from the UTC value Postgres returns, so the hashes never matched and isValid was always false. Both paths now hash a UTC-normalized timestamp.

Migrations

Run in order on top of 1.4.0:

  • rehash_ledger_audit_logs — data-only; rebuilds prev_hash + row_hash for every existing ledger_audit_logs row in sequence_number order under the corrected formula. No schema change. Idempotent (re-running converges on the same canonical chain).

Apply with task migrate-dev against staging, or task migrate-prod once promoted. The migration must run before ledgerAuditChainVerify will report true for previously-written rows.

Frontend impact

None. No query, field, type, or enum changed. The "Audit integrity" badge described in the ledger audit trail doc simply starts returning isValid: true once the migration has run.

Versioning notes

  • PATCH bump: bug fix, no schema change, no frontend coordination required.
  • Bumped via uv run python scripts/bump_version.py 1.4.1 --changelog-stub.
  • Deploy order: apply migration rehash_ledger_audit_logs as part of the release; the code fix and the rehash are consistent in either order (new writes are already UTC-correct; the migration repairs historical rows).