loopmarket 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {loopmarket-0.2.0/src/loopmarket.egg-info → loopmarket-0.3.0}/PKG-INFO +14 -7
  2. {loopmarket-0.2.0 → loopmarket-0.3.0}/README.md +11 -6
  3. {loopmarket-0.2.0 → loopmarket-0.3.0}/pyproject.toml +3 -2
  4. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/__init__.py +1 -1
  5. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/cli.py +786 -132
  6. loopmarket-0.3.0/src/loopmarket/dimensions.py +205 -0
  7. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/federation.py +20 -0
  8. loopmarket-0.3.0/src/loopmarket/handoff.py +95 -0
  9. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/matching.py +22 -11
  10. loopmarket-0.3.0/src/loopmarket/ontology.py +321 -0
  11. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/registry.py +40 -5
  12. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/schema.py +94 -36
  13. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/sigs.py +14 -0
  14. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/spacetime.py +48 -10
  15. {loopmarket-0.2.0 → loopmarket-0.3.0/src/loopmarket.egg-info}/PKG-INFO +14 -7
  16. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket.egg-info/SOURCES.txt +4 -1
  17. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket.egg-info/requires.txt +2 -0
  18. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_cli.py +246 -49
  19. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_dimensions.py +86 -0
  20. loopmarket-0.3.0/tests/test_handoff.py +137 -0
  21. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_matching.py +24 -0
  22. loopmarket-0.3.0/tests/test_ontology.py +150 -0
  23. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_schema.py +3 -1
  24. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_swarm_book.py +26 -16
  25. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_swarm_federation.py +21 -9
  26. loopmarket-0.3.0/tests/test_v3_record.py +228 -0
  27. loopmarket-0.2.0/src/loopmarket/dimensions.py +0 -147
  28. loopmarket-0.2.0/src/loopmarket/ontology.py +0 -169
  29. loopmarket-0.2.0/tests/test_ontology.py +0 -36
  30. {loopmarket-0.2.0 → loopmarket-0.3.0}/LICENSE +0 -0
  31. {loopmarket-0.2.0 → loopmarket-0.3.0}/setup.cfg +0 -0
  32. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/__main__.py +0 -0
  33. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/clearing.py +0 -0
  34. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/graph.py +0 -0
  35. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/settlement.py +0 -0
  36. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/solver/__init__.py +0 -0
  37. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket/solver/agent.py +0 -0
  38. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket.egg-info/dependency_links.txt +0 -0
  39. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket.egg-info/entry_points.txt +0 -0
  40. {loopmarket-0.2.0 → loopmarket-0.3.0}/src/loopmarket.egg-info/top_level.txt +0 -0
  41. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_boundaries.py +0 -0
  42. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_docs.py +0 -0
  43. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_end_to_end.py +0 -0
  44. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_federation.py +0 -0
  45. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_graph.py +0 -0
  46. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_registry.py +0 -0
  47. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_sigs.py +0 -0
  48. {loopmarket-0.2.0 → loopmarket-0.3.0}/tests/test_spacetime.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loopmarket
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Universal combinatorial marketplace: uniform offers over an OntoDAG catalogue, a versioned offer book on recordstore/Swarm, and solver agents hunting profitable loops
5
5
  License: BSD-3-Clause
6
6
  Project-URL: Homepage, https://github.com/petfold/loopmarket
@@ -25,6 +25,8 @@ Requires-Dist: recordstore[bee,feeds]>=0.16.0; extra == "swarm"
25
25
  Provides-Extra: sig
26
26
  Requires-Dist: eth-keys; extra == "sig"
27
27
  Requires-Dist: eth-hash[pycryptodome]; extra == "sig"
28
+ Requires-Dist: coincurve; extra == "sig"
29
+ Requires-Dist: cryptography; extra == "sig"
28
30
  Provides-Extra: test
29
31
  Requires-Dist: pytest; extra == "test"
30
32
  Dynamic: license-file
@@ -51,15 +53,16 @@ whole loop atomically.
51
53
 
52
54
  ```console
53
55
  $ odag put piano-lesson music-lesson # the catalogue is ontodag's
54
- $ loop set maker amara; loop place home 46.05,14.50,5km; loop set where home
56
+ $ loop set maker amara; loop place home 46.05,14.50,5km; loop set terms 'where(home)'
55
57
  $ loop give piano-lesson 100 # I give this, priced on my scale
56
58
  $ loop want produce local weekly 104 # I want this, priced on my scale
57
- $ loop loops && loop clear # hunt profitable loops; clear one
59
+ $ loop loops && loop clearing # hunt profitable loops; run the clearing house
58
60
  ```
59
61
 
60
62
  `loop` is the command line (`pip install loopmarket`): ontodag's grammar
61
63
  plus two conventions — a bare number first is the quantity, last is the
62
- price — every name a catalogue node, an omitted price your last unit
64
+ price — and `+` between the parts of a want that must clear together;
65
+ every name a catalogue node, an omitted price your last unit
63
66
  price, and nothing published before the fully resolved offer is shown.
64
67
  Type `loop` alone for a prompt, pipe it a script for a batch. The same in
65
68
  Python:
@@ -82,7 +85,7 @@ agent.step() # snapshot → match → hunt loops → cl
82
85
 
83
86
  ```bash
84
87
  pip install -e ".[test]" # (--break-system-packages or a venv)
85
- python3 -m pytest tests/ -v # 92 tests (two need a live Bee node)
88
+ python3 -m pytest tests/ -v # 119 tests (two need a live Bee node)
86
89
  LOOP_HOME=$(mktemp -d) loop --catalogue examples/triangle.od < examples/triangle.loop # P0 as a script
87
90
  PYTHONPATH=src python3 examples/demo_triangle.py # the same, through the API
88
91
  PYTHONPATH=src python3 examples/demo_federation.py # P1: books, fold, forgery, follower
@@ -106,8 +109,11 @@ one-screen version; the design record with its reasons is
106
109
  [`docs/plans/cli.md`](docs/plans/cli.md).
107
110
 
108
111
  Candidate generation can also run through ontodag's **parametric
109
- dimensions**: `DimensionIndex` files gives under their exact service window
110
- and centre cell, and `candidate_matches_indexed` prunes by concept cones
112
+ dimensions**: `DimensionIndex` files gives under their service-role terms
113
+ (`where(u24)`, `when(...)`, `from(...)`, matched by overlap; place prunes
114
+ through cells since 2026-09-12 — and, for v2 records, under their window
115
+ and centre cell), and
116
+ `candidate_matches_indexed` prunes by concept cones
111
117
  and window overlap — provably the same matches as the exhaustive baseline
112
118
  (the recall test enforces set-equality), with far fewer exact checks. The
113
119
  index is a derived, per-solver copy; the shared catalogue and its pinned
@@ -161,6 +167,7 @@ And two more: **clearing** is the atomic commit that fixes obligations; **settle
161
167
  | Document | One line |
162
168
  |---|---|
163
169
  | [`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. |
170
+ | [`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): the role-head rule — containment for what a thing is, overlap for where/when it changes hands, declared in the catalogue as `service-role`; 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. |
164
171
  | [`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. |
165
172
  | [`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). |
166
173
  | [`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). |
@@ -20,15 +20,16 @@ whole loop atomically.
20
20
 
21
21
  ```console
22
22
  $ odag put piano-lesson music-lesson # the catalogue is ontodag's
23
- $ loop set maker amara; loop place home 46.05,14.50,5km; loop set where home
23
+ $ loop set maker amara; loop place home 46.05,14.50,5km; loop set terms 'where(home)'
24
24
  $ loop give piano-lesson 100 # I give this, priced on my scale
25
25
  $ loop want produce local weekly 104 # I want this, priced on my scale
26
- $ loop loops && loop clear # hunt profitable loops; clear one
26
+ $ loop loops && loop clearing # hunt profitable loops; run the clearing house
27
27
  ```
28
28
 
29
29
  `loop` is the command line (`pip install loopmarket`): ontodag's grammar
30
30
  plus two conventions — a bare number first is the quantity, last is the
31
- price — every name a catalogue node, an omitted price your last unit
31
+ price — and `+` between the parts of a want that must clear together;
32
+ every name a catalogue node, an omitted price your last unit
32
33
  price, and nothing published before the fully resolved offer is shown.
33
34
  Type `loop` alone for a prompt, pipe it a script for a batch. The same in
34
35
  Python:
@@ -51,7 +52,7 @@ agent.step() # snapshot → match → hunt loops → cl
51
52
 
52
53
  ```bash
53
54
  pip install -e ".[test]" # (--break-system-packages or a venv)
54
- python3 -m pytest tests/ -v # 92 tests (two need a live Bee node)
55
+ python3 -m pytest tests/ -v # 119 tests (two need a live Bee node)
55
56
  LOOP_HOME=$(mktemp -d) loop --catalogue examples/triangle.od < examples/triangle.loop # P0 as a script
56
57
  PYTHONPATH=src python3 examples/demo_triangle.py # the same, through the API
57
58
  PYTHONPATH=src python3 examples/demo_federation.py # P1: books, fold, forgery, follower
@@ -75,8 +76,11 @@ one-screen version; the design record with its reasons is
75
76
  [`docs/plans/cli.md`](docs/plans/cli.md).
76
77
 
77
78
  Candidate generation can also run through ontodag's **parametric
78
- dimensions**: `DimensionIndex` files gives under their exact service window
79
- and centre cell, and `candidate_matches_indexed` prunes by concept cones
79
+ dimensions**: `DimensionIndex` files gives under their service-role terms
80
+ (`where(u24)`, `when(...)`, `from(...)`, matched by overlap; place prunes
81
+ through cells since 2026-09-12 — and, for v2 records, under their window
82
+ and centre cell), and
83
+ `candidate_matches_indexed` prunes by concept cones
80
84
  and window overlap — provably the same matches as the exhaustive baseline
81
85
  (the recall test enforces set-equality), with far fewer exact checks. The
82
86
  index is a derived, per-solver copy; the shared catalogue and its pinned
@@ -130,6 +134,7 @@ And two more: **clearing** is the atomic commit that fixes obligations; **settle
130
134
  | Document | One line |
131
135
  |---|---|
132
136
  | [`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. |
137
+ | [`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): the role-head rule — containment for what a thing is, overlap for where/when it changes hands, declared in the catalogue as `service-role`; 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. |
133
138
  | [`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. |
134
139
  | [`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). |
135
140
  | [`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). |
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "loopmarket"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Universal combinatorial marketplace: uniform offers over an OntoDAG catalogue, a versioned offer book on recordstore/Swarm, and solver agents hunting profitable loops"
9
9
  readme = "README.md"
10
10
  license = { text = "BSD-3-Clause" }
@@ -38,7 +38,8 @@ dependencies = [
38
38
  swarm = ["recordstore[bee,feeds]>=0.16.0"]
39
39
  # Detached offer signatures (U8's off-feed layer): the same secp256k1
40
40
  # identity that owns the maker's feed, recoverable without a node.
41
- sig = ["eth-keys", "eth-hash[pycryptodome]"]
41
+ # ...and sealed handoffs (`handoff.py`): ECDH on the same curve + AES-GCM.
42
+ sig = ["eth-keys", "eth-hash[pycryptodome]", "coincurve", "cryptography"]
42
43
  test = ["pytest"]
43
44
 
44
45
  [project.scripts]
@@ -29,7 +29,7 @@ from .graph import ExchangeGraph, Loop
29
29
  from .clearing import LoopProposal, MockClearing, Receipt, Clearing
30
30
  from .solver.agent import SolverAgent
31
31
 
32
- __version__ = "0.2.0"
32
+ __version__ = "0.3.0"
33
33
 
34
34
  __all__ = [
35
35
  "GIVE", "WANT", "ASK", "BID", "GeoDisc", "Offer", "Thing", "TimeWindow",