Skip to content

Commit fcc6a83

Browse files
hyperpolymathclaude
andcommitted
feat(oblibeniser): implement Phase 1 — reversible operations, audit trails, undo/time-travel
Implement the core Oblíbený engine: manifest parsing for [project], [[operations]], [audit], and [undo] sections; code generation for inverse functions using mirror/log-replay/snapshot strategies; hash-chained audit trail with tamper detection; undo/redo stack with configurable depth; and time-travel debugging via snapshot-indexed history navigation. - ABI: ReversibleOperation, InverseStrategy, AuditEntry, AuditTrail, UndoStack, UndoEntry, TimeTravel, TimeTravelStep, StateSnapshot - Codegen: parser.rs, inverse_gen.rs, audit_gen.rs with full module output - Manifest: project/operations/audit/undo TOML schema with validation - Tests: 27 unit tests + 8 integration tests (all passing) - Example: examples/reversible-db/ with 6 operations across all strategies Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1288263 commit fcc6a83

12 files changed

Lines changed: 3791 additions & 50 deletions

File tree

Cargo.lock

Lines changed: 906 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/reversible-db/README.adoc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// SPDX-License-Identifier: PMPL-1.0-or-later
2+
= Reversible Database Example
3+
:author: Jonathan D.A. Jewell
4+
:email: j.d.a.jewell@open.ac.uk
5+
6+
== Overview
7+
8+
This example demonstrates how oblibeniser makes common database operations
9+
fully reversible using all three inverse strategies:
10+
11+
[cols="2,1,3"]
12+
|===
13+
| Operation | Strategy | Rationale
14+
15+
| `db_insert` / `db_delete`
16+
| Mirror
17+
| Insert ↔ Delete are algebraic inverses — deterministic reversal.
18+
19+
| `db_update` / `db_batch_update`
20+
| Log-replay
21+
| Updates record old values in a mutation log and replay backwards to undo.
22+
23+
| `schema_migrate` / `db_truncate`
24+
| Snapshot
25+
| Destructive operations capture full state before execution.
26+
|===
27+
28+
== Usage
29+
30+
[source,bash]
31+
----
32+
# Generate reversible wrappers from this manifest:
33+
oblibeniser generate \
34+
--manifest examples/reversible-db/oblibeniser.toml \
35+
--output generated/reversible-db
36+
37+
# Inspect generated files:
38+
ls generated/reversible-db/
39+
# → inverses.rs audit.rs verify_audit.rs summary.txt
40+
41+
# View the generation summary:
42+
cat generated/reversible-db/summary.txt
43+
----
44+
45+
== Audit Trail
46+
47+
The audit trail uses hash-chaining (like a lightweight blockchain) to ensure
48+
tamper-evidence. Each entry contains the hash of the previous entry:
49+
50+
....
51+
Entry[0]: hash=a1b2c3... prev=
52+
Entry[1]: hash=d4e5f6... prev=a1b2c3...
53+
Entry[2]: hash=g7h8i9... prev=d4e5f6...
54+
....
55+
56+
If any entry is modified after the fact, the chain breaks and verification fails.
57+
58+
== Undo Stack
59+
60+
With `max-depth = 200`, the last 200 operations can be undone. The
61+
`auto-checkpoint-interval = 25` means a full state snapshot is taken every
62+
25 operations, enabling efficient time-travel to any point in history.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Example: Reversible database operations via Oblíbený.
3+
#
4+
# This manifest demonstrates all three inverse strategies applied to
5+
# common database operations. Run with:
6+
# oblibeniser generate --manifest examples/reversible-db/oblibeniser.toml
7+
8+
[project]
9+
name = "reversible-db"
10+
version = "0.1.0"
11+
description = "A database layer with fully reversible CRUD operations"
12+
13+
# INSERT: Mirror strategy — inverse is DELETE by key.
14+
[[operations]]
15+
name = "db_insert"
16+
forward-fn = "db::insert"
17+
params = ["table:String", "key:String", "value:Vec<u8>"]
18+
inverse-strategy = "mirror"
19+
20+
# DELETE: Mirror strategy — inverse is INSERT with the deleted data.
21+
[[operations]]
22+
name = "db_delete"
23+
forward-fn = "db::delete"
24+
params = ["table:String", "key:String"]
25+
inverse-strategy = "mirror"
26+
27+
# UPDATE: Log-replay strategy — records old values and replays them backwards.
28+
[[operations]]
29+
name = "db_update"
30+
forward-fn = "db::update"
31+
params = ["table:String", "key:String", "field:String", "new_value:String"]
32+
inverse-strategy = "log-replay"
33+
34+
# BATCH UPDATE: Log-replay — records each individual change in the batch.
35+
[[operations]]
36+
name = "db_batch_update"
37+
forward-fn = "db::batch_update"
38+
params = ["table:String", "updates:Vec<UpdatePair>"]
39+
inverse-strategy = "log-replay"
40+
41+
# SCHEMA MIGRATION: Snapshot — captures full DB state before migration.
42+
[[operations]]
43+
name = "schema_migrate"
44+
forward-fn = "schema::migrate"
45+
params = ["target_version:u32"]
46+
inverse-strategy = "snapshot"
47+
48+
# TRUNCATE: Snapshot — only safe inverse is full state restore.
49+
[[operations]]
50+
name = "db_truncate"
51+
forward-fn = "db::truncate"
52+
params = ["table:String"]
53+
inverse-strategy = "snapshot"
54+
55+
[audit]
56+
hash-chain = true
57+
storage = "file"
58+
max-entries = 50000
59+
60+
[undo]
61+
max-depth = 200
62+
auto-checkpoint-interval = 25

0 commit comments

Comments
 (0)