Skip to content

Commit 4883ae2

Browse files
claudehyperpolymath
authored andcommitted
proof(db): EchoTransaction — rollback discards writes (no-section); closes #174
SQL transaction rollback safety as a Security instance reducing to no-section-of-collapsing-map (affinescript db-theory #2 / #DB-2.1). A staged WriteSet is an affine resource; rollback collapses it to an information-free RollbackLog, so no pure function recovers the discarded writes from the receipt alone. - proofs/agda/EchoTransaction.agda: Mutation/WriteSet/RollbackLog/rollback, rollback-discards-writes (direct no-section), transaction-security (Security instance), rollback-no-recovery (via the abstract theorem), honest matched-negative block (NOT durability/isolation/commit-dual/ savepoint/runtime-memory). - Wired into All.agda; headlines pinned in Smoke.agda. - Classified in echo-kernel-note.adoc + MAP.adoc (kernel-guard Check B). --safe --without-K, zero postulates. All.agda + Smoke.agda exit 0; kernel-guard PASS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019GiSiEfgZCte35dyykgBHs
1 parent 7020621 commit 4883ae2

5 files changed

Lines changed: 200 additions & 1 deletion

File tree

docs/echo-types/MAP.adoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,14 @@ honest-bound matched-negative block.
253253
the `affine` mode in `EchoObservationalEquivalence`. Honest-bound:
254254
NOT side-channel-safe / cryptographic deniability / adaptive
255255
adversary. `proofs/agda/EchoDeniability.agda`. `[REAL]`
256+
* *Transaction (rollback safety, issue #174)* — `WriteSet` (staged
257+
mutations) → `RollbackLog` collapsing audit boundary; `rollback`
258+
admits no section, so a discarded write-set is unrecoverable from the
259+
receipt alone (#DB-2.1). Packaged as a `Security` instance
260+
(`transaction-security`), reducing to `no-section-of-collapsing-map`.
261+
Honest-bound: NOT durability / isolation / commit-semantics (the
262+
dual) / savepoint-locality / runtime-memory-zeroed.
263+
`proofs/agda/EchoTransaction.agda`. `[REAL]`
256264
* *Aggregation (general, issue #175)* — aggregation-as-fold over a
257265
`Monoid`, with a `GroupAggregator` and the monoid-homomorphism law
258266
`aggregation-as-fold` (aggregating a concatenation = combining the

docs/echo-types/echo-kernel-note.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ kernel** — the boundary is real and lives outside this core.
125125
*Application/extension modules* (also added via the same sweep):
126126
`EchoEntropy`, `EchoLLEncoding`, `EchoProvenance`, `EchoSecurity`,
127127
`EchoProbabilisticSupport`, `EchoDifferential`, `EchoDeniability`,
128-
`EchoAggregation`, `EchoVariance`
128+
`EchoAggregation`, `EchoVariance`, `EchoTransaction`
129129
are derived domain applications mapped under their own headings in
130130
MAP.adoc. `EchoDeniability` formalises residue deniability: the
131131
perfect (constant / no-section) case and the partial (injective /

proofs/agda/All.agda

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ open import EchoDifferential -- Perturbation tracking (audience-facing sensi
9696
-- and the injective/section-exists story (partial case), with the
9797
-- IsConstantOpener boundary tying deniability to the affine mode.
9898
open import EchoDeniability
99+
open import EchoTransaction -- Transaction rollback safety (issue #174; Security instance)
99100

100101
-- Narrative deliverable: curated index of "why Echo deserves a name".
101102
open import EchoCanonicalIdentitySuite

proofs/agda/EchoTransaction.agda

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
{-# OPTIONS --safe --without-K #-}
2+
-- SPDX-License-Identifier: MPL-2.0
3+
-- SPDX-FileCopyrightText: 2025-2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
4+
5+
-- EchoTransaction: SQL transaction rollback safety as an instance of the
6+
-- generic no-section theorem. Closes echo-types#174 (consumer:
7+
-- affinescript db-theory #2, `stdlib/Transaction.affine`,
8+
-- `docs/academic/proofs/db-theory-2-transaction-safety.md` #DB-2.1).
9+
--
10+
-- !! HONEST BOUND, STATED UP FRONT !!
11+
--
12+
-- `rollback-discards-writes` is a TYPE-LEVEL guarantee that no pure Agda
13+
-- function reconstructs a discarded write-set from the rollback receipt
14+
-- alone (factored through
15+
-- `EchoNoSectionGeneric.no-section-of-collapsing-map`). It is NOT:
16+
-- * `durability` — a claim about writes surviving a crash;
17+
-- * `isolation` — a claim about concurrent-transaction visibility;
18+
-- * `commit-semantics` — #DB-2.2 commit-promotes-writes is the DUAL
19+
-- (commit PRESERVES writes, so it is not a
20+
-- no-section statement at all);
21+
-- * `savepoint-locality` — #DB-2.3 is a structural/runtime nesting
22+
-- claim outside this carrier;
23+
-- * `runtime-memory-zeroed` — a claim about physical memory contents.
24+
-- Conflating any of these with `rollback-discards-writes` is the category
25+
-- error the matched-negative block at the bottom heads off. Same
26+
-- honest-bound discipline as `EchoSecurity` / `RegionExitAudit`
27+
-- (R-2026-05-18).
28+
--
29+
-- *Structural content (#DB-2.1).* A transaction's staged-but-uncommitted
30+
-- writes are an affine resource; `rollback` consumes that resource and
31+
-- emits a receipt that records only THAT a rollback occurred, never which
32+
-- writes were discarded. Two distinct write-sets therefore collapse to
33+
-- the same receipt, so `rollback` admits no section: a post-rollback
34+
-- caller holding only the receipt cannot type-check a function returning
35+
-- the discarded write-set. This is precisely "the one consumption that
36+
-- discards is observationally equivalent to never having started".
37+
--
38+
-- This is the first `Security` instance outside the original region-exit
39+
-- audit setting (`EchoSecurity.region-exit-audit-instance`), establishing
40+
-- that any bracketed-mutation resource — transactions, scoped
41+
-- capabilities, scoped logs — reduces to the same generic lemma.
42+
--
43+
-- Headlines (pinned in Smoke.agda):
44+
--
45+
-- * Mutation / WriteSet / RollbackLog -- the carrier types
46+
-- * rollback -- the collapsing audit boundary
47+
-- * rollback-discards-writes -- #DB-2.1, direct no-section
48+
-- * transaction-security -- the `Security` instance
49+
-- * rollback-no-recovery -- #DB-2.1 via the abstract theorem
50+
--
51+
-- Scope guardrail (Echo-vs-Σ clearance). `rollback-discards-writes` uses
52+
-- `no-section-of-collapsing-map` directly, whose three-line trans/sym/cong
53+
-- proof is the canonical non-trivial Echo-typed content; replacing it with
54+
-- a bare `Σ` + `_≡_` would lose the collapse/no-section content. The
55+
-- `NotProved-*` aliases pin the honest scope.
56+
57+
module EchoTransaction where
58+
59+
open import EchoNoSectionGeneric using (no-section-of-collapsing-map)
60+
open import EchoSecurity using (Security; module SecurityTheorems)
61+
62+
open import Data.Nat.Base using (ℕ)
63+
open import Data.List.Base using (List; []; _∷_)
64+
open import Data.Product.Base using (Σ)
65+
open import Data.Unit.Base using (⊤; tt)
66+
open import Relation.Binary.PropositionalEquality using (_≡_; _≢_; refl)
67+
open import Relation.Nullary using (¬_)
68+
69+
----------------------------------------------------------------------
70+
-- The carrier.
71+
--
72+
-- A `Mutation` is an opaque cell-write (address, value); a `WriteSet` is
73+
-- the ordered list a transaction has staged but not committed. The
74+
-- `RollbackLog` receipt is information-free: it records only that a
75+
-- rollback happened.
76+
----------------------------------------------------------------------
77+
78+
data Mutation : Set where
79+
set-cell : Mutation
80+
81+
WriteSet : Set
82+
WriteSet = List Mutation
83+
84+
data RollbackLog : Set where
85+
rolled-back : RollbackLog
86+
87+
-- The audit boundary: rollback collapses every write-set to the single
88+
-- receipt, discarding the staged mutations.
89+
rollback : WriteSet RollbackLog
90+
rollback _ = rolled-back
91+
92+
----------------------------------------------------------------------
93+
-- The audit witnesses: two distinct write-sets that collapse identically.
94+
----------------------------------------------------------------------
95+
96+
ws₁ ws₂ : WriteSet
97+
ws₁ = []
98+
ws₂ = set-cell 0 1 ∷ []
99+
100+
ws₁≢ws₂ : ws₁ ≢ ws₂
101+
ws₁≢ws₂ ()
102+
103+
rollback-collapses : rollback ws₁ ≡ rollback ws₂
104+
rollback-collapses = refl
105+
106+
----------------------------------------------------------------------
107+
-- #DB-2.1 rollback-discards-writes (headline): no pure function
108+
-- reconstructs a discarded write-set from the rollback receipt alone.
109+
----------------------------------------------------------------------
110+
111+
rollback-discards-writes :
112+
¬ Σ (RollbackLog WriteSet) (λ recover ws recover (rollback ws) ≡ ws)
113+
rollback-discards-writes =
114+
no-section-of-collapsing-map rollback ws₁ ws₂ ws₁≢ws₂ rollback-collapses
115+
116+
----------------------------------------------------------------------
117+
-- The same guarantee as a `Security` instance, so the transaction
118+
-- carrier joins the EchoSecurity audience family. A single transaction
119+
-- scope is the (trivial) `RegionId`; `audit-no-recovery-at` re-derives
120+
-- #DB-2.1 through the abstract theorem, witnessing that the instance is
121+
-- real (not merely structurally similar).
122+
----------------------------------------------------------------------
123+
124+
transaction-security : Security
125+
transaction-security = record
126+
{ RegionId =
127+
; Resource = λ _ WriteSet
128+
; Receipt = λ _ RollbackLog
129+
; exit = λ _ rollback
130+
; res₁ = λ _ ws₁
131+
; res₂ = λ _ ws₂
132+
; res-distinct = λ _ ws₁≢ws₂
133+
; exit-collapses = λ _ rollback-collapses
134+
}
135+
136+
rollback-no-recovery :
137+
(r : ⊤)
138+
¬ Σ (RollbackLog WriteSet) (λ recover ws recover (rollback ws) ≡ ws)
139+
rollback-no-recovery = SecurityTheorems.audit-no-recovery-at transaction-security
140+
141+
----------------------------------------------------------------------
142+
-- Matched-negative block (HONEST BOUND, per R-2026-05-18 discipline).
143+
--
144+
-- `⊤`-aliased so `grep NotProved` catches them. A consumer citing
145+
-- `rollback-discards-writes` beyond these scopes is making a category
146+
-- error: the guarantee is exactly "no pure Agda function reconstructs
147+
-- the discarded write-set from the receipt alone, inside this model".
148+
----------------------------------------------------------------------
149+
150+
NotProved-durability : Set
151+
NotProved-durability =
152+
153+
NotProved-isolation : Set
154+
NotProved-isolation =
155+
156+
NotProved-commit-semantics : Set -- #DB-2.2 is the dual, not a no-section
157+
NotProved-commit-semantics =
158+
159+
NotProved-savepoint-locality : Set -- #DB-2.3 is structural/runtime
160+
NotProved-savepoint-locality =
161+
162+
NotProved-runtime-memory-zeroed : Set
163+
NotProved-runtime-memory-zeroed =
164+
165+
----------------------------------------------------------------------
166+
-- Companion remark.
167+
--
168+
-- #DB-2.2 (commit-promotes-writes) is the dual of #DB-2.1: commit
169+
-- PRESERVES the write-set, so it is an equality/section statement, not a
170+
-- no-section one — it belongs in a separate carrier and is deliberately
171+
-- not modelled here. #DB-2.3 (savepoint-locality) is a nesting/structural
172+
-- property of the transaction tree; it too is out of scope for this
173+
-- minimal rollback-safety carrier. The `Mutation` / `RollbackLog` types
174+
-- are placeholders chosen for inhabitability + a clean distinctness
175+
-- witness; the proof goes through for any carrier with two distinct
176+
-- write-sets collapsing to the same receipt.
177+
----------------------------------------------------------------------

proofs/agda/Smoke.agda

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,19 @@ open import EchoSecurity using
850850
; region-exit-audit-instance
851851
)
852852

853+
-- EchoTransaction — SQL transaction rollback safety (issue #174). The
854+
-- staged write-set is an affine resource; rollback collapses it to an
855+
-- information-free receipt, so no pure function recovers the discarded
856+
-- writes (#DB-2.1). A `Security` instance reducing to no-section.
857+
open import EchoTransaction using
858+
( WriteSet
859+
; RollbackLog
860+
; rollback
861+
; rollback-discards-writes
862+
; transaction-security
863+
; rollback-no-recovery
864+
)
865+
853866
-- EchoProbabilisticSupport — third audience move per GPT order.
854867
-- Abstract `Sampling` record (outcome + index + distinguishability
855868
-- witness) with four parametric headline theorems via `module

0 commit comments

Comments
 (0)