Skip to content

hygiene: per-lemma Smoke pins for EchoApprox via concrete instance module#71

Merged
hyperpolymath merged 2 commits into
mainfrom
hygiene/smoke-per-lemma-pins-echo-approx
May 20, 2026
Merged

hygiene: per-lemma Smoke pins for EchoApprox via concrete instance module#71
hyperpolymath merged 2 commits into
mainfrom
hygiene/smoke-per-lemma-pins-echo-approx

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

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, so the invariant has been quietly skipped for every echo-approx-* and echo-strict→approx lemma. 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 := λ _ _ → 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 below can be re-pointed at it (this is option 1 of two candidates considered; option 2, a discrete metric over Bool, adds nothing for the pinning purpose).

Headlines now pinned in Smoke.agda (9 names)

New top-level name Underlying Approx term
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 status

Verified in the parent session (a sandbox quirk in this worktree denied positional-argument agda invocations despite project .claude/settings.json allowing them; the call worked from the parent):

$ 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 (Agda would have errored otherwise). No postulates, no funext, no path algebra — every field is tt or refl.

Files

  • New: proofs/agda/EchoApproxInstance.agda (instance + 9 per-lemma re-bindings)
  • Modified: proofs/agda/All.agda (one open import line, keeps orphan-module-as-dead-code rule satisfied)
  • Modified: proofs/agda/Smoke.agda (per-lemma using clause adjacent to the existing Approx block)

Refs

Test plan

  • LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/All.agda exits 0 under --safe --without-K (verified parent session)
  • LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/Smoke.agda exits 0 under --safe --without-K (verified parent session)
  • No new postulates introduced
  • No --safe weakening or escape pragmas
  • CI green on this branch

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

…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>
@hyperpolymath hyperpolymath marked this pull request as ready for review May 20, 2026 14:13
@hyperpolymath hyperpolymath merged commit 0a83258 into main May 20, 2026
@hyperpolymath hyperpolymath enabled auto-merge (squash) May 20, 2026 14:13
@hyperpolymath hyperpolymath deleted the hygiene/smoke-per-lemma-pins-echo-approx branch May 20, 2026 14:13
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>
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>
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>
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 10 issues detected

Severity Count
🔴 Critical 0
🟠 High 5
🟡 Medium 5
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

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