Safe operations preserve evidence through routine failures, corrections, retention, and backup. Application commands append events inside transactions; they do not edit history. A mistake is fixed by a compensating event that references the original and explains the reason.
Build one repository method: append_event(expected_version, event). It begins a transaction, checks current projection version, validates payload and transition, inserts a unique idempotency key, updates the rebuildable projection, and commits. A conflict rolls back and asks the caller to reload. Never catch a database error and continue with partial in-memory state.
Hash chains make accidental mutation detectable: each event hash covers canonical payload, prior hash, sequence, type, and timestamp. They do not prove who controlled the database, so combine them with restricted file access, backups, and periodic signed audit exports.
Corrections must name the erroneous event, category, author/reviewer, and replacement facts. The original remains in reports with a “superseded” annotation. Resolution-source changes generate new versions and place affected paper results in disputed state until reviewed.
Backups need restore tests. Copy through SQLite’s supported backup mechanism or a consistent snapshot, hash the backup, store it outside the active directory, restore into a temporary location, run integrity checks, and replay projections. A backup never restored is only a hope.
Retention removes exported raw public documents only according to a declared policy and never silently breaks an event’s provenance. Keep required hashes and tombstone metadata; do not retain unexpected personal data.
Practice disaster recovery with explicit objectives: maximum acceptable lost sealed runs and maximum restore time for this educational service. Record backup start/end, source database hash, backup hash, verification result, restore duration, and replay result. Keep at least one restore copy outside the active VPS failure domain, using access controls appropriate to the public-only dataset.
Add a read-only audit mode that opens a copied database, verifies migrations and hash chains, replays projections, and emits a signed summary without changing the file. Run it on a schedule and before release. If it fails, keep serving the last clearly dated report with a degraded banner; do not publish new state.
🇵🇰 Pakistan Angle
Power interruption can occur mid-write. Transactions and WAL improve recovery, but still test sudden termination and disk-full behavior. Keep an offline backup where practical, and never synchronize .env or sensitive operational data into shared drives.
Hands-On Exercise
Implement append with version checks. Simulate duplicate delivery, two concurrent writers, process termination, disk-full error, correction, backup, and restore. Reconcile original and restored event hashes and document any expected SQLite journal files.
Completion Rubric
- Appends are transactional, validated, versioned, and idempotent.
- Corrections preserve and reference original history.
- Hash chains and projections reconcile.
- Backup restore is exercised, not assumed.
- Retention cannot silently destroy provenance.
Sources
Key takeaway: Safe data operations make failures and corrections visible while keeping the evidence chain replayable.