Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# The artwork under docs/art/ is generated, and a gate compares the committed
# bytes to a fresh render. Normalizing line endings per platform would make that
# comparison depend on who checked the repository out.
docs/art/*.svg text eol=lf
docs/art/*.json text eol=lf
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<p align="center"><img src=".github/assets/zentropy-banner.png" alt="plexus" width="100%"></p>
<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>

# plexus

Expand Down Expand Up @@ -29,6 +29,8 @@ consumable mid-task, not just from a human's terminal.
How it compares to MCP / LangGraph / Dagster / CrewAI: see [COMPARISON.md](COMPARISON.md).
plexus is the discovery layer that sits *above* an executor, not another executor.

<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>

## The problem

You wire up five tools. Each one produces artifacts and accepts inputs, but
Expand Down Expand Up @@ -90,6 +92,12 @@ tampered plan is caught, and a tool whose manifest changed since the plan makes
drift **visible** instead of letting it silently shift under you. Exit non-zero on drift,
so it works as a CI check over your toolchain's wiring.

Two things make that check worth running. `verify` rebuilds the receipt from the
plan it just re-derived, not from the one saved in the file, so editing the saved
body cannot make it agree with itself. And the receipt carries a method version
that has to match before anything else is compared, so a plan written by an older
plexus is reported as failing rather than silently re-interpreted under new rules.

## How a tool plugs in

A manifest is plain JSON. A tool ships one and it joins the mesh. Drop
Expand Down Expand Up @@ -171,6 +179,15 @@ plexus is also honest about what does **not** connect:
- `discover().collisions`: organ ids declared by more than one manifest, named
rather than silently resolved last-writer-wins.

<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>

An unmet input is a capability something consumes that nothing in the set emits,
and an unconsumed output is the mirror of it. Both fall out of the same
comparison, so neither is a special case someone remembered to write. The set is
also exactly what you handed it: plexus reads the manifests present and reasons
about nothing else, which is why an unmet input means only that no manifest here
produces it, not that no such tool exists.

## Receipt

`plexus discover` stamps a `receipt` on its output: the plexus version, a UTC
Expand Down
19 changes: 19 additions & 0 deletions docs/art/honesty-lane.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/art/plexus-header.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
141 changes: 141 additions & 0 deletions docs/art/plexus.art.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"header": {
"name": "plexus",
"role": "toolchain wiring discovery",
"tagline": "Point it at your tools and it computes how they plug together.",
"words": [
"emit",
"consume",
"wire",
"plan",
"declare"
]
},
"flows": [
{
"file": "wiring-lane.svg",
"kicker": "one tool set, one runnable order",
"title": "How a pile of tools becomes a plan you can check later",
"footnote": "Verify re-derives the plan from the manifests. The saved body is never trusted.",
"alt": "Eight stages from manifest to verify: manifest, discover, capability, wiring, goal, plan, receipt, verify. Each tool ships a small manifest naming what it emits and what it consumes. Discovery reads every manifest and hashes its canonical content. A capability is a typed name, and an edge exists wherever one tool emits a name another consumes. Naming a goal produces a dependency order with any feedback loops reported rather than forced flat. The receipt binds the plan to the content hash of every manifest behind it plus a hash over the plan body. Verify re-derives the plan from the live mesh and compares receipts, so a tampered body and a manifest that changed both fail. Two outcomes: still holds, and drifted.",
"stages": [
{
"title": "Manifest",
"note": "Each tool ships one: what it emits, what it needs."
},
{
"title": "Discover",
"note": "Every manifest read, and its content hashed."
},
{
"title": "Capability",
"note": "A typed name, on both sides of an edge."
},
{
"title": "Wiring",
"note": "An edge wherever a name matches across tools."
},
{
"title": "Goal",
"note": "The tool you want fed, named on the command line."
},
{
"title": "Plan",
"note": "An order over the graph, with cycles reported."
},
{
"title": "Receipt",
"note": "The plan hash, and every manifest hash behind it."
},
{
"title": "Verify",
"note": "Re-derive from the mesh, then compare receipts."
}
],
"returns": [
{
"from": 7,
"to": 5,
"label": "VERIFY NEVER TRUSTS THE SAVED PLAN BODY"
}
],
"outcomes": [
{
"label": "STILL HOLDS",
"note": "the same manifests re-derive the same plan",
"tone": "verified"
},
{
"label": "DRIFTED",
"note": "a manifest moved under the saved plan",
"tone": "drift"
}
]
},
{
"file": "honesty-lane.svg",
"kicker": "one mesh, and what it will not pretend",
"title": "How the parts that do not connect get named instead of hidden",
"footnote": "Every edge is declared by its producer. Nothing here imports or runs the source it cites.",
"alt": "Eight stages of the honesty surface: tool set, emits, consumes, match, leftover, loop, collision, report. Only the manifests present are considered. A capability name appearing on both an emit and a consume side becomes an edge. Every name that matched on only one side is a leftover: an unmet input that nothing in the set produces, or an output nobody downstream takes. A cycle is surfaced as a feedback loop rather than forced into a false linear order, and an organ id claimed by two manifests is named as a collision rather than resolved last writer wins. Three outcomes: wired, colliding, and unmet.",
"stages": [
{
"title": "Tool set",
"note": "The manifests present, and nothing else."
},
{
"title": "Emits",
"note": "What each one declares that it produces."
},
{
"title": "Consumes",
"note": "What each one declares that it needs."
},
{
"title": "Match",
"note": "A name on both sides becomes one edge."
},
{
"title": "Leftover",
"note": "Every name that matched on one side only."
},
{
"title": "Loop",
"note": "An edge set that returns where it started."
},
{
"title": "Collision",
"note": "One organ id claimed by two manifests."
},
{
"title": "Report",
"note": "Named in the output, never quietly resolved."
}
],
"returns": [
{
"from": 7,
"to": 4,
"label": "EACH LEFTOVER IS NAMED, ONE BY ONE"
}
],
"outcomes": [
{
"label": "WIRED",
"note": "every input has a producer in the set",
"tone": "verified"
},
{
"label": "COLLIDING",
"note": "two manifests claim the same organ id",
"tone": "drift"
},
{
"label": "UNMET",
"note": "an input nothing in the set emits",
"tone": "none"
}
]
}
]
}
Loading
Loading