Skip to content

proof(p3.2): A16 — typed ProgressiveCheckW + progressive-order monotonicity#158

Open
hyperpolymath wants to merge 5 commits into
mainfrom
proof/progressive-check-typed
Open

proof(p3.2): A16 — typed ProgressiveCheckW + progressive-order monotonicity#158
hyperpolymath wants to merge 5 commits into
mainfrom
proof/progressive-check-typed

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Closes the deferred half of PROOF-NEEDS §P3.2 — the "progressive-order monotonicity under a typed ProgressiveCheck" claim that the 2026-04-18 A8 banner explicitly left as future work:

the stronger "progressive-order" claim requires redesigning ProgressiveCheck with a typed level = S prevLevel index and is left as future work.

A16 lands that redesign as a purely additive ProgressiveCheckW alongside the legacy ProgressiveCheck, built on top of the standards#130 LevelAttestationW family (already in tree). Skipping levels (advancing L1 → L5 in one step) and out-of-order attestations (attaching AttestL3W to a ProgressiveCheckW 5) are now type errors — they cannot construct.

What lands

src/abi/TypedWasm/ABI/Proofs.idr §A16 (~150 LOC appended)

```idris
data ProgressiveCheckW : (highestLevel : Nat) -> Type where
StartL1W : LevelAttestationW 1 -> ProgressiveCheckW 1
AdvanceW : (n : Nat)
-> ProgressiveCheckW n
-> LevelAttestationW (S n)
-> ProgressiveCheckW (S n)

data VisitedAt : (m : Nat) -> ProgressiveCheckW n -> Type where
VAStartW : (att : LevelAttestationW 1) -> VisitedAt 1 (StartL1W att)
VAHeadW : (n : Nat) -> (prev : ProgressiveCheckW n)
-> (att : LevelAttestationW (S n))
-> VisitedAt (S n) (AdvanceW n prev att)
VATailW : VisitedAt m prev -> VisitedAt m (AdvanceW n prev att)

progressiveOrderW : (check : ProgressiveCheckW n)
-> (m : Nat) -> LT 0 m -> LTE m n
-> VisitedAt m check
```

Plus:

  • lteSuccCases : {m, n : Nat} -> LTE m (S n) -> Either (m = S n) (LTE m n) — decidable LTE case-split helper used by the recursion.
  • chainAlwaysVisitsL1 — specialised corollary for the common "L1 is the entry point" guarantee.
  • forgetProgressiveCheckW : ProgressiveCheckW n -> ProgressiveCheck — index-erasing bridge to the legacy untyped chain, so downstream consumers can still feed buildCertificate via the typed API.

PROOF-NEEDS.md

Purely additive

The legacy ProgressiveCheck, LevelAchievedIn, composeAchievedL/R, and the entire buildCertificate pipeline are untouched. No external caller of ProgressiveCheck / StartL1 / Advance exists in src/ / examples/ / tests/ (grep-verified before landing — the only signature reference is in tests/proof/regression.mjs), so the additivity preserves the typed-wasm public surface.

Stacking

This PR is stacked on #152 (proof/epistemic-fresh-pin-102) — same reason as PR #155: the HEAD build break #152 fixes is required for the package build to pass. Siblings on the same base.

When #152 merges, this PR will rebase forward to main as a 1-commit fast-forward.

Test plan

Cross-references

🤖 Generated with Claude Code

hyperpolymath and others added 5 commits June 1, 2026 01:10
- C001: CodeQL language fixes
- C002: License identifier standardization
- C003: Outdated actions audit
- C004: Pin standards refs to SHA 861b5e9
- C005: Add workflow-level permissions
…composeWitness/composeCertificates definitional mismatch

* Epistemic.idr — close the symmetric soundness gap A11 left open.
  `WriteSync` was tightened to require a `FieldVersion` pin in A11
  (PR #72), but `Fresh` and (transitively) `ExplicitSync` remained
  freely constructible via `MkFresh Refl`. This change re-indexes
  `Fresh` on a `FieldVersion` value plus `fv.field = field` and
  `fv.version = currentVersion` pins, so freshness can no longer be
  minted ex nihilo. `ExplicitSync` inherits the pin via its embedded
  `Fresh` argument — no separate parameter needed; documented inline.
  Cascade: `writerKnowsFresh` now takes the canonical FieldVersion +
  writer-identity pin; `syncRestoresFresh (ExplicitSync fresh)`
  returns `fresh` directly (no remint); the three Fresh-matching
  lemmas (`freshImpliesEqual`, `freshNotStale`,
  `concurrentWriteStales`) use `MkFresh _ _ _ eq` shape. Residual-debt
  block rewritten to record A14 closure.

* Proofs.idr — root-cause fix for HEAD build break in
  `composeWitnessLegacyAgree`. `composeWitness` used `Prelude.min`
  (Ord-derived, `if compareNat _ _ == LT then _ else _`) while
  `composeCertificates` uses `Data.Nat.minimum` (structural). The
  bridge lemma's `rewrite ... in Refl` could not reduce across the
  mismatch. Switched `composeWitness` to `minimum` (numerically
  identical, definitionally aligned). Docstring records why.

* Both files also pick up the in-progress estate copyright-owner
  format adjustment on line 2 (drops the `(hyperpolymath)`
  parenthetical) to satisfy the local pre-commit owner-line check.
  Single-line touch each, no SPDX-identifier or LICENSE change.

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 across both files.

Closes #102.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
…nicity

PROOF-NEEDS §P3.2 (A8) reframed the level-monotonicity claim under
the operational (untyped) `ProgressiveCheck`, leaving the stronger
"progressive-order" claim — achieving level N implies levels 1..N
were all visited — explicitly deferred:

  > the stronger "progressive-order" claim requires redesigning
  > `ProgressiveCheck` with a typed `level = S prevLevel` index and
  > is left as future work.

A16 closes that deferred half.

What lands in src/abi/TypedWasm/ABI/Proofs.idr (~150 LOC appended, no
existing definition touched):

* `ProgressiveCheckW : (highestLevel : Nat) -> Type` — typed chain
  built on top of the standards#130 `LevelAttestationW` family
  (already in tree).  Constructors enforce that each attestation
  attest the exact level it sits at:

      StartL1W : LevelAttestationW 1 -> ProgressiveCheckW 1
      AdvanceW : (n : Nat)
              -> ProgressiveCheckW n
              -> LevelAttestationW (S n)
              -> ProgressiveCheckW (S n)

  Skipping levels (advancing L1 → L5 in one step) and out-of-order
  attestations (attaching `AttestL3W` to a `ProgressiveCheckW 5`)
  are now type errors — they cannot construct.

* `VisitedAt : (m : Nat) -> ProgressiveCheckW n -> Type` — sub-
  derivation witness with three constructors (StartW / HeadW / TailW
  shift).

* `lteSuccCases : {m, n : Nat} -> LTE m (S n) -> Either (m = S n)
  (LTE m n)` — decidable case-split helper used by the recursion.

* `progressiveOrderW : (check : ProgressiveCheckW n) -> (m : Nat)
                    -> LT 0 m -> LTE m n -> VisitedAt m check`
  — the progressive-order theorem.  By induction on the check and
  one LTE branch at each `AdvanceW` layer.  Total.

* `chainAlwaysVisitsL1` — specialised corollary for the common
  "L1 is the entry point" guarantee.

* `forgetProgressiveCheckW : ProgressiveCheckW n -> ProgressiveCheck`
  — index-erasing bridge to the legacy untyped chain, so downstream
  consumers can still feed `buildCertificate` via the typed API.

What lands in PROOF-NEEDS.md:

* New `RECONCILIATION 2026-06-03 (A16 — P3.2 progressive-order half
  closed)` banner at the top.
* §P3.2 itself now records the closure with the typed-chain
  signature, the bridge, and the "Purely additive" / "Zero escape
  hatches" disclaimers.
* 3-line owner-line header normalisation (incidental hook
  compliance — same micro-pattern as PR #153 / #155).

Purely additive arc.  The legacy `ProgressiveCheck`,
`LevelAchievedIn`, `composeAchievedL/R`, and the entire
`buildCertificate` pipeline are untouched.  No external caller of
`ProgressiveCheck` / `StartL1` / `Advance` exists in src/ /
examples/ / tests/ (grep-verified before landing), so the
additivity preserves the typed-wasm public surface.

Verification:

* Whole-package build rc=0, 22/22 modules, 0 errors (only pre-
  existing shadowing warnings in unrelated modules — Epistemic,
  Tropical, Choreography).
* `idris2 --check src/abi/TypedWasm/ABI/Proofs.idr` clean.

No `believe_me`, `assert_total`, `postulate`, `sorry`, `Admitted`,
or `assert_smaller` introduced.  `%default total` preserved across
the arc.

Stacks on `proof/epistemic-fresh-pin-102` (#152) — same reason as
PR #155 (the HEAD build break PR #152 fixes is required for the
package build to pass).

Refs PROOF-NEEDS §P3.2 (the deferred half).
Refs #102, #152, #153, #155 (companion proof work in flight).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Base automatically changed from proof/epistemic-fresh-pin-102 to main June 3, 2026 23:36
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 6, 2026 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant