Skip to content

Commit aa7ee25

Browse files
hyperpolymathclaude
andcommitted
proof(epistemic): A15 — name the write ⟶ knows ⟶ fresh chain corollaries
Three named lemmas composing the post-A11+A14 pinned chain: * `syncImpliesKnowledge : Sync mod field old new -> Knowledge mod field new` — names the `Observed` step. * `writerKnowsPostWrite : (fv : FieldVersion) -> fv.field = field -> fv.lastWriter = writer -> Knowledge writer field fv.version` — a writer who commits to the canonical FieldVersion at the post-write state has Knowledge at that version; the writer-identity pin (`fv.lastWriter = writer`) flows through from WriteSync, so no caller can claim post-write knowledge for a module it does not own the write of. * `knowsImpliesFresh : Knows mod field ver -> Fresh mod field ver ver` — closes the chain: any non-trivial `Knows` witness yields a Fresh witness at the same version. The `Unknown` branch is dispatched via `absurd p` (the `MkKnows` precondition `ver > 0 = True` reduces to `False = True` when ver = 0). These are pure corollaries of A11 (WriteSync pin), A14 (Fresh pin), and the existing `syncRestoresFresh` / `Observed` machinery — no new constructors, no soundness change, just named composition for downstream callers. Residual-debt note extended to record A15. Verification: `idris2 --build src/abi/typed-wasm.ipkg` clean rebuild 22/22 modules, rc=0, zero errors. No `believe_me` / `assert_total` / `assert_smaller` / `postulate` / `sorry` introduced; `%default total` preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent cb272bd commit aa7ee25

1 file changed

Lines changed: 56 additions & 1 deletion

File tree

src/abi/TypedWasm/ABI/Epistemic.idr

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,58 @@ observedHasProvenance :
342342
observedHasProvenance Unknown = Nothing
343343
observedHasProvenance (Observed {oldVer} sync) = Just (oldVer ** sync)
344344

345+
-- ============================================================================
346+
-- Knowledge chain corollaries (A15, 2026-06-03 — composes A11 + A14)
347+
-- ============================================================================
348+
--
349+
-- Now that `Sync` (via A11) and `Fresh` (via A14) are both pinned to
350+
-- canonical `FieldVersion` records, the chain from a write to a
351+
-- knower's freshness is fully witness-carrying. The three lemmas
352+
-- below name the chain steps so callers can quote them directly
353+
-- rather than re-deriving each composition at every use site.
354+
355+
||| A `Sync` event immediately establishes `Knowledge` at the new
356+
||| version. Trivial corollary of the `Observed` constructor, named
357+
||| so the post-sync read protocol can be spelled out lemma-by-lemma.
358+
public export
359+
syncImpliesKnowledge :
360+
{old : Nat} ->
361+
Sync mod field old new -> Knowledge mod field new
362+
syncImpliesKnowledge {old} sync = Observed {oldVer = old} sync
363+
364+
||| A writer who supplies the canonical `FieldVersion` for its write
365+
||| has `Knowledge` at the post-write version. Composes `WriteSync`
366+
||| with `syncImpliesKnowledge`; the writer's identity flows in via
367+
||| the `fv.lastWriter = writer` pin, so no caller can claim
368+
||| post-write knowledge for a module it does not own the write of.
369+
public export
370+
writerKnowsPostWrite :
371+
(fv : FieldVersion) ->
372+
fv.field = field ->
373+
fv.lastWriter = writer ->
374+
Knowledge writer field fv.version
375+
writerKnowsPostWrite fv fp wp =
376+
Observed (WriteSync {oldVersion = 0} fv fp Refl wp)
377+
378+
||| Any non-trivial `Knows` witness entails a `Fresh` witness at the
379+
||| same version. Closes the chain `Sync ⟶ Knowledge ⟶ Knows ⟶
380+
||| Fresh`: a module that knows a field's version is, by construction,
381+
||| fresh at that version (because the `Sync` that established the
382+
||| knowledge restored freshness; A11+A14 pinning guarantees the
383+
||| `FieldVersion` threads through end-to-end).
384+
|||
385+
||| The `Unknown` branch is impossible by the `MkKnows` precondition
386+
||| `ver > 0 = True`: `Unknown` inhabits only `Knowledge mod field 0`,
387+
||| at which point `0 > 0` reduces to `False`, contradicting the
388+
||| `= True` proof.
389+
public export
390+
knowsImpliesFresh :
391+
Knows mod field ver -> Fresh mod field ver ver
392+
knowsImpliesFresh (MkKnows (Observed sync) _) = syncRestoresFresh sync
393+
knowsImpliesFresh (MkKnows Unknown p) = absurd p
394+
345395
-- ----------------------------------------------------------------------------
346-
-- Residual debt note — A11 ➞ A14 closure (2026-06-02, #102)
396+
-- Residual debt note — A11 ➞ A14 ➞ A15 closure (2026-06-03)
347397
-- ----------------------------------------------------------------------------
348398
--
349399
-- A11 (2026-05-26) tightened only `WriteSync` to require a
@@ -357,3 +407,8 @@ observedHasProvenance (Observed {oldVer} sync) = Just (oldVer ** sync)
357407
-- caller has supplied a real `FieldVersion`. `Observed` likewise
358408
-- inherits the pin via its `Sync` argument. No remaining
359409
-- constructor in this file admits an unfounded version claim.
410+
--
411+
-- A15 (2026-06-03) names the chain corollaries `syncImpliesKnowledge`,
412+
-- `writerKnowsPostWrite`, and `knowsImpliesFresh`, so the
413+
-- write ⟶ sync ⟶ knowledge ⟶ knows ⟶ fresh chain can be quoted
414+
-- step-by-step rather than re-derived at each use site.

0 commit comments

Comments
 (0)