hygiene: per-lemma Smoke pins for EchoApprox via concrete instance module#71
Merged
Merged
Conversation
…dule
Closes a silent violation of the CLAUDE.md "Working rules" invariant
("Every headline theorem must be pinned in Smoke.agda via using clause")
for parameterised modules. EchoApprox.Approx lemmas could not be named
in Smoke.agda until some PseudoMetric was supplied; PR #70 (Lane C of
the multi-lane swarm) added the retract-direction lemmas but, following
existing convention, left them unpinned for the same reason. This PR
closes the gap with the smallest, most honest possible instance.
Instance chosen: the trivial / collapse-to-strict pseudometric on the
unit carrier ⊤.
* Tol := ⊤, zero := tt, _+_ := λ _ _ → tt
* _≤_ := λ _ _ → ⊤
* dist := λ _ _ → tt on B := ⊤
Every order / monotonicity / triangle obligation discharges to tt.
Every approximate echo collapses to Σ A (λ _ → ⊤), so each pinned
lemma is a proof-of-life sanity check that the parameterised module's
term is well-typed at *some* instance — exactly the hygiene contract
the invariant asks for. No new mathematical content. When a genuine
metric instance lands in the repo, the per-lemma pins can be re-pointed
at it.
Headlines now pinned in Smoke.agda (9 names):
* approx-EchoR (= EchoR)
* approx-intro (= echo-approx-intro)
* approx-strict→approx (= echo-strict→approx)
* approx-relax (= echo-approx-relax)
* approx-NonExpansive (= NonExpansive)
* approx-compose (= echo-approx-compose)
* approx-comp-sound (= echo-approx-comp-sound)
* approx-comp-retract-to (= echo-approx-comp-retract-to)
* approx-comp-retract-A (= echo-approx-comp-retract-A)
Plus the instance constructors trivialTolerance, trivialPseudoMetric.
Build verified in parent session (sandbox quirk denied positional-
argument agda invocations in this worktree):
$ LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/All.agda
exit: 0
$ LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/Smoke.agda
exit: 0
--safe --without-K invariants intact. No postulates, no funext, no
path algebra — every field is tt or refl.
Refs PR #70 (Lane C surfaced the gap).
Refs CLAUDE.md "Working rules" invariant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
6 tasks
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
…dow (#74) ## Summary Picks up two of three §7 deferrals from PR #70 in `/tmp/echo-types-exploration/axis2-approximate.md`. Refs not Closes because §7 is multi-rung and one rung (B-component + tolerance-budget retract round-trip) stays deferred pending a `Tolerance` interface design call (see below). ## Rungs landed ### Rung A — separated zero-collapse (§7 #7) - `Separated : Set` — separation predicate on the pseudo-metric: `∀ b₁ b₂ → dist b₁ b₂ ≤ zero → b₁ ≡ b₂`. Kept out of the `PseudoMetric` record; supplied as an explicit hypothesis at the lemma site (pseudo-metrics in general only guarantee `dist y y ≡ zero`, not the converse — making them a *metric proper* is an optional refinement the record deliberately does not bake in). - `echo-approx-zero-collapses-strict : Separated → EchoR zero f y → Echo f y` formalises the §4 "Approximate → strict (only when separated, at ε = 0)" statement. ### Rung B — axis-1 shadow agreement (§7 #8) - `echo-shadow-A` — A-component projection (axis-1 shadow of an approximate echo). - `echo-shadow-iso-{to,from}` — pins the §7 #8 obligation explicitly (definitional both ways: `EchoR ε f y` IS the existential `Σ A (λ x → dist (f x) y ≤ ε)`). - `echo-strict→approx-shadow-A` — cross-axis cohere: the A-component of `echo-strict→approx` agrees with the strict A-component on the nose (`refl`). - `echo-strict→approx-collapse-shadow-A` — round-trip under separation: `zero-collapses-strict ∘ strict→approx ≡ id` on the A-component, definitionally. ## DESIGN-DECISION STOP — Rung C deferred The full B-component + tolerance-budget retract round-trip (`echo-approx-comp-retract-from-to` and friends) requires a `+`-left-identity axiom on `Tolerance` (`zero + ε ≡ ε`, plus right-identity for the symmetric variants). ### Current shape of `Tolerance` ```agda record Tolerance ℓ : Set (suc ℓ) where field Tol : Set ℓ zero : Tol _+_ : Tol → Tol → Tol _≤_ : Tol → Tol → Set ℓ ≤-refl : ∀ {ε} → ε ≤ ε ≤-trans : ∀ {ε₁ ε₂ ε₃} → ε₁ ≤ ε₂ → ε₂ ≤ ε₃ → ε₁ ≤ ε₃ +-mono-≤ : ∀ {a b c d} → a ≤ b → c ≤ d → (a + c) ≤ (b + d) ``` No identity laws on `+`. Minimal interface, lets us state `echo-approx-compose`; that's all it currently does. ### What needs to be added For the symmetric retract round-trip: ```agda +-identityˡ : ∀ {ε} → (zero + ε) ≡ ε +-identityʳ : ∀ {ε} → (ε + zero) ≡ ε ``` (`≡`, not `≤` — the round-trip is a definitional retract on the tolerance budget, so we need a propositional equality, not just mutual `≤`.) ### Two options **(a)** Extend `Tolerance` with the two identity-law fields. - Pro: minimal scaffolding; one type to thread through. - Con: ripples to every `Tolerance` instance — currently just `EchoApproxInstance.trivialTolerance` (trivial discharge), but consumers may grow. Makes `Tolerance` strictly stronger than the "ordered commutative-monoid-flavoured" framing in §3 of the axis-2 design note. **(b)** Add a separate `BalancedTolerance` record on top of `Tolerance` carrying just the identity laws. - Pro: additive; no interface breakage; layered/opt-in. Matches the design pattern of `PseudoMetric` (which is *separately* refined to a metric by adding `Separated`, not by widening the base record). Keeps the §3 "minimal moving parts" promise. - Con: an extra record name to thread through retract-round-trip lemmas. ### Recommendation **(b).** The current `Tolerance` is deliberately the minimal interface that lets us state `echo-approx-compose` (triangle + additive monotonicity, nothing else). Identity laws are needed only by the retract round-trip, which is a downstream refinement — keeping them out of the core interface preserves the "minimal moving parts" design from §3 of the axis-2 design note. The analogue is `PseudoMetric` vs. (`PseudoMetric` + `Separated`): the refinement lives outside the base record. Rung C is deferred pending owner decision. ## Rung D — also deferred The Lipschitz generalisation `L_g ≠ 1` would need scalar multiplication on `Tolerance` — a third interface call (whether to add it to the core record, or layer a `ScalableTolerance` refinement). Deferred alongside Rung C; same recommendation shape applies. ## Hygiene All new headlines pinned via the per-lemma proof-of-life pattern from PR #71: `EchoApproxInstance.agda` adds top-level identifiers at the trivial-pseudometric-on-`⊤` instance, `Smoke.agda` enumerates them in its `using` clause. ## Verification ``` $ agda -i proofs/agda proofs/agda/All.agda # exit 0 $ agda -i proofs/agda proofs/agda/Smoke.agda # exit 0 ``` `--safe --without-K` throughout. No postulates. No escape pragmas. No funext. ## Refs - PR #70 (retract direction) - `/tmp/echo-types-exploration/axis2-approximate.md` §7 Refs not Closes — §7 obligations 7 and 8 are landed, but obligation 6's "full retract round-trip" (Rung C) and the Lipschitz generalisation remain. ## Test plan - [x] `agda proofs/agda/All.agda` exits 0 - [x] `agda proofs/agda/Smoke.agda` exits 0 - [x] No postulates / escape pragmas / funext introduced - [x] All new headlines pinned in `Smoke.agda` via `EchoApproxInstance` - [ ] Owner decides Rung C `Tolerance` interface question (a vs. b) - [ ] After decision: implement chosen option, land full retract round-trip 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
…eferred) (#75) ## Summary Extends `proofs/agda/EchoAccess.agda` (the PR #68 thin slice) with the join structure and per-decoration composition trio, completing the same recipe as `EchoGraded` and `EchoLinear` at the per-decoration composition rung. **Rung A — categorical join structure.** `_⊔a_` (componentwise max along `free ≤ decidable ≤ enum ≤ feasible ≤ infeasible`) + `≤a-⊔a-left` + `≤a-⊔a-right` + `≤a-⊔a-univ` (universal property). **Rung B — per-decoration composition trio.** * `degrade-access-comp` — two successive degrades along a factoring agree with one degrade along the composed proof. Closes `refl` on every reachable `(p12, p23)` constructor pair (the carriers reduce in lock-step with `≤a-trans`). * `degrade-access-compose` — factoring-free composition; corollary of `degrade-access-comp` + `≤a-prop`. * `degrade-access-via-join` — same law restated through the join. **Rung C — honest carriers — deferred with design note.** An honest `enum`-grade carrier needs an enumerator `Fin n → A` and a decider on `B`. Neither can be supplied without breaking the parametricity over `A` that `Echo f y` enjoys at the `free` grade. The two clean resolutions are (a) parameterise the whole `CEcho` family on `Decidable B` + an enumeration witness (forces every caller to supply them, even at `free` where they do nothing), or (b) bury both in an existential inside the `enum` / `feasible` / `infeasible` cases (loses the ability to extract from outside). Both are real architectural choices — the PR brief's Stop-condition explicitly flagged this as the design-decision case and instructed landing A + B with a written deferral. Importantly, the composition layer that lands here is **grade-indexed not carrier-indexed**, so it is unaffected by the eventual carrier choice. Module preamble carries the full deferral note. All new headlines pinned in `Smoke.agda`. Module preamble section list refreshed; `degrade-access` follow-up commentary updated. No new imports beyond `sym` from `Relation.Binary.PropositionalEquality`. No postulates. `--safe --without-K` preserved throughout. ## Build status **BUILD UNVERIFIED LOCALLY** — the sandbox repeatedly blocked `agda` invocations on positional file arguments (the known quirk that hit PRs #71 + #72). Parent session will verify (`LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/All.agda` and same for `Smoke.agda`, both expected to exit 0) and post a confirmation comment. The mathematical content is mechanical mirror of `EchoGraded.{degrade-comp, degrade-compose, degrade-via-join, ⊔g, ≤g-⊔g-*}` (with 5 grades instead of 3) and `EchoLinear.{degradeMode-comp, degradeMode-compose, degradeMode-via-join, ⊔m, ≤m-⊔m-*}` (with 5 grades instead of 2). Every clause closes `refl` modulo the `≤a-trans` reduction table that already ships in PR #68. ## Refs Refs PR #68 (the thin slice), `docs/echo-types/roadmap.md` Axis 8 entry, `/tmp/echo-types-exploration/axis8.md` §5 deferred list. ## Test plan - [ ] `LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/All.agda` exits 0. - [ ] `LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/Smoke.agda` exits 0. - [ ] No postulates / no escape pragmas / `--safe --without-K` preserved. - [ ] All seven new headline names resolve in `Smoke.agda`. Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
Lands the deferred Rung C from PR #74 / axis-2 design-note §7 via option (b) of the post-#74 design call: a separate `BalancedTolerance` record layered on `Tolerance` (mirroring how `Separated` is layered on `PseudoMetric`), NOT a mutation of the base `Tolerance` interface. Landed: * `BalancedTolerance T` record — `+-identityˡ : ∀ ε → zero + ε ≡ ε` and `+-identityʳ : ∀ ε → ε + zero ≡ ε`. Base `Tolerance` interface untouched. * `echo-approx-comp-retract-B` — B-component pin: the canonical-split section picks `b := f x` definitionally (`refl`; no BT needed). * `echo-approx-comp-retract-budget` — budget round-trip: `(zero + ε) ≡ ε` from `BalancedTolerance.+-identityˡ`. * `echo-approx-comp-retract-from-to` — budget-aligned A-component round-trip: `proj₁ (subst _ (+-identityˡ ε) (sound (retract-to e))) ≡ proj₁ e`, via the `subst-A-invariant` auxiliary. * `trivialBalancedTolerance` pin in `EchoApproxInstance.agda` (both identity laws discharge to `refl` on `Tol := ⊤`) and the four new per-lemma headlines pinned through `Smoke.agda` per the PR-#71 hygiene pattern. * `docs/echo-types/composition.md` §Q3 refreshed: option-(b) design cited, new round-trip lemmas enumerated, leftover deferred work (Lipschitz; transported full equality needing `_≤_`-propositionality) re-stated honestly. The full transported equality `subst _ (+-identityˡ ε) (sound (retract-to e)) ≡ e` is NOT discharged — it would require propositionality of the order `_≤_` on the inner bound, which the `Tolerance` interface deliberately does not assert. The A-component statement above is the strongest available without that extra structural hypothesis; this is noted in the file header, module preamble, and `composition.md`. Agda status. `EchoApprox.agda` + `EchoApproxInstance.agda` typecheck clean on Agda 2.8.0 (both `.agdai` produced from a clean cache). `proofs/agda/Smoke.agda` itself cannot be driven to exit 0 in this sandbox because of a pre-existing baseline-rot error in `proofs/agda/EchoAccess.agda:400` on origin/main (Agda 2.8 stricter unification rejects a `decidable ⊔a enum` reduction landed in PR \#75; unrelated to this change). CI is expected to run on the pinned stdlib v2.3 + apt-shipped older Agda where that reduction still goes through. Refs PR #74, /tmp/echo-types-exploration/axis2-approximate.md §7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
…rip (#78) ## Summary Lands the deferred Rung C from PR #74 / axis-2 design-note §7 via the post-#74 design decision — **option (b)**: a separate `BalancedTolerance` record layered on `Tolerance` (mirroring how `Separated` is layered on `PseudoMetric`), **NOT** a mutation of the base `Tolerance` interface. ## Landed - `BalancedTolerance T` record — `+-identityˡ : ∀ ε → zero + ε ≡ ε` and `+-identityʳ : ∀ ε → ε + zero ≡ ε`. The base `Tolerance` interface stays untouched. - `echo-approx-comp-retract-B` — B-component pin: the canonical-split section picks `b := f x` definitionally (`refl`; no `BT` needed). - `echo-approx-comp-retract-budget` — budget round-trip: `(zero + ε) ≡ ε` from `BalancedTolerance.+-identityˡ`. - `echo-approx-comp-retract-from-to` — budget-aligned A-component round-trip: `proj₁ (subst _ (+-identityˡ ε) (sound (retract-to e))) ≡ proj₁ e`, via a small `subst-A-invariant` auxiliary. - `trivialBalancedTolerance` instance in `EchoApproxInstance.agda` (both identity laws discharge to `refl` on `Tol := ⊤`) plus the four new per-lemma headlines pinned through `Smoke.agda` per the PR #71 hygiene pattern. - `docs/echo-types/composition.md` §Q3 refreshed: option-(b) design cited, new round-trip lemmas enumerated, leftover deferred work re-stated honestly. ## Out of scope (still deferred) The full transported equality `subst _ (+-identityˡ ε) (sound (retract-to e)) ≡ e` is **not** discharged here — it would require propositionality of `_≤_` on the inner bound, which `Tolerance` deliberately does not assert. The A-component statement above is the strongest available without that extra structural hypothesis; documented in the file header, module preamble, and `composition.md`. The Lipschitz generalisation (`L_g ≠ 1`) is still deferred — it needs multiplication on `Tolerance`, an orthogonal interface call. ## Agda status - `EchoApprox.agda` + `EchoApproxInstance.agda` typecheck clean on Agda 2.8.0 (both `.agdai` produced from a clean cache in the worktree sandbox). - `proofs/agda/Smoke.agda` itself **cannot** be driven to exit 0 in this sandbox because of a pre-existing baseline-rot error at `proofs/agda/EchoAccess.agda:400` on `origin/main` (Agda 2.8 stricter unification rejects a `decidable ⊔a enum` reduction landed in #75; unrelated to this change). CI runs on the apt-shipped older Agda + pinned stdlib v2.3 where that reduction still goes through — the green CI signal here is the merge oracle. ## Test plan - [ ] CI (`agda.yml`) green on the `theory/echo-approx-balanced-tolerance` branch with `--safe --without-K`, no postulates. - [ ] `agda proofs/agda/All.agda` and `agda proofs/agda/Smoke.agda` both exit 0 on CI. - [ ] Verify the four new headline pins (`approx-comp-retract-B`, `approx-comp-retract-budget`, `approx-comp-retract-from-to`, `approx-subst-A-invariant`) appear in `Smoke.agda` and resolve against `EchoApproxInstance`. ## References - Builds on / refs PR #74 (Rung B; `Separated` layer + `echo-strict→approx` + axis-1 shadow), PR #71 (per-lemma Smoke pins via instance module). - Closes the Rung-C portion of `/tmp/echo-types-exploration/axis2-approximate.md` §7 obligations (B-component + budget round-trip). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
that referenced
this pull request
May 20, 2026
Adds `proofs/agda/EchoCost.agda` (and `EchoCostInstance.agda` for smoke pins), the cost-indexed refinement of `Echo` named in `docs/echo-types/taxonomy.md` §Axis 8 (refinement 1: full cost-tracking via an explicit cost algebra). Sits orthogonal to the already-landed qualitative Axis-8 artefacts (`EchoDecidable`, `EchoFiberCount`, `EchoAccess`); names the resource-budget dimension of the axis. ## What lands - `CostAlgebra` — ordered commutative-monoid-flavoured cost carrier (`Cost`, `zero`, `_+_`, `_≤_`, `≤-refl`, `≤-trans`, `+-identityˡ`, `+-mono-≤`). Right-identity / associativity / commutativity deliberately omitted — the headlines close without them; layering pattern matches `BalancedTolerance` in `EchoApprox.agda`. - `EchoC cost c f y := Σ A (λ x → f x ≡ y × cost x ≤ c)` - Headlines: - `echo-cost-intro` / `-≤` — zero-budget intro - `echo-cost-relax` — monotone in budget - `echo-cost-forget` — Axis-8 → Axis-1 projection (the shadow obligation of every Axis-8 refinement) - `echo-cost-compose` — two-source additive composition (combiner + image-equation + cost-receipt triple, no funext) - `echo-cost-compose-mono` — single-source specialisation - `echo-cost-forget-compose-mono-A` — compose-then-forget agrees with the bare composite on the A-component - `echo-cost-relax-zero` — `(zero + c) ≡ c` (the budget lever) - Wired into `All.agda` (alphabetical, between `EchoApproxInstance` and `EchoIndexed`) and `Smoke.agda` (per-lemma `using` clause on `EchoCostInstance`, mirroring the `EchoApproxInstance` pattern). ## Design judgement calls - **`CostAlgebra` field minimality.** Took only the laws needed to close the four headlines (`+-identityˡ` for the budget round-trip, `+-mono-≤` for compose). Right-identity / commutativity / associativity belong on a separate `BalancedCostAlgebra` record if a downstream proof needs them — same layering as `BalancedTolerance`. - **Composition shape (`echo-cost-compose`).** Took the more general two-source first-order shape with an explicit `combine : A → B → A''`, caller-supplied `image-eq`, and caller-supplied `cost-bound`. Strictly more general than restricting to an endomorphic outer leg (the `EchoApprox.echo-approx-compose` shape, `g : B → B`); the single-source corner falls out as `echo-cost-compose-mono`. No funext used; image equation is supplied, not derived from a pointwise homotopy. - **Trivial-on-⊤ instance via `EchoCostInstance.agda`.** Closes the CLAUDE.md "Working rules" invariant for parameterised modules (`EchoCost.Cost` is parameterised over `K : CostAlgebra ℓ`). Exact recipe of `EchoApproxInstance.agda` post-PR-#71. ## Invariants - `--safe --without-K` on every new module - No postulates, no funext, no escape pragmas, no `believe_me` - Clean-worktree Agda build green: `EchoCost.agda` + `EchoCostInstance.agda` + `All.agda` + `Smoke.agda` all exit 0 (verified after `find . -name '*.agdai' -delete`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 10 issues detected
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": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in secret-scanner.yml",
"type": "missing_workflow",
"file": "secret-scanner.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action actions/cache@v4 needs attention",
"type": "unpinned_action",
"file": "agda.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "No dependabot.yml or renovate.json found in echo-types",
"type": "DependencyUpdate",
"file": "/home/runner/work/echo-types/echo-types",
"action": "auto_fix",
"rule_module": "scorecard",
"severity": "high",
"remediation": "Add .github/dependabot.yml or renovate.json configuration.",
"scorecard_check": "Dependency-Update-Tool"
},
{
"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": "1 workflow(s) with tag-pinned (not SHA-pinned) actions in echo-types",
"type": "DependencyPinning",
"file": "/home/runner/work/echo-types/echo-types",
"action": "auto_fix",
"rule_module": "scorecard",
"severity": "medium",
"remediation": "Pin GitHub Actions and Docker base images by SHA hash.",
"scorecard_check": "Pinned-Dependencies"
},
{
"reason": "Repository has 1 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes a silent violation of the CLAUDE.md "Working rules" invariant — "Every headline theorem must be pinned in
Smoke.agdaviausingclause" — for parameterised modules.EchoApprox.Approxlemmas could not be named inSmoke.agdauntil somePseudoMetricwas supplied, so the invariant has been quietly skipped for everyecho-approx-*andecho-strict→approxlemma. PR #70 (Lane C of the multi-lane swarm) added the retract-direction lemmas (echo-approx-comp-sound,echo-approx-comp-retract-to,echo-approx-comp-retract-A) but, following existing convention, left them unpinned for the same reason. This PR closes the gap with the smallest, most honest possible instance.Instance chosen: the trivial / collapse-to-strict pseudometric on the unit carrier
⊤.Tol := ⊤,zero := tt,_+_ := λ _ _ → tt_≤_ := λ _ _ → ⊤dist := λ _ _ → ttonB := ⊤Every order / monotonicity / triangle obligation discharges to
tt. Every approximate echo collapses toΣ A (λ _ → ⊤), so each pinned lemma is a proof-of-life sanity check that the parameterised module's term is well-typed at some instance — exactly the hygiene contract the invariant asks for. No new mathematical content. When a genuine metric instance lands in the repo, the per-lemma pins below can be re-pointed at it (this is option 1 of two candidates considered; option 2, a discrete metric overBool, adds nothing for the pinning purpose).Headlines now pinned in
Smoke.agda(9 names)Approxtermapprox-EchoREchoRapprox-introecho-approx-introapprox-strict→approxecho-strict→approxapprox-relaxecho-approx-relaxapprox-NonExpansiveNonExpansiveapprox-composeecho-approx-composeapprox-comp-soundecho-approx-comp-soundapprox-comp-retract-toecho-approx-comp-retract-toapprox-comp-retract-Aecho-approx-comp-retract-APlus the instance constructors
trivialTolerance,trivialPseudoMetric.Build status
Verified in the parent session (a sandbox quirk in this worktree denied positional-argument
agdainvocations despite project.claude/settings.jsonallowing them; the call worked from the parent):--safe --without-Kinvariants intact (Agda would have errored otherwise). No postulates, no funext, no path algebra — every field isttorrefl.Files
proofs/agda/EchoApproxInstance.agda(instance + 9 per-lemma re-bindings)proofs/agda/All.agda(oneopen importline, keeps orphan-module-as-dead-code rule satisfied)proofs/agda/Smoke.agda(per-lemmausingclause adjacent to the existingApproxblock)Refs
Smoke.agdaviausingclause."Test plan
LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/All.agdaexits 0 under--safe --without-K(verified parent session)LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/Smoke.agdaexits 0 under--safe --without-K(verified parent session)--safeweakening or escape pragmasCo-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com