Skip to content

Commit c97d0c4

Browse files
committed
feat(aggregation): generalize EchoAggregation to monoid/group form (#175)
Generalize EchoAggregation from the macro-economics-specific module into the general monoid-aggregation form requested by #175 (the SQL GROUP-BY-as-monoid-homomorphism consumer in affinescript db-theory #3): * record Monoid (Elem/ε/_⊕_/assoc/identity-l/identity-r); * ⊕-fold + ⊕-fold-++ (fold is a monoid homomorphism over _++_); * record GroupAggregator (agg : V → Elem) + aggregate-values; * aggregation-as-fold — the #175 headline law, PROVED (not merely signed): aggregating a concatenation equals combining the aggregates; * sumMonoid / countMonoid / maxMonoid (ℕ) + minMonoid (Maybe ℕ, nothing = ∞) + a worked countAggregator; * no-canonical-disaggregation-of — generic non-disaggregability (any collision ⇒ no section, via no-section-of-collapsing-map); this also discharges #174's no-section sibling. The macro→micro economics reading survives mechanised as module Example-PairSum (pairSum : ℕ × ℕ → ℕ IS the sumMonoid fold — pairSum-is-fold — so it is an instance of the general form, nothing re-proved or lost): pairSum-non-injective + no-canonical-disaggregation (the Sonnenschein–Mantel–Debreu / representative-agent critique type-theoretically). oikos reads that instance at macro scale under the name MacroAggregation, cited back here. --safe --without-K, zero postulates, kernel-guard PASS; All.agda + Smoke.agda exit 0. Smoke pins + MAP.adoc + echo-kernel-note.adoc + cross-repo-bridge-status.md swept to the general/macro split. Refs #175, #174 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VwbFNQJw23tW8tqM7utWku
1 parent 879ec9b commit c97d0c4

6 files changed

Lines changed: 392 additions & 170 deletions

File tree

CLAUDE.md

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,93 @@ work to `main` and refresh all documentation:
212212

213213
## Current rung state (2026-06-18)
214214

215-
### Session arc 2026-06-18 — EchoAggregation / oikos alib bridge (read this first)
215+
### Session arc 2026-06-18 — EchoAggregation general/macro split + long-form prose relicense (read this first)
216+
217+
*Where we started:* three housekeeping loose ends from the EchoAggregation /
218+
oikos-alib work. (1) stale branch `session/slice-4-narrowing` (a git-ancestor
219+
of `estate-standardization-20260607`, zero unique commits); (2) an
220+
owner-authorised prose relicensing (`f6cc023`) that never re-landed — 9
221+
long-form docs still `MPL-2.0` while the estate prose licence is
222+
`CC-BY-SA-4.0`; (3) a NAME COLLISION: the merged economics module (#230)
223+
squatted `EchoAggregation`, the name open issue **#175** wants for the
224+
*general* monoid/group aggregation (SQL GROUP-BY-as-fold; consumer =
225+
affinescript db-theory #3).
226+
227+
*User decision (the pivot):* echo-types' `EchoAggregation` becomes the
228+
GENERAL / fundamental form (serving #175); the MACRO economics reading moves
229+
to oikos under a distinct name + a context statement. Key fact making this
230+
loss-free: `pairSum (a,b) = a+b` IS literally the `sumMonoid` fold of a
231+
two-element list, so the macro result is just an *instance* of the general
232+
form — nothing is re-proved.
233+
234+
*Where we ended:* two echo-types commits on `claude/ecstatic-wright-OBEvx`
235+
(draft PR), plus an oikos doc commit (draft PR):
236+
237+
* **Commit A — `docs(licence): long-form prose → CC-BY-SA-4.0 (9 docs)`**
238+
(`879ec9b`). Header-line swap only (`SPDX-License-Identifier: MPL-2.0`
239+
`…: CC-BY-SA-4.0`) on `FOUNDATION_CONTRACT.md`, `docs/theorem-index.md`,
240+
`docs/CLAIMS_AUDIT.adoc`, `docs/echo-types/{fibration-package,universal-property}.adoc`,
241+
`wiki/{Architecture,Overview,Roadmap,Working-Rules}.adoc`. Copyright /
242+
`SPDX-FileCopyrightText` lines untouched. (Re-applies orig `f6cc023`.)
243+
244+
* **Commit B — `feat(aggregation): generalize EchoAggregation to monoid/group
245+
form (#175)`.** `proofs/agda/EchoAggregation.agda` rewritten:
246+
`record Monoid ℓ` (`Elem`/`ε`/`_⊕_`/`assoc`/`identity-l`/`identity-r`);
247+
`⊕-fold` + `⊕-fold-++` (fold-is-a-monoid-homomorphism over `_++_`);
248+
`record GroupAggregator {ℓ}(K V)(M)` (`agg : V → Elem`); `aggregate-values`
249+
+ the *proved* `aggregation-as-fold` law (#175's headline, by induction —
250+
no `map-++` needed); four instances `sumMonoid`/`countMonoid`/`maxMonoid`
251+
(ℕ,0,+ / + / ⊔) + `minMonoid` over `Maybe ℕ` (`nothing` = ∞, `_⊓∞_` with
252+
`⊓∞-assoc`/`⊓∞-identity-r`); `countAggregator`; generic
253+
`no-canonical-disaggregation-of` (= `no-section-of-collapsing-map`, also
254+
covers #174); and `module Example-PairSum` (the OLD macro `ℕ×ℕ→ℕ` ledger,
255+
neutrally framed: `pairSum-is-fold`, `pairSum-non-injective`,
256+
`no-canonical-disaggregation`) — the mechanised anchor oikos cites.
257+
`Smoke.agda` pins rewritten to the general headlines + a separate
258+
`open EchoAggregation.Example-PairSum using (…)` block. Docs swept:
259+
`echo-kernel-note.adoc` (Check B still PASS — name unchanged), `MAP.adoc`
260+
(general bullet, cites #175/#174), `docs/bridges/cross-repo-bridge-status.md`
261+
(bridge row + new revision entry: echo-types = general, oikos = macro).
262+
263+
* **oikos — `docs(alib): macro-aggregation reading cites the general
264+
EchoAggregation`.** `oikos/docs/alib-aggregate-bridge.adoc` extended with
265+
the macro reading + the context statement (it is the EchoAggregation of
266+
echo-types read at macro scale; named `MacroAggregation` here because
267+
aggregation is a fundamental there) + §8 pointer updated (macro is now an
268+
*instance* of the general form). NO Agda in oikos (Rust + AffineScript +
269+
Haskell); citation-level, per its own §8.
270+
271+
Build invariant held: `EchoAggregation.agda` + `All.agda` + `Smoke.agda`
272+
exit 0 under `--safe --without-K`, zero postulates, `kernel-guard.sh` PASS.
273+
274+
*Honest scope.* `aggregation-as-fold` is the fold's monoid-homomorphism law,
275+
NOT full SQL GROUP-BY operational semantics. `avg` is deliberately absent
276+
(not a monoid — express as `sum / count`, per #175).
277+
`no-canonical-disaggregation-of` refutes a *section* (left inverse), NOT the
278+
existence of *some* representative choice (economists pick representatives;
279+
the content is that no choice is canonical).
280+
281+
*Flagged (non-executable here):* deleting `session/slice-4-narrowing` (and,
282+
post-merge, `chore/prose-licence-longform-cc-by-sa`) is a manual GitHub-UI
283+
step — `git push --delete` returns HTTP 403 and the GitHub MCP has no
284+
delete-branch endpoint. The genuinely-open `Fidelity.agda` order-type
285+
fidelity debt (`D-2026-06-14`) is untouched.
286+
287+
*Plan for the next Claude.* (1) After the echo-types PR merges, a frugal
288+
one-line note on #175 that the general form landed (covers #174 too).
289+
(2) `EchoTypes.jl` mirror — add an `EchoAggregation` finite-domain shadow
290+
(the `Monoid`/`sumMonoid` instances + `pairSum` are directly executable).
291+
(3) oikos alib Route-B build, gated on the owner's Route A vs B decision.
292+
293+
DO NOT reopen: the general/macro split design (the macro IS the
294+
`Example-PairSum` instance — `pairSum` is the `sumMonoid` fold, so nothing is
295+
lost by hosting the general form here); the `no-section` refutation target
296+
(a section is a *left* inverse — exactly what non-disaggregability denies; do
297+
NOT restate it as a failed surjection, which is false since the maps are
298+
onto); the citation-level scope of the oikos bridge (oikos is Rust; no
299+
Agda↔Rust import path).
300+
301+
### Session arc 2026-06-18 — EchoAggregation / oikos alib bridge (the original macro-only landing)
216302

217303
*Where we started:* user asked (cross-repo) to investigate the wasm /
218304
typed-wasm route, then to scope an oikos/betlang "alib" aggregate library

docs/bridges/cross-repo-bridge-status.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ touches other repositories.
2222
| **Verdict-provenance (phronesis)** | `Echo`, `echo-intro` | `phronesis/academic/formal-verification/agda/PhronesisEcho.agda` (imports echo-types directly) | **Content bridge done (2026-06-12).** An ethical verdict's provenance IS `Echo verdict v`: `eval` is non-injective, so the fiber retains *which* expressions justify a verdict the bare `Bool` forgets (`verdict-forgets-provenance`); `proj₁` is the recovering section. Machine-checked vs real echo-types. (Also fixed 4 pre-existing bugs making `Phronesis.agda` compile.) | — (closed; downstream consumer in the agentic-ethics language). |
2323
| **KitchenSpeak `@` witness (nextgen-languages)** | `Echo` | `nextgen-languages/kitchenspeak/proofs/agda/EchoBridge.agda` | **Status upgraded to MACHINE-CHECKED (2026-06-12).** Previously "hand-verified, not machine-checked"; now typechecks against the real `Echo`. The `@` sensor witness IS `Echo (fired sensor thr) true` (`witness⇒echo` / `echo⇒witness`). PoachedEgg stdlib-v2.3 drift (`toWitness {Q=}``{a?=}`) fixed so the suite type-checks. | — (the `--` comments in `kitchenspeak.agda-lib` need Agda ≥ 2.6.4; on the 2.6.3 CI toolchain use the explicit `-i` form, documented in the module). |
2424
| **Invariant Path application (invariant-path)** | Structured-loss vocabulary (the `Echo` fiber concept) — citation-level | `invariant-path` (Rust): `classify_candidate` + `docs/ECHO-TYPES.md` + `crates/invariant-path-core/{examples,tests}/echo_structured_loss.rs` | **Application example (2026-06-12).** `classify_candidate` is a non-injective classifier; the retained `ClaimCandidate` + `ClassificationOutcome.losses` IS the echo (fiber) over a `Classification`. Invariant Path is "a claim-path debugger, not a truth engine" precisely because it retains echoes. Runnable example + 2 CI-covered tests. | No Agda↔Rust import path; citation-level — the application *uses* the echo principle; no mechanised cross-repo theorem. |
25-
| **oikos alib aggregation bridge (economics)** | `proofs/agda/EchoAggregation.agda` (`aggregate : MicroLedger → MacroTotal` IS an `Echo`; `no-canonical-disaggregation = no-section-of-collapsing-map`) | `oikos/docs/alib-aggregate-bridge.adoc` (toolchain-free design note for the alib aggregate library; oikos is the Rust SFC-macro DSL) | **Keystone formalisation + design note landed (2026-06-18).** Micro→macro economic aggregation is mechanised as an `Echo` map: the fibre over a macro total is exactly the set of micro ledgers consistent with it, and non-disaggregability is `no-section-of-collapsing-map` (no canonical `raise : MacroTotal → MicroLedger` left-inverse exists). This is the type-theoretic form of the Sonnenschein–Mantel–Debreu / representative-agent critique — it refutes a *section* (left inverse), not a representative *choice*. `EchoAggregation.agda` is self-contained in echo-types (imports `Echo` + `EchoNoSectionGeneric` only), `--safe --without-K`, zero postulates, pinned in `Smoke.agda`, classified in the kernel-note. The oikos design note recommends Route B (alib as an aggregation-morphism library over `MacroState`). | No Agda↔Rust import path; citation-level — echo-types proves the aggregation principle, oikos's alib will *consume* it. The alib library itself is not yet built (design-note stage; open questions §"Route A vs B" pending owner decision). |
25+
| **oikos alib aggregation bridge (economics)** | `proofs/agda/EchoAggregation.agda` — the GENERAL aggregation form (`Monoid` + `GroupAggregator` + `aggregation-as-fold` homomorphism + `sumMonoid`/`countMonoid`/`maxMonoid`/`minMonoid` + `no-canonical-disaggregation-of`); the macro economics is the `Example-PairSum` instance (`pairSum` IS the `sumMonoid` fold) | `oikos/docs/alib-aggregate-bridge.adoc` (toolchain-free design note; oikos is the Rust SFC-macro DSL) — names the macro reading `MacroAggregation`, cited back to echo-types | **General/macro split landed (2026-06-18, gen. rung).** echo-types now hosts the *general* monoid-aggregation form requested by issue #175 (SQL GROUP-BY as a monoid homomorphism; consumer = affinescript db-theory #3); the `aggregation-as-fold` law is *proved*, not merely signed, and generic non-disaggregability `no-canonical-disaggregation-of` also discharges #174's no-section sibling. The *macro→micro economics* reading — micro ledger rolled up to a Godley total, the Sonnenschein–Mantel–Debreu / representative-agent critique (refuting a *section* / left inverse, not a representative *choice*) — is the `Example-PairSum` instance, read at macro scale in oikos under the name `MacroAggregation` (naming it `EchoAggregation` there would be odd: aggregation is a *fundamental* of echo-types). `EchoAggregation.agda` is self-contained (imports `Echo` + `EchoNoSectionGeneric` only), `--safe --without-K`, zero postulates, pinned in `Smoke.agda`, classified in the kernel-note + `MAP.adoc`. The oikos design note recommends Route B (alib as an aggregation-morphism library over `MacroState`). | No Agda↔Rust import path; citation-level — echo-types proves the general aggregation principle (and its macro instance), oikos's alib will *consume* it. The alib library itself is not yet built (design-note stage; Route A vs B pending owner decision). |
2626

2727
## Immediate next actions
2828

@@ -72,6 +72,19 @@ precisely to paper over this in the relational model.
7272

7373
## Revision history
7474

75+
- 2026-06-18: **EchoAggregation general/macro split.** Generalised
76+
`EchoAggregation.agda` from the macro-economics-specific module into the
77+
general monoid-aggregation form requested by issue #175 (`Monoid` +
78+
`GroupAggregator` + the *proved* `aggregation-as-fold` homomorphism law +
79+
`sumMonoid`/`countMonoid`/`maxMonoid`/`minMonoid` + generic
80+
`no-canonical-disaggregation-of`, which also covers #174). The
81+
macro→micro economics reading survives mechanised as the `Example-PairSum`
82+
instance (`pairSum` IS the `sumMonoid` fold — nothing re-proved or lost);
83+
oikos reads that instance at macro scale under the name `MacroAggregation`
84+
(aggregation is a fundamental of echo-types, so re-using the name there
85+
would be odd). Updated the bridge row, `MAP.adoc`, and
86+
`echo-kernel-note.adoc`; `--safe --without-K`, zero postulates,
87+
kernel-guard PASS.
7588
- 2026-06-18: **oikos alib aggregation bridge.** Added the
7689
economics-aggregation row recording `EchoAggregation.agda` (micro→macro
7790
rollup is an `Echo`; non-disaggregability is `no-section-of-collapsing-map`

docs/echo-types/MAP.adoc

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -253,17 +253,28 @@ honest-bound matched-negative block.
253253
the `affine` mode in `EchoObservationalEquivalence`. Honest-bound:
254254
NOT side-channel-safe / cryptographic deniability / adaptive
255255
adversary. `proofs/agda/EchoDeniability.agda`. `[REAL]`
256-
* *Aggregation* — `aggregate` rolls a two-account ledger up to a
257-
Godley column total. The fibre `ConsistentLedgers m = Echo
258-
aggregate m` is "aggregation is many-to-one" as a type;
259-
`aggregate-non-injective` exhibits two distinct micro ledgers at
260-
the same macro total; `no-canonical-disaggregation` is the
261-
non-identifiability theorem (no section of `aggregate`, via
262-
`no-section-of-collapsing-map`). The mechanised keystone of the
263-
oikos/betlang alib note (`oikos:docs/alib-aggregate-bridge.adoc`).
264-
Honest-bound: NOT a quantitative fibre-size bound / joint
265-
identifiability of the full MacroState record.
266-
`proofs/agda/EchoAggregation.agda`. `[REAL]`
256+
* *Aggregation (general, issue #175)* — aggregation-as-fold over a
257+
`Monoid`, with a `GroupAggregator` and the monoid-homomorphism law
258+
`aggregation-as-fold` (aggregating a concatenation = combining the
259+
aggregates; proved, not merely signed). Four concrete instances
260+
(`sumMonoid` / `countMonoid` / `maxMonoid` / `minMonoid`, the last
261+
over `ℕ ∪ {∞}` via `Maybe ℕ`), a worked `countAggregator`, and
262+
generic non-disaggregability `no-canonical-disaggregation-of` (any
263+
collision ⇒ no section, via `no-section-of-collapsing-map`; this
264+
also discharges issue #174's no-section sibling). The
265+
macro→micro *economic* reading lives in `module Example-PairSum`:
266+
`pairSum : ℕ × ℕ → ℕ` IS the `sumMonoid` fold (`pairSum-is-fold`),
267+
is many-to-one (`pairSum-non-injective`), and has no canonical
268+
disaggregation (`no-canonical-disaggregation`) — the
269+
Sonnenschein–Mantel–Debreu / representative-agent critique
270+
type-theoretically. That instance is the mechanised anchor the
271+
oikos/betlang alib note cites (`oikos:docs/alib-aggregate-bridge.adoc`),
272+
where it is read at macro scale and named `MacroAggregation`.
273+
Consumer of the general form: affinescript db-theory #3 (SQL
274+
GROUP-BY as a monoid homomorphism). Honest-bound: `aggregation-as-fold`
275+
is the fold's homomorphism law, NOT full SQL GROUP-BY operational
276+
semantics; `avg` is deliberately absent (not a monoid — express as
277+
`sum / count`). `proofs/agda/EchoAggregation.agda`. `[REAL]`
267278

268279
*Curated suite — single-file entry point.* The narrative
269280
deliverable that pulls the Tier-1 / Tier-2 / Tier-3 named theorems

docs/echo-types/echo-kernel-note.adoc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,16 @@ kernel** — the boundary is real and lives outside this core.
130130
MAP.adoc. `EchoDeniability` formalises residue deniability: the
131131
perfect (constant / no-section) case and the partial (injective /
132132
has-section) case, with `IsConstantOpener` as the exact cut-point.
133-
`EchoAggregation` formalises micro→macro economic aggregation: the
134-
rollup `aggregate` is an `Echo` map and non-disaggregability is
135-
`no-section-of-collapsing-map` (the mechanised keystone of the
136-
oikos/betlang alib note). Imports `Echo` + `EchoNoSectionGeneric`.
133+
`EchoAggregation` is the general aggregation form (issue #175):
134+
aggregation-as-fold over a `Monoid`, a `GroupAggregator`, the
135+
monoid-homomorphism law `aggregation-as-fold`, the four concrete
136+
instances (`sumMonoid`/`countMonoid`/`maxMonoid`/`minMonoid`), and
137+
generic non-disaggregability `no-canonical-disaggregation-of` (any
138+
collision ⇒ no section, via `no-section-of-collapsing-map`; also
139+
covers #174). The macro→micro economic reading is the
140+
`Example-PairSum` instance the oikos/betlang alib note cites
141+
(`pairSum` IS the `sumMonoid` fold). Imports `Echo` +
142+
`EchoNoSectionGeneric`.
137143

138144
| *Earn-back gate modules* +
139145
(derived / scoped; not kernel)

0 commit comments

Comments
 (0)