v5.15.0 5 March 2026 Improvement

Milestone 2 — Financial Immutability and State Machine Enforcement

Kernel Milestone: 2 of 6 Previous: Milestone 1 — Tenant Isolation (5.14.0) Next: Milestone 3 — Monetary Domain Migration

System Impact
-------------
Ledger integrity:         strengthened
Ledger mutation:          structurally impossible after posting
Tenant isolation:         unchanged
Financial immutability:   enforced at database layer
State machine:            forward-only transitions enforced
Cascade deletion:         closed on core financial tables
Breaking changes:         none
Replay determinism:       preserved
Invariant Change
----------------
Axiom 2.1 (Posted Set) is now mechanically enforced at the database layer.

Why This Matters

An accounting system’s most fundamental guarantee is that posted financial records cannot change. Without this property the ledger is not a ledger. It is a mutable table that happens to hold numbers. Auditors, regulators, and the mathematics of double-entry bookkeeping all depend on the same invariant: once a transaction is posted, its lines are permanently fixed.

Before this release that guarantee existed only at the application layer. The application code respected immutability, but the database did not enforce it. A direct database connection, a future developer shortcut, or a defect in application logic could silently modify or delete posted transaction lines. No error would be raised. The ledger would simply drift.

This release moves that guarantee to the only layer that cannot be bypassed: the database itself.

There is also a deeper architectural reason this matters. If posted records never change, the entire financial history of a tenant can be reconstructed from first principles by replaying the ordered ledger event stream. Deterministic replayability is the prerequisite for the cryptographic ledger verification arriving in Milestone 6.


Financial Immutability

Posted Transaction Line Protection (Axiom 2.1 — The Posted Set)

The SpeyBooks kernel defines the Posted Set: once a transaction is posted, its lines are immutable at three independent enforcement layers:

  1. Database triggers (this release)
  2. Ledger append-only policy (Milestone 6)
  3. PostedTransaction TypeScript type with no mutation methods

These layers eliminate any single point of failure. Bypassing one does not bypass the others.

Two trigger functions now execute before any modification or deletion of a transaction line. If the parent transaction is posted or void, the operation is blocked before execution with a fatal exception.

  • Modification blocked Amounts, account assignments, directions, and all other values on a posted line are permanently fixed. Reversal is performed through the void mechanism, which generates a compensating entry rather than mutating history.

  • Deletion blocked Lines belonging to posted or voided transactions cannot be removed. Financial records are never destroyed. This is enforced by database exception, not application convention.

  • Orphan detection If a trigger fires on a line whose parent transaction cannot be found, an integrity exception is raised. In a correctly functioning system this state is impossible. Failures surface loudly rather than passing silently.

The Void Principle (Axiom 2.2 — No Cascade Destruction)

Financial records in SpeyBooks are never destroyed. This release eliminates the primary destruction pathway: cascade deletion on core financial tables.

Three foreign key constraints have been converted from CASCADE to RESTRICT, creating a three-sided enclosure around every posted transaction:

  1. Lines cannot be modified or deleted individually (Axiom 2.1 triggers)
  2. Parent transactions cannot be deleted while lines exist (Axiom 2.2 restrict)
  3. Lines cannot be cascade-destroyed through parent deletion (Axiom 2.2 restrict)

There is no remaining deletion path.


State Machine Enforcement

Forward-Only Transitions (Axiom 4.1 — The Arrow of Time)

Transactions follow a strict lifecycle: draft > posted > void

Before this release the database validated allowed status values but did not enforce transition direction. A posted transaction could be reverted to draft. A voided transaction could theoretically be reposted.

A new trigger enforces forward-only transitions at the database layer:

  • draft > posted — permitted, subject to existing zero-sum and line-count preconditions
  • posted > void — permitted
  • All other transitions — fatal exception before execution

Invoices receive equivalent protection. Once issued, an invoice cannot revert to draft.

This enforcement matters for deterministic replay. If transactions can be un-posted, the relationship between transaction state and ledger history becomes ambiguous. The hash chain in Milestone 6 becomes unverifiable.


Threat Closure

ThreatStatus BeforeStatus AfterEnforcement Layer
Posted transaction line modificationOpenClosed (Class M)Trigger guard (Axiom 2.1)
Posted transaction line deletionOpenClosed (Class M)Trigger guard (Axiom 2.1)
Cascade destruction of financial linesOpenClosed (Class M)FK RESTRICT (Axiom 2.2)
Illegal state transition (posted to draft)OpenClosed (Class M)State machine trigger (Axiom 4.1)
Invoice reversion to draftOpenClosed (Class M)State machine trigger
Orphaned line silent passOpenClosed (Class M)Integrity exception

Security Posture Change

Financial mutation pathways previously guarded only by application logic are now structurally closed at the database layer.

This release converts several operational guarantees into mechanically enforced invariants (Class O to Class M). Database enforcement ensures the ledger cannot be altered even if application logic fails or is bypassed.


Verification Record

Pre-flight:
  4/4 validation checks clean
  No invalid transaction or invoice states detected
  CASCADE constraints confirmed before migration

Migration:
  COMMIT
  All three invariant validation blocks passed

Post-commit:
  V1  immutability triggers present on transaction_lines
  V2  state machine triggers present on transactions and invoices
  V3  foreign keys converted to RESTRICT

Adversarial review:
  9.6 / 10 Production Gold

Amendment:
  Orphan detection guard added to both immutability triggers

Architectural Context

Kernel invariants are introduced in dependency order. Tenant isolation must precede immutability because immutability of cross-tenant data is not a useful property. Both must precede the monetary domain migration, which operates on a tenant-isolated and immutable schema.

After Milestone 2, three foundational invariants are enforced mechanically at the database layer:

  • Tenant isolation — row-level security enforced for all roles including table owners
  • Financial immutability — posted records cannot be modified or destroyed
  • State machine correctness — transactions and invoices move forward only through their lifecycle

These three properties together make deterministic ledger replay possible.


Operational Impact

Immutability: Posted transaction lines immutable at the database layer. Orphan detection prevents silent corruption.

State machine: Forward-only transaction lifecycle enforced. Invoice reversion to draft prevented.

Data safety: Cascade deletion removed from core financial tables. No deletion path exists for posted transactions by any route.

Deployment: Migration fully transactional. Invariant checks executed inside migration. Adversarial review applied before deployment.


Kernel Status

MilestoneDescriptionStatus
M1Tenant IsolationComplete
M2Financial Immutability and State MachinesComplete
M3Monetary Domain MigrationPending
M4ProvenancePending
M5Schema-Derived Categorical BoundaryPending
M6Append-Only Cryptographic LedgerPending

Files Changed

Backend:

  • api/db/migrations/069-milestone-2-immutability-state-machines.sql — transaction line immutability triggers (Axiom 2.1), transaction and invoice state machine triggers (Axiom 4.1), cascade to restrict conversion on core financial foreign keys (Axiom 2.2), structural invariant validation blocks, post-migration verification queries

Milestone 3 — Monetary Domain Migration — introduces integer minor-unit currency representation with deterministic reduction functions and algebraic database constraints.