Metadata-Version: 2.4
Name: loopmarket
Version: 0.4.0
Summary: Universal combinatorial marketplace: uniform offers over an OntoDAG catalogue, a versioned offer book on recordstore/Swarm, and solver agents hunting profitable loops
License: BSD-3-Clause
Project-URL: Homepage, https://github.com/petfold/loopmarket
Project-URL: Repository, https://github.com/petfold/loopmarket
Project-URL: Issues, https://github.com/petfold/loopmarket/issues
Keywords: marketplace,combinatorial-exchange,ontology,dag,subsumption,swarm,web3,decentralized,solver,negative-cycle,barter,mutual-credit,coincidence-of-wants
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ontodag>=0.25.0
Requires-Dist: recordstore>=0.16.0
Provides-Extra: swarm
Requires-Dist: recordstore[bee,feeds]>=0.16.0; extra == "swarm"
Provides-Extra: sig
Requires-Dist: eth-keys; extra == "sig"
Requires-Dist: eth-hash[pycryptodome]; extra == "sig"
Requires-Dist: coincurve; extra == "sig"
Requires-Dist: cryptography; extra == "sig"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

# loopmarket

[![license](https://img.shields.io/badge/license-BSD--3--Clause-blue)](LICENSE)

A universal combinatorial marketplace over the
[ontodag](https://github.com/petfold/ontodag) /
[recordstore](https://github.com/petfold/recordstore) /
[Ethereum Swarm](https://www.ethswarm.org/) stack.

Every economic intention is one uniform, content-addressed **offer** — a
thing described as a conjunction of OntoDAG categories, with a service time
window and region, priced on the maker's **personal scale** (a personal
numeraire; the record encoding calls it the maker's personal token). A
distributed, versioned **offer book** holds them (recordstore keyspace;
Swarm-backed via `BeeBytesStore` + a signed `SwarmFeedPointer`). Competing
**solver agents** hunt profitable **loops** — cycles whose exchange-rate
product exceeds one, i.e. negative cycles under −log weights — and a
**clearing** layer re-verifies every leg from scratch and commits the
whole loop atomically.

```console
$ odag put piano-lesson music-lesson        # the catalogue is ontodag's
$ loop set maker amara; loop place home 46.05,14.50,5km; loop set terms 'where(home)'
$ loop give piano-lesson 100                # I give this, priced on my scale
$ loop want produce local weekly 104        # I want this, priced on my scale
$ loop loops && loop clearing               # hunt profitable loops; run the clearing house
```

`loop` is the command line (`pip install loopmarket`): ontodag's grammar
plus two conventions — a bare number first is the quantity, last is the
price — and `+` between the parts of a want that must clear together;
every name a catalogue node, an omitted price your last unit
price, and nothing published before the fully resolved offer is shown.
Type `loop` alone for a prompt, pipe it a script for a batch. The same in
Python:

```python
from recordstore import MemoryBytesStore, RecordStore
from loopmarket import (Ontology, OfferRegistry, MockClearing,
                        SolverAgent, Thing, give, want, ...)

ontology = Ontology().load({"produce": [], "vegetable-box": ["produce"], ...})
registry = OfferRegistry(RecordStore(MemoryBytesStore()))
registry.publish_many([...])          # gives and wants, one uniform form
registry.commit()

agent = SolverAgent(registry, ontology, MockClearing(registry, ontology))
agent.step()                          # snapshot → match → hunt loops → clear
```

## Try it

```bash
pip install -e ".[test]"              # (--break-system-packages or a venv)
python3 -m pytest tests/ -v           # 123 tests (two need a live Bee node)
LOOP_HOME=$(mktemp -d) loop --catalogue examples/triangle.od < examples/triangle.loop   # P0 as a script
PYTHONPATH=src python3 examples/demo_triangle.py     # the same, through the API
PYTHONPATH=src python3 examples/demo_federation.py   # P1: books, fold, forgery, follower
```

The script publishes the smallest nontrivial book — a piano teacher, a
market gardener and a bicycle mechanic, no pair of whom can trade — and
`loops && clear` finds, verifies and clears the triangle at a 12% surplus:
fifteen lines of `set maker`, `give piano-lesson where(amara_flat) 100`,
`want produce local weekly ...`. It runs unchanged with the book on Swarm
(`loop -f swarm:TOPIC ...`; 0.3.0 live-checked 2026-09-12 on a Bee 2.8.2
light node: published, solved and cleared in 1m51s with the same `loop_id`
the in-memory run gives, a fresh session reading the six fills back in
11s). The federation demo runs per-maker books on their own feeds, two
aggregators folding to byte-identical manifests, a censoring aggregator
convicted by absence proofs, a forged offer dying at the fold, a
tombstoned offer staying closed, clearing provably based on the fold, and
a follower reading it all back — in memory by default, live against a Bee
node when `BEE_API` and `BEE_BATCH` are set (0.3.0 live, with ontodag's
core pack: 4m25s, every check true). New here? Start with the
**[User Guide](docs/USER-GUIDE.md)** (a tutorial at the command line,
with the API alongside), then the **[Reference Manual](docs/REFERENCE.md)**
(commands, settings, API, record formats, invariants). `loop help` is the
one-screen version; the design record with its reasons is
[`docs/plans/cli.md`](docs/plans/cli.md).

Candidate generation can also run through ontodag's **parametric
dimensions**: `DimensionIndex` files gives under exactly the terms they
carry (`where(u24)`, `where(ljubljana)`, `when(...)`, `from(my_home)` —
cells, places, regions and floors, ordered by the graph), and
`candidate_matches_indexed` asks **one** ontodag `get` per want — the
want's own conjunction as the query, items only — provably the same
matches as the exhaustive baseline
(the recall test enforces set-equality), with far fewer exact checks. The
index is a derived, per-solver copy; the shared catalogue and its pinned
roots never move because of it. Swap the in-memory store for
`recordstore.swarm_store("offers", signer=...)` (extra:
`pip install -e ".[swarm]"`, plus a Bee node and a postage batch) and the
same code runs with the book on Swarm.

## What is built, and what is designed

**Built (P0, plus the live-Swarm milestone):** the full pipeline above runs
in memory — and, since 2026-09-12, from the command line (`loop`) — and since 2026-08-01 also end-to-end on a real Gnosis-mainnet
Bee node — catalogue and book on Swarm, book head in a signed feed, fills
atomic (the gated `tests/test_swarm_book.py`). Since 2026-08-21 the
federation layer runs too — in memory *and* live (the gated
`tests/test_swarm_federation.py`, 96.5s on a Bee 2.8.1 node): per-maker
books under their own feeds and signers, an `Aggregator` folding them
under the U8 admission rules into a three-root manifest published on its
own feed, withdrawal tombstones, and a scorched-earth follower
reconstructing the cleared world from (address, topic) alone. Since
2026-09-04 the federation demo adopts ontodag's `core` pack as the
catalogue and includes a censoring aggregator: `audit_manifest` convicts
it from its own manifest with absence proofs, and a solver folding the
announced maker books itself recovers the honest fold (T14).
Alpha; interfaces will move.

**Designed (2026-08-07):** most of what loopmarket *is* now lives as a
decided, research-grounded plan corpus under `docs/plans/` — one document
per work package, each with measurable gates, named open problems, and a
closing "what this document does not promise" section. Anything implying
unbuilt code carries a dated marker ("decided 2026-08, lands with the v2
bump / P1 / P2"). Planned invariants **U8–U14** are specified in the
documents that motivate them and summarized across `ARCHITECTURE.md`'s
update notes and §11; they enter `CLAUDE.md` as binding invariants only
when their enforcing code and tests land. factbond's mirror corpus is
`factbond/docs/plans/`.

## Vocabulary

Three words carry the design and are used precisely since 2026-09-07:

- **loop** — any cleared circulation: the essay's word and the name in code (`Loop`, `LoopProposal`, `loop/`, `loop_id`).
- **cycle** (simple loop) — the strict circle; all the P0 solver finds, and the only case where "the product of rates around it" means anything.
- **circulation** — the technical name for the cleared object: a flow conserved at every maker on that maker's own scale, with composed legs where one want takes several gives (`docs/plans/P2-loop-selection.md` §10–11).
- **hyper-leg** — a composed leg: several givers as tails, one wanting maker as head, one flow variable, so it fills every tail or none. The maker graph with hyper-legs is a hypergraph; its flow is an LP for divisible legs and an ILP where a hyper-leg is all-or-nothing.

And two more: **clearing** is the atomic commit that fixes obligations; **settlement** is the makers delivering.

## The plan corpus

| Document | One line |
|---|---|
| [`P1-federated-book.md`](docs/plans/P1-federated-book.md) | Per-maker books under own feeds/signers; announcement, aggregation, merge discipline, lifecycle, postage economics, spam floors. |
| [`P1-spacetime-terms.md`](docs/plans/P1-spacetime-terms.md) | Place and time leave the offer's fields for its conjunction (decided 2026-09-12): one relation, containment, for every term — where/when a thing changes hands are terms like its categories (the overlap rule of the same morning, superseded that night); cells and region nodes as the exact geo truth, the disc retires; the path to the v3 record. Step 2 (`satisfies` over mixed terms) landed the same day. |
| [`P2-batch-auction.md`](docs/plans/P2-batch-auction.md) | The beat: sealed proposals, numeraire-free scoring, the fairness floor, capped solver rewards, collusion resistance, fees. |
| [`P2-clearing-pricing.md`](docs/plans/P2-clearing-pricing.md) | Turning a winning loop's surplus into per-leg prices: equal log-surplus split under uniform directional clearing; clearing prices as node potentials (§10). |
| [`P2-loop-selection.md`](docs/plans/P2-loop-selection.md) | Clearing as optimization: flow LP vs packing ILP, chains, failure-aware objective, pre-commit compression; composition on the want side (§10); the cleared object is a circulation, clearing prices its node potentials (§11). |
| [`proof-fabric.md`](docs/plans/proof-fabric.md) | Cross-phase proofs and certificates: trie proofs vs POT, the pin table, certificate envelopes, absence proofs. |
| [`P3-guarantee-coupling.md`](docs/plans/P3-guarantee-coupling.md) | loopmarket's half of the factbond coupling: witness edges, reliance-capped insurance, oracle consumption, risk-priced routing. |
| [`P4-privacy.md`](docs/plans/P4-privacy.md) | Staged privacy: Tier 1 with zero new cryptography, the P2 format-freeze list, explicit dead/deferred rulings. |
| [`ontodag-coupling.md`](docs/plans/ontodag-coupling.md) | The catalogue contract: dimension terms, unit families, match degrees, the upstream-vs-local tripwire table. |
| [`cli.md`](docs/plans/cli.md) | The command line (designed 2026-09-11, **built 2026-09-12** as `loop`): ontodag's grammar plus quantity-first/price-last, every name a catalogue node, last-price memory, "declare in the direction you know" instead of a tolerance parameter, the approval block, batch scripts; what is still open (`fold`/`audit`/`propose`, U8 for peers, the upstream asks). |
| [`catalogue-bootstrap.md`](docs/plans/catalogue-bootstrap.md) | Seeding and governing the shared catalogue: seed taxonomies, the import pipeline, norms as protocol rules. |
| [`adoption-and-thickness.md`](docs/plans/adoption-and-thickness.md) | Where the first loops come from: launch verticals, the broker surface, bridge liquidity, thickness engineering. |
| [`THREATS.md`](docs/plans/THREATS.md) | The threat register, T1–T9, ordered by expected damage to a young system; mirrored in factbond. |
| [swarm-da](https://github.com/petfold/swarm-da) (separate repo) | Memo, 2026-09-09: what building this book on Swarm taught about Swarm as a data-availability layer — the archival-DA opportunity, Bee's push-sync receipts as the half-built publication primitive, and what loopmarket sheds the day they are exposed and anchored. |

**Phase ↔ document map.** P1 (federation): `P1-federated-book.md`,
supported by `ontodag-coupling.md` and `catalogue-bootstrap.md`, with
`cli.md` as its tooling. P2
(verifiable clearing): the three P2 docs plus `proof-fabric.md`,
*constrained* by `P4-privacy.md`'s format-freeze list and gated by
`THREATS.md` tripwires. P3 (guarantee fabric): `P3-guarantee-coupling.md`
plus factbond's entire corpus — gated by factbond's Phase-0 simulation
going green *and* the P2 format freeze. P4 (privacy): `P4-privacy.md`,
whose Tier 1 may ship alongside P2. Cross-phase: `proof-fabric.md`,
`THREATS.md`, `adoption-and-thickness.md`, `catalogue-bootstrap.md`,
`ontodag-coupling.md`.

**Reading order.** First pass: `ARCHITECTURE.md` → `THREATS.md` →
`P1-federated-book.md`. Clearing track: `P2-loop-selection.md` →
`P2-clearing-pricing.md` → `P2-batch-auction.md` → `proof-fabric.md`.
Guarantee track: factbond `DESIGN.md` → `mechanism-design.md` →
`insurance-products.md` → `phase0-simulation.md` →
`P3-guarantee-coupling.md`. Market track: `adoption-and-thickness.md` →
`catalogue-bootstrap.md` → `ontodag-coupling.md`.

Order of documents is not order of construction — gates decide that; and a
document's existence proves nothing about feasibility. The Phase-0
simulation and the named empirical gates can kill designs recorded here;
the corpus is built so that they can.

## Documentation

- **[docs/USER-GUIDE.md](docs/USER-GUIDE.md)** — the tutorial: from your
  first offer to a federated book on a live Swarm network, every snippet
  runnable.
- **[docs/REFERENCE.md](docs/REFERENCE.md)** — the reference manual:
  every public class and function, the keyspace, record formats,
  invariants, environment.
- **[ARCHITECTURE.md](ARCHITECTURE.md)** — the design and its rationale:
  the uniform offer form, time/place as fits-within dimensions, the book's
  keyspace and multi-writer story, the loop arithmetic (and why prices are
  never negative), the trust model, the proof fabric, economic security,
  and what the architecture does not promise.
- **[ROADMAP.md](ROADMAP.md)** — the phase index with status:
  P0 (built) → P1 (federated book, live since 2026-08-21) → P2 (verifiable
  clearing, batch auctions) → P3 (guarantee fabric via factbond) →
  P4 (privacy), each linking to its plan document.
- **[CLAUDE.md](CLAUDE.md)** — working rules for development: dependency
  boundaries, core invariants U1–U7, known simplifications.
- **[docs/loop-economy.md](docs/loop-economy.md)** — the vision essay: the
  loop economy, its gallery of loops, the solver ecology, judges without
  swords, and the path in.
