@trokster/chem
v0.0.1
Published
Run agents on a Freenet task contract: identity, subscription, convergence, signing.
Maintainers
Readme
chem
"Words in the head. The chem is the golem."
A library for running agents on a Freenet task contract.
A golem cannot act without a chem — the written words in its head that give it purpose. That is what a task is here: a signed record that makes a worker act. The library gives an agent an identity, points it at a contract it has been granted access to, and lets it contribute the one thing it is allowed to contribute — testimony.
What it is not
It is not an agent framework, a prompt library, or a scheduler. It is the part between a running agent and a replicated task list: identity, subscription, convergence, and signing.
The shape
your agent process freenet node contract
───────────────── ──────────── ────────
new Golem({ handle, key }) ──────────► subscribe ────────────────► tasks
│ │
│ ◄── on(change) ───────────────────┘ merged state
│
├─ status_of(task) ← the same monotone fold every peer runs
│
└─ assert(task, 'achieved', {evidence}) ──► signed ──► UPDATE ──► mergeWhat an agent may and may not do
The asymmetry is the whole design, and it is enforced by keys rather than by policy:
| | needs | who has it | |---|---|---| | read a task | the task's content key, granted per task | the agent, if opted in | | assert something about it | its own signing key | the agent | | make it true | a quorum the goal names | usually a human |
An agent has an identity — an ed25519 keypair and a handle — and is a member of the list like anyone else. It signs its own assertions and nothing else. It can say "I did this, here is the evidence"; whether that counts is decided by the task's goal, which the agent does not write.
Two implementations, pinned together
The JS reimplements two things the Rust contract already defines: the signing bytes, and the monotone fold. Both are needed client-side, and both fail silently when they drift.
- Wrong signing bytes → every assertion is dropped at validation. The golem gets no error; the task list simply never changes.
- A wrong fold → the golem works forever on tasks the network finished last week.
Neither raises anything, and both sides stay internally consistent — which is why
they are not trusted to agree. contract/tests/conformance.rs generates vectors
into test/fixtures/, test/conformance.test.js replays them, and a delta the
JS actually emitted is replayed back through the contract's real update_state.
A drift in either direction is a failing test that names the field.
npm run test:all # both suites
npm run bless # regenerate the vectors, then verify — review the diffTESTING.md records the rest of the discipline, and every rule in it was bought
with a real bug.
Everything that knows what a byte looks like lives in src/wire.js. No other
file should learn.
Against a live node
npm run test:all verifies chem against the contract. It cannot verify chem
against the network, which is a different question — four of the five faults
found in src/node.js were invisible to every other test here, and three of them
produced no error at all (a duplicated query parameter that turned every request
into a silent hang, a missing handler that threw where the answer was invisible,
and notifications routed by a field that does not exist).
node scripts/live-smoke.mjs <address> [--ws <url>]It stands a list up, admits an agent and a human, sets a goal that names both, and checks that the agent's own testimony does NOT close the task while the human's countersignature does. Then it confirms a subscribed golem is told about work it never asked for. It needs a running node and a published contract, and it writes to whatever address you point it at.
Status
Early, but the loop runs: identity, subscription, the fold, signing, and the asymmetry have all been exercised against a live node.
DESIGN.md is self-contained — this repository does not require another one to be
present, and the contract it targets is in contract/. The model was argued out
in the hex-freenet project chem was extracted from, whose specs carry the
reasoning and the measurements; that is context for anyone who wants to know
why, not a dependency for anyone who wants to use it.
