v5.17.1 6 March 2026 Fix

Milestone 3 Completion — Trigger Hardening and Domain Migration

Kernel Milestone: 3 of 6 — Completion patch Previous: Milestone 3 — Monetary Domain Migration (v5.17.0) Next: Milestone 4 — Provenance

System Impact
-------------
Ledger integrity:         strengthened
Ledger mutation:          none — no posted records modified financially
Tenant isolation:         unchanged
Financial immutability:   strengthened — immutability triggers now function correctly
State machine:            unchanged
Breaking changes:         none
Replay determinism:       preserved
Invariant Change
----------------
Financial immutability triggers are now unconditionally executable regardless
of session search_path. Transaction VAT components and director/dividend
amounts are now stored under the canonical monetary domain.

Why This Matters

v5.17.0 established the monetary domain and corrected all application-layer arithmetic paths. During the final domain promotion migrations for transaction VAT components, two trigger paths sharing the same schema-qualification defect were discovered in the financial immutability enforcement layer: both referenced tables without schema qualification. PostgreSQL trigger functions execute without inheriting the session search path, which caused these guards to fail at runtime with a relation resolution error rather than the intended invariant exception. Both defects are corrected here.

Without these fixes, any application path that issued an update or delete against transaction lines associated with locked journals would fail with an opaque database error rather than the intended TMADD 5.0 rejection. The immutability enforcement was present but non-functional on these two paths.

This release also completes the final two domain promotions deferred from v5.17.0: transaction VAT components and director loan / dividend amounts are now stored under the canonical pence domain, eliminating the last remaining primitive-typed monetary columns in the financial kernel.


Immutability Trigger Fixes

Schema qualification defect — update path

A trigger guarding updates to transaction lines belonging to locked opening balance journals referenced the parent transactions table without schema qualification. Because trigger functions do not inherit the application session search path, PostgreSQL could not resolve the unqualified reference and the trigger aborted with a relation resolution error instead of enforcing the TMADD 5.0 Axiom 5 rejection.

Corrected to use the fully qualified reference. The guard now executes deterministically regardless of session configuration.

Enforced by: database trigger — Class M. Proof: migration_077.

Schema qualification defect — delete path

An identical defect existed in the corresponding delete-path trigger. Same root cause, same correction.

Enforced by: database trigger — Class M. Proof: migration_077b.


Domain Promotions

Transaction VAT components

The VAT amount column on transaction lines was a nullable primitive integer. Three-hundred and thirty existing rows carried a NULL value representing zero VAT — a tri-state representation (NULL / zero / non-zero) that is incompatible with the canonical monetary domain, which admits only integer values.

All NULL values were normalised to zero — a semantically neutral transformation, as NULL VAT and zero VAT are financially identical. The column was then promoted to the canonical monetary domain and made non-nullable, collapsing the tri-state to a binary (zero / non-zero). Triggers were temporarily disabled within the migration transaction to permit this schema normalisation and re-enabled immediately after the update. This is the only legitimate trigger bypass in a migration — it does not weaken the immutability guarantee for any application-layer write path.

Enforced by: domain type constraint — Class M. Proof: migration_078.

Director loan and dividend amounts

Director loan transaction amounts and dividend amounts were stored as 32-bit integers, creating an overflow risk for values above approximately £21,000 — a realistic threshold for director salary and dividend workflows. Both columns have been widened to the canonical 64-bit monetary domain, eliminating the overflow risk with no data rewrite required.

Enforced by: domain type constraint — Class M. Proof: migration_079.


Threat Closure

ThreatStatus BeforeStatus AfterEnforcement Layer
Immutability trigger failing on locked-journal update pathOpen — runtime error instead of invariant rejectionClosed (Class M)Database trigger, schema-qualified
Immutability trigger failing on locked-journal delete pathOpen — runtime error instead of invariant rejectionClosed (Class M)Database trigger, schema-qualified
Tri-state NULL / zero / non-zero VAT representationOpen — domain inconsistencyClosed (Class M)Domain type constraint, NOT NULL
32-bit overflow on director loan and dividend amountsOpen — silent truncation above ~£21kClosed (Class M)Domain type widening to 64-bit

Kernel Status

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

M4 (Provenance) begins with a fully canonical monetary schema and a correctly functioning immutability enforcement layer.