Skip to content

Commit 588ffd8

Browse files
hyperpolymathclaude
andcommitted
characteristic/EI: discharge abstract loss-only obligation via sharpened proper-strict criterion
The obligation flagged open in RecipeNonTriviality.agda was `Mode-is-loss-only : ¬ NonLossOnly ModeAxis`. That literal claim is FALSE: the un-refined NonLossOnly counts reflexive identity steps, so it is vacuously satisfied by every multi-inhabitant axis. This commit proves that vacuity explicitly (NonLossOnly-holds-vacuously-for-Mode), then sharpens the criterion to the intended irreflexive reading (ProperNonLossOnly: proper strict steps move between distinct decorations) and discharges the obligation in its defensible form: * ChoreoAxis-proper-non-loss-only — positive case retained * Mode-is-not-proper-non-loss-only — Mode loss-only, discharged All --safe --without-K, zero postulates, zero escape pragmas; full characteristic lane typechecks. EI-2 remains [CLOSED-NEG] (terminated-negative) — verdict unchanged. MAP.adoc status updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2b9be9c commit 588ffd8

2 files changed

Lines changed: 151 additions & 34 deletions

File tree

docs/echo-types/MAP.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ behind — `git fetch` and read `origin/main` before trusting any survey.
4141
remainder of information-losing computation: for `f : A → B`,
4242
`Echo f y := Σ (x : A), (f x ≡ y)`. `[REAL]`
4343

44+
* Kernel: `proofs/agda/EchoKernel.agda` — the funext-free,
45+
postulate-free core (re-export of `Echo` + a pinned `Kernel-contract`).
46+
`[REAL]` Everything else imports `Echo` transitively; the
47+
kernel-vs-derived classification + funext-free certificate is
48+
`docs/echo-types/echo-kernel-note.adoc`.
4449
* Proofs: `proofs/agda/Echo.agda` + ~24 `Echo*.agda` modules
4550
(`EchoCategorical`, `EchoDecidable`, `EchoCharacteristic`,
4651
`EchoApprox`, `EchoIndexed`, …).
@@ -84,6 +89,12 @@ The echo-invariant line: epistemic structure, choreographies, roles.
8489
* `EI-2` is `[CLOSED-NEG]` (terminated negative — do not reopen).
8590
`RoleRole.agda`'s "REAL OBSTRUCTION" is a closed negative result,
8691
not debt.
92+
* `[REAL]` 2026-05-18: the abstract loss-only obligation flagged open
93+
in `RecipeNonTriviality.agda` is discharged. The un-refined
94+
`NonLossOnly` is shown vacuous (`NonLossOnly-holds-vacuously-for-Mode`);
95+
the sharpened irreflexive `ProperNonLossOnly` certifies Choreo
96+
(`ChoreoAxis-proper-non-loss-only`) and refutes Mode
97+
(`Mode-is-not-proper-non-loss-only`). EI-2 verdict unchanged.
8798

8899
=== CNO / absolute-zero `[REAL]`
89100
Certified Null Operations = echo types where `f = id`. absolute-zero is

proofs/agda/characteristic/RecipeNonTriviality.agda

Lines changed: 140 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ open import EchoLinear using
114114
; linear≤linear
115115
; linear≤affine
116116
; affine≤affine
117+
; LEcho
118+
; degradeMode
119+
; affine-all-equal
117120
)
118121
open import EchoGraded using
119122
( Grade
@@ -128,7 +131,12 @@ open import EchoGraded using
128131
; residue≤forget
129132
; forget≤forget
130133
)
131-
open import EchoCharacteristic using (collapse)
134+
open import EchoCharacteristic using
135+
( collapse
136+
; echo-true
137+
; echo-false
138+
; echo-true≢echo-false
139+
)
132140
open import characteristic.RoleGraded using
133141
( RoleGEcho
134142
; applyRole
@@ -349,7 +357,14 @@ recipe-non-triviality-concrete =
349357
--
350358
-- Status of the generic form:
351359
-- * Axis record: defined.
352-
-- * NonLossOnly predicate: defined.
360+
-- * NonLossOnly predicate: defined (and shown vacuous — see
361+
-- `NonLossOnly-holds-vacuously-for-Mode`).
362+
-- * ProperNonLossOnly predicate (sharpened, irreflexive): defined.
363+
-- * Choreo certified under the sharpened predicate
364+
-- (`ChoreoAxis-proper-non-loss-only`).
365+
-- * Mode loss-only under the sharpened predicate: DISCHARGED
366+
-- (`Mode-is-not-proper-non-loss-only`). This is the abstract
367+
-- obligation previously flagged open.
353368
-- * Generic 2D family: requires decidable equality and a live
354369
-- decoration; partial scaffolding below.
355370
-- * Generic forward direction: not yet proved.
@@ -423,40 +438,131 @@ ChoreoAxis-non-loss-only =
423438
Client , Server , c⊑s , choreo-c⊑s-strict
424439

425440
------------------------------------------------------------------------
426-
-- Mode is loss-only at the abstract level.
427-
--
428-
-- The strict step linear≤affine has transport `weaken` =
429-
-- collapse-to-residue, which collapses Echo collapse tt (multiple
430-
-- inhabitants) to EchoR ⊤ TrivialCert tt (one inhabitant up to
431-
-- TrivialCert structure). All inputs map to the same output, so
432-
-- the step has no distinguishing pair.
433-
--
434-
-- Formalising "no distinguishing pair" requires showing that
435-
-- distinct inputs map to equal outputs, which is the
436-
-- collapse-residue-same property. EchoLinear has
437-
-- weaken-collapses-distinction : weaken echo-true ≡ weaken echo-false
438-
-- as the formal certificate. We can lift this to "Mode is not
439-
-- non-loss-only" — i.e., Mode does not satisfy NonLossOnly.
440-
--
441-
-- However: NonLossOnly only requires the EXISTENCE of *some* strict
442-
-- step with a distinguishing pair. Mode has only one strict step
443-
-- (linear≤affine), and we need to show it has no distinguishing
444-
-- pair. This requires examining all pairs of inputs in
445-
-- LEcho linear and showing they all map to equal outputs under
446-
-- weaken — which involves the universal property of LEcho linear.
447-
--
448-
-- This is straightforward but requires more machinery (LEcho's
449-
-- definition unfolds to Echo collapse tt; collapse-to-residue's
450-
-- behaviour on all such inputs; uniqueness of the residue).
451-
--
452-
-- Left as an open obligation in the abstract section. The concrete
453-
-- forward direction above (rolegraded-cell-action,
454-
-- rolemode-cell-action) does not depend on this abstract
455-
-- formalisation.
441+
-- Why `Mode-is-loss-only : ¬ NonLossOnly ModeAxis` cannot be proved
442+
-- as literally stated — and the sharpening that discharges it.
443+
--
444+
-- The flagged obligation was `¬ NonLossOnly ModeAxis`. That claim is
445+
-- FALSE under the `NonLossOnly` predicate above, and the file below
446+
-- proves it false rather than papering over the gap.
447+
--
448+
-- The defect is in `IsStrict`/`NonLossOnly`: a step counts as
449+
-- "strict" merely if it carries a distinguishing pair. But the
450+
-- *reflexive* steps `m ≤m m` transport by the identity
451+
-- (`degradeMode linear≤linear e = e` definitionally), and the
452+
-- identity trivially preserves distinguishability whenever the
453+
-- decoration has ≥2 separable inhabitants. So *every* axis with a
454+
-- multi-inhabitant decoration satisfies `NonLossOnly` via a
455+
-- reflexive step — the predicate is vacuously true and does not
456+
-- discriminate loss-only axes at all. `Mode` is no exception:
457+
-- `NonLossOnly-holds-vacuously-for-Mode` below exhibits the witness
458+
-- explicitly, which is exactly why `¬ NonLossOnly ModeAxis` is
459+
-- unprovable.
460+
--
461+
-- The rigorous fix is to SHARPEN the criterion to the intended
462+
-- reading (cf. ChoreoInjective.agda: "at least one of its strict
463+
-- (non-reflexive) steps"): a *proper* strict step must move between
464+
-- DISTINCT decorations. Under that sharpened predicate
465+
-- (`ProperNonLossOnly`):
466+
--
467+
-- * Choreo still certifies (c⊑s : Client ≢ Server, distinguishing
468+
-- transport) — the positive case is not lost.
469+
-- * Mode does NOT certify: its only inter-decoration step is
470+
-- linear≤affine, whose transport `weaken` lands in `LEcho affine`
471+
-- where `affine-all-equal` forces ALL outputs equal, so no
472+
-- distinguishing pair can exist. The reflexive steps are now
473+
-- excluded by the `distinct` requirement.
474+
--
475+
-- This discharges the abstract obligation in its defensible form:
476+
-- `Mode-is-not-proper-non-loss-only`. It does NOT affect the
477+
-- terminated-negative EI-2 verdict (see TERMINATION NOTICE / the
478+
-- EI-2 STATUS banners and docs/EI2_REPORT.adoc); it removes a
479+
-- residual proof-debt comment from the abstract section and
480+
-- sharpens the underlying criterion.
481+
------------------------------------------------------------------------
482+
483+
-- The original predicate is vacuously satisfied by Mode via the
484+
-- reflexive linear step. This is the concrete reason
485+
-- `¬ NonLossOnly ModeAxis` is FALSE (not merely "hard").
486+
ModeAxis : Axis
487+
ModeAxis = record
488+
{ D = Mode
489+
; _≤_ = _≤m_
490+
; F = LEcho
491+
; t = degradeMode
492+
}
493+
494+
mode-linear-reflexive-strict : IsStrict ModeAxis linear≤linear
495+
mode-linear-reflexive-strict = record
496+
{ x = echo-true
497+
; y = echo-false
498+
; x≢y = echo-true≢echo-false
499+
; tx≢ty = echo-true≢echo-false
500+
}
501+
502+
NonLossOnly-holds-vacuously-for-Mode : NonLossOnly ModeAxis
503+
NonLossOnly-holds-vacuously-for-Mode =
504+
linear , linear , linear≤linear , mode-linear-reflexive-strict
505+
506+
------------------------------------------------------------------------
507+
-- Sharpened criterion: a *proper* strict step moves between DISTINCT
508+
-- decorations. This excludes reflexive identity steps, which carry
509+
-- no information-preserving transport content of their own.
510+
------------------------------------------------------------------------
511+
512+
record ProperlyStrict (a : Axis) {d1 d2 : Axis.D a}
513+
(le : Axis._≤_ a d1 d2) : Set where
514+
open Axis a
515+
field
516+
distinct : d1 ≢ d2
517+
x y : F d1
518+
x≢y : x ≢ y
519+
tx≢ty : t le x ≢ t le y
520+
521+
ProperNonLossOnly : Axis Set
522+
ProperNonLossOnly a =
523+
Σ (Axis.D a) (λ d1
524+
Σ (Axis.D a) (λ d2
525+
Σ (Axis._≤_ a d1 d2) (λ le
526+
ProperlyStrict a le)))
527+
528+
------------------------------------------------------------------------
529+
-- The sharpening keeps the positive case: Choreo still certifies,
530+
-- now via the genuinely proper step c⊑s (Client ≢ Server).
531+
------------------------------------------------------------------------
532+
533+
ChoreoAxis-proper-non-loss-only : ProperNonLossOnly ChoreoAxis
534+
ChoreoAxis-proper-non-loss-only =
535+
Client , Server , c⊑s , record
536+
{ distinct = λ ()
537+
; x = rg-input₁
538+
; y = rg-input₂
539+
; x≢y = rg-inputs-distinct
540+
; tx≢ty = rg-images-distinct
541+
}
542+
543+
------------------------------------------------------------------------
544+
-- The discharged obligation: Mode is loss-only under the sharpened
545+
-- (proper-step) criterion. Case analysis on the mode order:
546+
--
547+
-- * linear≤linear / affine≤affine — reflexive; `distinct` is
548+
-- `m ≡ m → ⊥`, refuted by `refl`.
549+
-- * linear≤affine — the unique inter-decoration step; its
550+
-- transport `degradeMode linear≤affine = weaken` lands in
551+
-- `LEcho affine`, where `affine-all-equal` makes every pair of
552+
-- outputs equal, contradicting `tx≢ty`.
456553
------------------------------------------------------------------------
457554

458-
-- Mode-is-loss-only : ¬ NonLossOnly ModeAxis
459-
-- ^^^ open obligation; requires more LEcho machinery.
555+
Mode-is-not-proper-non-loss-only : ProperNonLossOnly ModeAxis
556+
Mode-is-not-proper-non-loss-only
557+
(linear , linear , linear≤linear , ps) = ProperlyStrict.distinct ps refl
558+
Mode-is-not-proper-non-loss-only
559+
(affine , affine , affine≤affine , ps) = ProperlyStrict.distinct ps refl
560+
Mode-is-not-proper-non-loss-only
561+
(linear , affine , linear≤affine , ps) =
562+
ProperlyStrict.tx≢ty ps
563+
(affine-all-equal
564+
(degradeMode linear≤affine (ProperlyStrict.x ps))
565+
(degradeMode linear≤affine (ProperlyStrict.y ps)))
460566

461567
------------------------------------------------------------------------
462568
-- Summary (prose; the formal content is above)

0 commit comments

Comments
 (0)