Skip to content

feat: echo-approx-compose-lipschitz — Rung D (Lipschitz composition)#252

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/echo-approx-lipschitz
Jun 20, 2026
Merged

feat: echo-approx-compose-lipschitz — Rung D (Lipschitz composition)#252
hyperpolymath merged 1 commit into
mainfrom
claude/echo-approx-lipschitz

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What

Closes Rung D (Lipschitz composition) that EchoApprox.agda deferred — generalising approximate-echo composition from a non-expansive outer leg (L = 1) to a Lipschitz leg with constant L.

How

The module's own note: "Rung D … requires multiplication on Tolerance, another interface call." Per your "do both", I resolved that interface call in favour of the repo's established pattern — a layered opt-in record, exactly like BalancedTolerance / Separated, leaving the base Tolerance minimal:

record LipschitzScale (T : Tolerance ℓ) where
  field _*_ : Tol  Tol  Tol
        *-monoʳ :  {s a c}  a ≤ c  (s * a) ≤ (s * c)

Then, in a Lipschitz (S : LipschitzScale T) sub-module of Approx:

IsLipschitz L g =  b₁ b₂  dist (g b₁) (g b₂) ≤ (L * dist b₁ b₂)

echo-approx-compose-lipschitz :
  IsLipschitz L g  EchoR ε₁ f b  dist (g b) y ≤ ε₂ 
  EchoR ((L * ε₁) + ε₂) (g ∘ f) y

Same triangle + accumulate skeleton as echo-approx-compose; the non-expansive step dist (g·)(g·) ≤ dist · · becomes the Lipschitz step ≤ L * dist · ·, and *-monoʳ carries the inner bound dist (f x) b ≤ ε₁ through the constant to L * ε₁. It recovers echo-approx-compose at the corner L * ε ≡ ε.

Minimal by design: only _*_ + right-monotonicity are needed; associativity/identity/distributivity are left to richer carriers.

Discipline

  • --safe --without-K, zero postulates.
  • Trivial- LipschitzScale instance + 2 pins in EchoApproxInstance (the parameterised-module Smoke-pinning pattern); header "Rung D deferred" note flipped to LANDED.
  • Verified on latest main: EchoApprox, EchoApproxInstance, Smoke.agda, All.agda all exit 0; kernel-guard.sh PASS (existing modules — no new module).

Context

This is gap 2-of-3 from the proof survey. Gap 3 (EchoSearch sequential composition) is next — it's a genuine product-search whose n₁ * n₂ bound provably requires a bound-dependent row-major pairing (DivMod), which I'm building now.

🤖 Generated with Claude Code

https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We


Generated by Claude Code

EchoApprox's composition handled only a non-expansive outer leg (L=1). Rung D
generalises to a Lipschitz leg with constant `L` via a new layered
`LipschitzScale` record (multiplication on `Tolerance` + right-monotonicity
`a ≤ c ⇒ s * a ≤ s * c`), mirroring the `BalancedTolerance` / `Separated`
opt-in-record pattern — the base `Tolerance` stays minimal so lop-sided
carriers remain instances. A Lipschitz outer leg scales the inner tolerance
by `L`:

  IsLipschitz L g = ∀ b₁ b₂ → dist (g b₁) (g b₂) ≤ L * dist b₁ b₂
  echo-approx-compose-lipschitz : IsLipschitz L g → EchoR ε₁ f b →
      dist (g b) y ≤ ε₂ → EchoR (L * ε₁ + ε₂) (g ∘ f) y

Same triangle + accumulate skeleton as `echo-approx-compose`, with the
non-expansive step `dist (g·)(g·) ≤ dist · ·` replaced by the Lipschitz step
`≤ L * dist · ·` and `*-monoʳ` carrying the inner bound through the constant.
Recovers `echo-approx-compose` at the corner `L * ε ≡ ε`.

`--safe --without-K`, zero postulates. Trivial-⊤ `LipschitzScale` instance +
2 Smoke pins in `EchoApproxInstance` (the parameterised-module pinning
pattern); the header "Rung D deferred" note flipped to LANDED. EchoApprox +
EchoApproxInstance + Smoke.agda + All.agda exit 0; kernel-guard PASS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 6 issues detected

Severity Count
🔴 Critical 0
🟠 High 3
🟡 Medium 3
View findings
[
  {
    "reason": "No test directory or test files found",
    "type": "no_tests",
    "file": "/home/runner/work/echo-types/echo-types",
    "action": "flag",
    "rule_module": "honest_completion",
    "severity": "high",
    "deduction": 20
  },
  {
    "reason": "Nominal-only SAST in echo-types: codeql.yml language matrix contains no language present in the repo and lacks `actions`, so CodeQL records zero results on every commit. Remediation: set the CodeQL matrix to `language: actions`.",
    "type": "StaticAnalysis",
    "file": "/home/runner/work/echo-types/echo-types",
    "action": "auto_fix",
    "rule_module": "scorecard",
    "severity": "medium",
    "remediation": "Add CodeQL or equivalent SAST workflow.",
    "scorecard_check": "SAST"
  },
  {
    "reason": "Repository has 6 non-main remote branch(es). Policy: single main branch only.",
    "type": "GS007",
    "file": ".",
    "action": "delete_remote_branches",
    "rule_module": "git_state",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Scorecard): TokenPermissionsID -- Token-Permissions -- 18 day(s) old [STALE]",
    "type": "CSA001",
    "file": ".github/workflows/scorecard.yml",
    "action": "escalate",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  },
  {
    "reason": "Code-scanning alert TokenPermissionsID (high) at .github/workflows/scorecard.yml is 18 days old (threshold: 7 days) -- overdue for remediation",
    "type": "CSA003",
    "file": ".github/workflows/scorecard.yml",
    "action": "escalate",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  },
  {
    "reason": "Code-scanning alert hypatia/code_safety/agda_postulate dismissed as 'false positive' -- ensure dismissal is documented and justified",
    "type": "CSA004",
    "file": "proofs/agda/EchoImageFactorizationPropPostulated.agda",
    "action": "review",
    "rule_module": "code_scanning_alerts",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath marked this pull request as ready for review June 20, 2026 19:53
@hyperpolymath hyperpolymath merged commit 7603e72 into main Jun 20, 2026
19 checks passed
@hyperpolymath hyperpolymath deleted the claude/echo-approx-lipschitz branch June 20, 2026 19:54
hyperpolymath added a commit that referenced this pull request Jun 20, 2026
…sition (#254)

## What

Closes the **last** "where next" gap in `EchoSearch` — product
(sequential) composition of bounded searches. This is gap 3-of-3 from
the proof survey (decidability #251 and Lipschitz #252 already merged).

## The correction

The module's original sketch — `EchoS … f b n₁ → EchoS … g y n₂ → EchoS
… (g ∘ f) y (n₁ * n₂)` — is **ill-typed**: the second search produces a
`g`-preimage of `y` over its *own* enumerator, with no tie to the first
search's output `b`, so `g (f x) ≡ y` doesn't follow. The well-typed
composition is the **product** of two independent searches:

```agda
productEnum n₂ enum₁ enum₂ k = (enum₁ (k / n₂) , enum₂ (k % n₂))

echo-search-product :
  EchoS enum₁ f₁ y₁ n₁ → EchoS enum₂ f₂ y₂ n₂ →
  EchoS (productEnum n₂ enum₁ enum₂) (productMap f₁ f₂) (y₁ , y₂) (n₁ * n₂)
```

## How (the row-major pairing)

The witness pairs the two step indices as `k₂ + k₁ * n₂`:
- **bound** `< n₁ * n₂`: `k₂ + k₁*n₂ < n₂ + k₁*n₂ = suc k₁ * n₂ ≤ n₁ *
n₂` (`+-monoˡ-<` then `*-monoˡ-≤`);
- **recovery**: `/ n₂ ≡ k₁` (`+-distrib-/-∣ʳ` + `m*n/n≡m` + `m<n⇒m/n≡0`)
and `% n₂ ≡ k₂` (`[m+kn]%n≡m%n` + `m<n⇒m%n≡m`).

The `n₁ * n₂` budget **provably requires** this budget-dependent pairing
— a global `ℕ × ℕ ↔ ℕ` cannot keep `pair (n₁-1) (n₂-1) < n₁ * n₂` —
which is exactly why it divides by `n₂` and carries `NonZero n₂` (a
zero-width second dimension admits no witness anyway). That's the
bijection the module deferred "to the slice that wants it".

## Discipline

- `--safe --without-K`, **zero postulates**, structural.
- 3 Smoke pins (`productMap`, `productEnum`, `echo-search-product`); the
"where next" note marked LANDED with the ill-typed-sketch correction.
- **Verified on latest `main`:** `EchoSearch`, `Smoke.agda`, `All.agda`
all exit 0; `kernel-guard.sh` PASS (existing module — no new module).

## Context

This is the **final** gap from the proof-surface survey. With it, the
echo-types proof surface is gap-free apart from the deliberately
**parked** ordinal/fidelity ladder and the author-driven Pillar E paper.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We

---
_Generated by [Claude
Code](https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We)_

Co-authored-by: Claude <noreply@anthropic.com>
hyperpolymath pushed a commit that referenced this pull request Jun 21, 2026
…rdinal-contradiction flag

Catches the machine ledger up to the gap-closing proofs that landed
without an arc (#249 EchoReversibilityBridge, #250 EchoResidueCell,
#251/#254 EchoSearch decidable+product, #252 EchoApprox Lipschitz,
#257 EchoLLEncoding universal gap, #258 proof-debt variance refresh),
records the cross-repo (echo-types + 007) docs-completeness audit, and
flags one unresolved owner decision: main carries ordinal BH climb
rungs 7 & 8 (f89a3aa, a096764) dated 2026-06-21 — the same day as the
D-2026-06-21 retirement — contradicting the retirement banner. The two
ordinal wiki files are deliberately left un-fixed pending that
reconciliation. Disposition: both repos clean/verified, push-nothing-else.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We
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.

2 participants