plexus-mesh 0.2.2__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 (36) hide show
  1. plexus_mesh-0.2.2/LICENSE +110 -0
  2. plexus_mesh-0.2.2/PKG-INFO +378 -0
  3. plexus_mesh-0.2.2/README.md +359 -0
  4. plexus_mesh-0.2.2/pyproject.toml +43 -0
  5. plexus_mesh-0.2.2/setup.cfg +4 -0
  6. plexus_mesh-0.2.2/src/plexus/__init__.py +27 -0
  7. plexus_mesh-0.2.2/src/plexus/__main__.py +4 -0
  8. plexus_mesh-0.2.2/src/plexus/cli.py +139 -0
  9. plexus_mesh-0.2.2/src/plexus/graph.py +38 -0
  10. plexus_mesh-0.2.2/src/plexus/manifest.py +117 -0
  11. plexus_mesh-0.2.2/src/plexus/mcp.py +156 -0
  12. plexus_mesh-0.2.2/src/plexus/mesh.py +88 -0
  13. plexus_mesh-0.2.2/src/plexus/plan.py +120 -0
  14. plexus_mesh-0.2.2/src/plexus/receipt.py +66 -0
  15. plexus_mesh-0.2.2/src/plexus/registry.py +418 -0
  16. plexus_mesh-0.2.2/src/plexus/run.py +44 -0
  17. plexus_mesh-0.2.2/src/plexus_mesh.egg-info/PKG-INFO +378 -0
  18. plexus_mesh-0.2.2/src/plexus_mesh.egg-info/SOURCES.txt +34 -0
  19. plexus_mesh-0.2.2/src/plexus_mesh.egg-info/dependency_links.txt +1 -0
  20. plexus_mesh-0.2.2/src/plexus_mesh.egg-info/entry_points.txt +2 -0
  21. plexus_mesh-0.2.2/src/plexus_mesh.egg-info/requires.txt +3 -0
  22. plexus_mesh-0.2.2/src/plexus_mesh.egg-info/top_level.txt +1 -0
  23. plexus_mesh-0.2.2/tests/test_extended_registry.py +85 -0
  24. plexus_mesh-0.2.2/tests/test_flagship_interop_roles.py +74 -0
  25. plexus_mesh-0.2.2/tests/test_mneme_contract.py +62 -0
  26. plexus_mesh-0.2.2/tests/test_plexus_core.py +96 -0
  27. plexus_mesh-0.2.2/tests/test_plexus_cycle9.py +179 -0
  28. plexus_mesh-0.2.2/tests/test_plexus_grounding.py +70 -0
  29. plexus_mesh-0.2.2/tests/test_plexus_manifests.py +41 -0
  30. plexus_mesh-0.2.2/tests/test_plexus_mcp.py +227 -0
  31. plexus_mesh-0.2.2/tests/test_plexus_receipt.py +70 -0
  32. plexus_mesh-0.2.2/tests/test_plexus_render.py +49 -0
  33. plexus_mesh-0.2.2/tests/test_qcr_replay_routing.py +81 -0
  34. plexus_mesh-0.2.2/tests/test_release_install_recipes.py +268 -0
  35. plexus_mesh-0.2.2/tests/test_release_metadata.py +47 -0
  36. plexus_mesh-0.2.2/tests/test_repo_art.py +163 -0
@@ -0,0 +1,110 @@
1
+ # Functional Source License, Version 1.1, MIT Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-MIT
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Zain Dana Harper
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the MIT license that is effective on the second anniversary of the date we make
91
+ the Software available. On or after that date, you may use the Software under
92
+ the MIT license, in which case the following will apply:
93
+
94
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
95
+ this software and associated documentation files (the "Software"), to deal in
96
+ the Software without restriction, including without limitation the rights to
97
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
98
+ of the Software, and to permit persons to whom the Software is furnished to do
99
+ so, subject to the following conditions:
100
+
101
+ The above copyright notice and this permission notice shall be included in all
102
+ copies or substantial portions of the Software.
103
+
104
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
107
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
108
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
110
+ SOFTWARE.
@@ -0,0 +1,378 @@
1
+ Metadata-Version: 2.4
2
+ Name: plexus-mesh
3
+ Version: 0.2.2
4
+ Summary: Declarative capability discovery + auto-wiring for agent toolchains: point it at tool manifests and it wires producer to consumer into an executable pipeline, every discovery edge tagged declared and citing the module its producer names. Discovery does not import or run cited tools; optional explicit probe helpers can launch owned MCP servers. Zero runtime dependencies.
5
+ Author: Zain Dana Harper
6
+ License-Expression: LicenseRef-FSL-1.1-MIT
7
+ Project-URL: Homepage, https://github.com/HarperZ9/plexus
8
+ Keywords: agent-tools,interop,mcp,discovery,pipeline,orchestration,capability-graph
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Software Development :: Libraries
12
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
+ Requires-Python: >=3.11
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Provides-Extra: test
17
+ Requires-Dist: pytest>=8; extra == "test"
18
+ Dynamic: license-file
19
+
20
+ <p align="center"><img src="docs/art/plexus-header.svg" alt="plexus: toolchain wiring discovery. Point it at your tools and it computes how they plug together." width="100%"></p>
21
+
22
+ # plexus
23
+
24
+ **Capability discovery and auto-wiring for agent toolchains.** Point it at a set
25
+ of tools and it discovers what each one emits and consumes, then wires producer
26
+ to consumer into a runnable pipeline. Zero runtime dependencies.
27
+
28
+ MCP tells an agent *that tools exist*. plexus tells it *how their outputs plug
29
+ into each other's inputs*: the layer above a flat tool list.
30
+
31
+ GitHub-only release install for 0.2.1 on Bash/macOS/Linux:
32
+
33
+ ```bash
34
+ set -euo pipefail
35
+ VERSION=0.2.1
36
+ BASE="https://github.com/HarperZ9/plexus/releases/download/v0.2.1"
37
+ WHEEL="plexus_mesh-${VERSION}-py3-none-any.whl"
38
+ SDIST="plexus_mesh-${VERSION}.tar.gz"
39
+ SUMS="SHA256SUMS.txt"
40
+ curl -fL -o "$WHEEL" "${BASE}/${WHEEL}"
41
+ curl -fL -o "$SDIST" "${BASE}/${SDIST}"
42
+ curl -fL -o "$SUMS" "${BASE}/${SUMS}"
43
+ python - "$WHEEL" "$SDIST" "$SUMS" <<'PY'
44
+ import hashlib
45
+ import re
46
+ import sys
47
+ from pathlib import Path
48
+
49
+ required = list(sys.argv[1:3])
50
+ sums = Path(sys.argv[3])
51
+ expected = {}
52
+ for line_number, raw_line in enumerate(sums.read_text(encoding="utf-8").splitlines(), 1):
53
+ line = raw_line.strip()
54
+ if not line:
55
+ continue
56
+ parts = line.split(maxsplit=1)
57
+ if len(parts) != 2:
58
+ raise SystemExit(f"malformed checksum line {line_number}")
59
+ digest, name = parts[0].lower(), parts[1].lstrip("*")
60
+ if not re.fullmatch(r"[0-9a-f]{64}", digest):
61
+ raise SystemExit(f"invalid checksum for {name}")
62
+ if Path(name).name != name:
63
+ raise SystemExit(f"unexpected checksum path: {name}")
64
+ if name not in required:
65
+ raise SystemExit(f"unexpected checksum entry: {name}")
66
+ if name in expected:
67
+ raise SystemExit(f"duplicate checksum entry: {name}")
68
+ expected[name] = digest
69
+ missing = [name for name in required if name not in expected]
70
+ if missing:
71
+ raise SystemExit(f"missing checksum entry: {', '.join(missing)}")
72
+ for name in required:
73
+ got = hashlib.sha256(Path(name).read_bytes()).hexdigest()
74
+ if got != expected[name]:
75
+ raise SystemExit(f"{name}: expected {expected[name]}, got {got}")
76
+ PY
77
+ python -m pip install "$WHEEL"
78
+ ```
79
+
80
+ GitHub-only release install for 0.2.1 on native PowerShell:
81
+
82
+ ```powershell
83
+ & {
84
+ $ErrorActionPreference = "Stop"
85
+ $Version = "0.2.1"
86
+ $Base = "https://github.com/HarperZ9/plexus/releases/download/v0.2.1"
87
+ $Wheel = "plexus_mesh-$Version-py3-none-any.whl"
88
+ $Sdist = "plexus_mesh-$Version.tar.gz"
89
+ $Sums = "SHA256SUMS.txt"
90
+ $Files = @($Wheel, $Sdist, $Sums)
91
+ foreach ($Name in $Files) {
92
+ Invoke-WebRequest -Uri "$Base/$Name" -OutFile $Name
93
+ }
94
+ $Required = @($Wheel, $Sdist)
95
+ $Expected = @{}
96
+ $LineNumber = 0
97
+ Get-Content -LiteralPath $Sums | ForEach-Object {
98
+ $LineNumber += 1
99
+ $Line = $_.Trim()
100
+ if (-not $Line) { return }
101
+ $Parts = $Line -split '\s+', 2
102
+ if ($Parts.Count -ne 2) { throw "malformed checksum line $LineNumber" }
103
+ $Digest = $Parts[0].ToLowerInvariant()
104
+ $Name = $Parts[1].TrimStart("*")
105
+ if ($Digest -notmatch '^[0-9a-f]{64}$') { throw "invalid checksum for $Name" }
106
+ if ([IO.Path]::GetFileName($Name) -ne $Name) { throw "unexpected checksum path: $Name" }
107
+ if ($Required -notcontains $Name) { throw "unexpected checksum entry: $Name" }
108
+ if ($Expected.ContainsKey($Name)) { throw "duplicate checksum entry: $Name" }
109
+ $Expected[$Name] = $Digest
110
+ }
111
+ foreach ($Name in $Required) {
112
+ if (-not $Expected.ContainsKey($Name)) { throw "missing checksum entry: $Name" }
113
+ $Got = (Get-FileHash -Algorithm SHA256 -Path $Name).Hash.ToLowerInvariant()
114
+ if ($Got -ne $Expected[$Name]) {
115
+ throw "${Name}: expected $($Expected[$Name]), got $Got"
116
+ }
117
+ }
118
+ python -m pip install $Wheel
119
+ }
120
+ ```
121
+
122
+ `plexus-mesh` is not published on PyPI in this release track. A source branch or
123
+ CI run is not a release; install from the GitHub `v0.2.1` assets only after the
124
+ wheel, sdist, and `SHA256SUMS.txt` are attached to that release.
125
+
126
+ ```
127
+ $ plexus discover --builtin
128
+ $ plexus plan --goal crucible
129
+ $ plexus route --from gather --to crucible
130
+ $ plexus graph --format mermaid # a diagram of the whole mesh
131
+ $ plexus run --goal crucible # a runnable pipeline script
132
+ $ plexus mcp # stdio MCP server for agents to query live
133
+ ```
134
+
135
+ An agent (Claude Code or any MCP client) can point at `plexus mcp` and call
136
+ `plexus_discover` / `plexus_plan` / `plexus_route` while it works, so the mesh is
137
+ consumable mid-task, not just from a human's terminal.
138
+
139
+ How it compares to MCP / LangGraph / Dagster / CrewAI: see [COMPARISON.md](COMPARISON.md).
140
+ plexus is the discovery layer that sits *above* an executor, not another executor.
141
+
142
+ <p align="center"><img src="docs/art/wiring-lane.svg" alt="Eight stages from manifest to verify, ending in still holds or drifted." width="100%"></p>
143
+
144
+ ## The problem
145
+
146
+ You wire up a set of tools. Each one produces artifacts and accepts inputs, but
147
+ nothing knows how they connect, so you hand-wire `A | B | C` every time and
148
+ rediscover the plumbing on every new task. plexus makes the toolchain
149
+ self-describing: each tool ships a small manifest of what it emits and consumes,
150
+ and plexus computes the wiring graph: which tool's output is which tool's input.
151
+
152
+ ## What you get
153
+
154
+ **Discover the mesh.** Producer-to-consumer edges by capability, shown here as
155
+ an excerpt:
156
+
157
+ ```
158
+ $ plexus wiring --builtin
159
+ {
160
+ "canon.capsule/v1": [["canon","canon"]],
161
+ "canon.record/v1": [["canon","canon"]],
162
+ "crucible.replay-pack/1": [["mneme", "crucible"]],
163
+ "crucible.replay-template/1": [["crucible", "mneme"]],
164
+ "crucible.thesis/1": [["mneme", "crucible"]],
165
+ "gather.digest/1": [["gather", "crucible"]],
166
+ "gather.items/1": [["gather", "mneme"]],
167
+ "index.verification/1": [["index", "crucible"]],
168
+ "project-telos.flagship-action/v1": [["crucible","index"],["forum","index"],["gather","index"]],
169
+ "relay.rvc/v1": [["relay","relay"]],
170
+ "relay.session-ledger/1": [["relay","relay"]]
171
+ }
172
+ ```
173
+
174
+ The Mneme/Crucible replay loop is bidirectional and schema-exact: Crucible emits
175
+ `crucible.replay-template/1` for Mneme to consume, and Mneme emits
176
+ `crucible.replay-pack/1` for Crucible to consume. The existing
177
+ `crucible.thesis/1` Mneme→Crucible route remains a separate declared edge,
178
+ satisfied by Mneme's native `mneme.crucible-export/2` export.
179
+
180
+ **Plan a pipeline.** "I want to feed `crucible`. What produces its inputs?"
181
+
182
+ ```
183
+ $ plexus plan --goal crucible
184
+ order: forum -> gather -> crucible -> index -> learn -> mneme -> telos
185
+ sources: forum, gather
186
+ cyclic: crucible, index, learn, mneme, telos # feedback loops, reported not hidden
187
+ ```
188
+
189
+ **Route between two tools.** "I have `gather` output and want a `crucible`
190
+ verdict. How do they connect?"
191
+
192
+ ```
193
+ $ plexus route --from gather --to crucible
194
+ [gather -> crucible via gather.digest/1]
195
+ ```
196
+
197
+ **A plan you can re-verify.** Every `plan` and `route` carries a receipt that binds the
198
+ wiring to the exact manifests it came from: the content hash of every organ, plus a hash
199
+ over the derived plan. Save a plan, and later re-check it against the live mesh:
200
+
201
+ ```
202
+ $ plexus plan --goal crucible --builtin > plan.json
203
+ $ plexus verify --plan plan.json --builtin # exit 0 if it still holds, 1 if it drifted
204
+ ```
205
+
206
+ `verify` re-derives the plan from the manifests (it never trusts the saved body), so a
207
+ tampered plan is caught, and a tool whose manifest changed since the plan makes the wiring
208
+ drift **visible** instead of letting it silently shift under you. Exit non-zero on drift,
209
+ so it works as a CI check over your toolchain's wiring.
210
+
211
+ Two things make that check worth running. `verify` rebuilds the receipt from the
212
+ plan it just re-derived, not from the one saved in the file, so editing the saved
213
+ body cannot make it agree with itself. And the receipt carries a method version
214
+ that has to match before anything else is compared, so a plan written by an older
215
+ plexus is reported as failing rather than silently re-interpreted under new rules.
216
+
217
+ ## How a tool plugs in
218
+
219
+ A manifest is plain JSON. A tool ships one and it joins the mesh. Drop
220
+ `*.interop.json` files in a directory and `plexus discover --dir DIR` reads them:
221
+
222
+ ```json
223
+ {
224
+ "organ": "mytool",
225
+ "invoke": {"cli": "mytool", "mcp_server": "mytool.mcp:serve", "python_import": "mytool"},
226
+ "emits": [
227
+ {"capability": "mytool.report/1", "title": "analysis report",
228
+ "module": "src/mytool/report.py:build", "consumable_as": ["crucible.thesis/1"]}
229
+ ],
230
+ "consumes": [
231
+ {"capability": "gather.digest/1", "title": "evidence intake",
232
+ "module": "src/mytool/intake.py:load"}
233
+ ]
234
+ }
235
+ ```
236
+
237
+ An edge `A -> B` forms when `B` consumes a capability that `A` emits (directly,
238
+ or via `consumable_as`, the way a producer declares "my output is also
239
+ consumable as X"). Matching is by capability string, so an edge exists wherever
240
+ the tools DECLARE compatible capabilities. Declarative discovery does not run the tools, so the edge is a declared claim, not a probed result.
241
+
242
+ Plexus commits the built-in registry's exported JSON manifests under
243
+ [`manifests/`](manifests/). Discovery from these Plexus-side files produces the
244
+ same declared mesh as the built-in registry, as checked by a round-trip test.
245
+ Their presence here does not establish that each tool publishes its own manifest
246
+ or that a declared route has been exercised.
247
+
248
+ ### Extended manifests (September 2026)
249
+
250
+ The registry now covers **ten organs**. Canon and Relay are the two visible
251
+ flagship roles for context and connectivity; Index, mneme, and Plexus keep their
252
+ component boundaries instead of being collapsed into a database or executor.
253
+
254
+ - **canon**: context and continuity flagship. It declares the shipped record
255
+ envelope, continuity capsule, readiness probe, bootstrap witness, and read-only
256
+ MCP surface. It does not declare universal context capture or shared preflight
257
+ as shipped.
258
+ - **relay**: connectivity and execution flagship. It declares the endpoint
259
+ ladder, MCP run request/result surfaces, hash-chained session ledgers,
260
+ Relay-Verified-Correctness certificates, and remote MCP endpoint. It does not
261
+ declare Canon capsules or Plexus route receipts as consumed until Relay ships
262
+ that adapter.
263
+ - **mneme**: memory recall, provenance chain, and drift component. It remains a
264
+ component under the context role, with its CLI/MCP compatibility intact.
265
+ - **index**: gatherer and source-context component. It still owns workspace
266
+ scanning, context envelopes, freshness, and verification outputs; those are
267
+ derived evidence, not authoritative memory.
268
+ - **learn**: tutor credential/mastery ledger entries, proof lessons,
269
+ misconceptions. Consumes crucible theses for proof-lesson derivation.
270
+ - **telos**: room summary, golden workflow verification, workbench status.
271
+ Consumes flagship-action envelopes for cross-tool reconciliation.
272
+ - **flywheel-infra**: 10 capabilities from the Flywheel infrastructure
273
+ controls (egress, lesson, tool-call-receipt, TADR classification,
274
+ governance envelope, credential scan, correlated event, isolation test,
275
+ kill switch, run BOM). Consumes accountable-surface actuation outcomes,
276
+ mneme drift reports, and learn misconceptions for lesson derivation.
277
+
278
+ ### Probe mode
279
+
280
+ `probe_lane(name)` actually spawns a lane's MCP server and calls
281
+ `tools/list` + `status`, returning `{reachable, tools, error}`. Unlike the
282
+ declared manifest (which cites source files without running them), the probe
283
+ verifies the lane is live. `probe_all()` probes every registered lane.
284
+
285
+ ```python
286
+ from plexus.registry import probe_all
287
+ results = probe_all(timeout=10)
288
+ for r in results:
289
+ print(f"{r['name']:20} reachable={r['reachable']} tools={len(r['tools'])}")
290
+ ```
291
+
292
+ ## Declared, not probed
293
+
294
+ <p align="center"><img src="docs/art/edge-evidence.svg" alt="The six keys plexus discover returns for one wiring edge, one to a row, each with what settled it. Four are computed by discovery: the producing organ, the consuming organ, the capability that matched, and whether both ends are the same organ. One is copied out of a manifest without being read: via, the producer's own pointer at the code behind the port. One is a constant: evidence, always the word declared. The via row is accented, because it is the field that looks like a citation and is the one plexus never follows." width="100%"></p>
295
+
296
+ Every edge is tagged `evidence: "declared"` and cites the **module** its producer
297
+ names as the source (`file:function`). Declarative discovery does not import,
298
+ resolve, or run that pointer, so the citation is a self-reported claim to check,
299
+ not a verified receipt. The running tool re-checks none of the built-in manifests, so treat
300
+ every edge as declared until you follow the pointer yourself. Mneme's contract
301
+ was refreshed from public main on 2026-09-14, including
302
+ `mneme.crucible-export/2` and `mneme.local-origin-recheck/1`. Canon and Relay
303
+ were added from public origin-main source on 2026-09-16, and their manifests use
304
+ only repo-relative public paths. They intentionally leave Canon-to-Relay and
305
+ Relay-to-Plexus routes disconnected until a public shipped consumer exists.
306
+
307
+ plexus is also honest about what does **not** connect:
308
+
309
+ - `orphans().unmet_inputs`: capabilities something consumes that nothing in the
310
+ set emits (an external or human input).
311
+ - `orphans().unconsumed_outputs`: artifacts nobody downstream consumes (terminal
312
+ outputs).
313
+ - `plan(...).cyclic`: feedback loops, surfaced instead of forced into a false
314
+ linear order.
315
+ - `discover().collisions`: organ ids declared by more than one manifest, named
316
+ rather than silently resolved last-writer-wins.
317
+
318
+ <p align="center"><img src="docs/art/honesty-lane.svg" alt="Eight stages from a tool set to a report, ending in wired, colliding, or unmet." width="100%"></p>
319
+
320
+ An unmet input is a capability something consumes that nothing in the set emits,
321
+ and an unconsumed output is the mirror of it. Both fall out of the same
322
+ comparison, so neither is a special case someone remembered to write. The set is
323
+ also exactly what you handed it: plexus reads the manifests present and reasons
324
+ about nothing else, which is why an unmet input means only that no manifest here
325
+ produces it, not that no such tool exists.
326
+
327
+ ## Receipt
328
+
329
+ `plexus discover` stamps a `receipt` on its output: the plexus version, a UTC
330
+ timestamp, and for every manifest read its `source` (`builtin:registry` or the
331
+ file path) plus a `sha256` over the manifest's canonical content. The hash binds
332
+ what was declared, so a stranger can recompute it from the same bytes and pin the
333
+ mesh to exactly the manifests that produced it.
334
+
335
+ ## Install
336
+
337
+ ```
338
+ python -m pip install plexus_mesh-0.2.1-py3-none-any.whl
339
+ ```
340
+
341
+ Use the GitHub release asset and verify it against `SHA256SUMS.txt` first. This
342
+ repository does not claim a PyPI publication for `plexus-mesh` in the 0.2.1
343
+ track. The installed package covers declared and synthetic mesh workflows; it
344
+ does not prove that real external lanes are live or that `probe_lane()` has been
345
+ run against owned services.
346
+
347
+ ## Library
348
+
349
+ ```python
350
+ from plexus import (builtin_manifests, discover, plan_to, route,
351
+ to_mermaid, pipeline_script)
352
+
353
+ mesh = discover(builtin_manifests())
354
+ mesh.edges # every producer -> consumer edge, each tagged declared
355
+ mesh.wiring() # capability -> [(producer, consumer)]
356
+ mesh.orphans() # unmet inputs / unconsumed outputs
357
+ plan_to(mesh, "crucible") # the upstream pipeline (+ any cycles)
358
+ route(mesh, "gather", "crucible") # the capability path between two tools
359
+ to_mermaid(mesh) # a Mermaid diagram of the mesh
360
+ pipeline_script(mesh, "crucible") # a runnable shell pipeline
361
+ ```
362
+
363
+ ## License
364
+
365
+ Plexus is fair-source: open to read, run, and build on, with commercial use reserved so the project can fund its own development. See [LICENSE](LICENSE).
366
+
367
+ ## What this believes
368
+
369
+ This tool is one part of a family that holds a single belief steady across
370
+ every surface: knowledge open to anyone who can attain the means; acceptance
371
+ decided by external checks, never reputation; every result re-runnable;
372
+ honest nulls first-class; ownership earned by comprehension; learning woven
373
+ into the work. The full text lives in [CREDO.md](CREDO.md).
374
+ The long form of this belief: [The Unbundling](https://github.com/HarperZ9/flywheel/blob/fix/release-model-identity/docs/essays/2026-07-13-the-unbundling.md).
375
+
376
+ ---
377
+
378
+ **[Zentropy Labs](https://github.com/ZentropyLabs-ai)** · order out of entropy. An independent lab building evidence-first tools that leave a re-checkable artifact behind. Built by Zain Dana Harper in Seattle. The full workbench is at [Project Telos](https://harperz9.github.io).