Koinii cross-seat dereference: the DISTRIBUTED topology, where independent seats — separate processes, each holding its own copy of the KB — stay in sync by content-addressed commits rather than by sharing one live daemon. A seat asserts a sentence and commits; another seat pulls the same commit and resolves the same sentence from its own KB. The locator travels over a transport; the proof comes from the KB, and neither seat trusts the marker.
A different deployment shape from koinii's default (N agents funnelling writes through
one single-writer daemon — docs/koinii.md, The deployment shape). There the
daemon IS the shared KB and dereference is a plain read; here each seat is its own
reader with its own store, and the shared reference point is a commit, not a socket.
Complements, not rivals: the daemon for live co-writing, this for disconnected or
independently-replicated seats.
The spike's vocabulary, mapped to real primitives:
kb;
every function takes one, exactly as the other koinii modules do.locator), plus the untrusted transport payload that carries it (the marker).dereference finds the sentence in the seat's own store, reads its
provenance, and hands off to why for the proof.Three ideas, each grounded on a primitive that ships:
"sha256:" followed by 64 lowercase hex chars — over a sentex's canonical
identity (its context, truth polarity, and canonicalized sentence,
docs/canonicalization.md). Three best-practice commitments live in that one string:
dereference
rehashes the resolved form and compares — and SHA-1 has practical chosen-prefix
collisions, so it is the wrong primitive for this job."sha256:" multihash-style tag names the algorithm in
the value itself, so a later migration to another primitive is unambiguous rather
than a silent reinterpretation of 64 anonymous hex chars.pr-str. The digest input is the explicit,
type-tagged, self-delimiting byte encoding of canonical-bytes — independent of
ambient *print-* vars and injective across the value space a sentence holds, so
a symbol never digests as the like-spelled string and (a b) never as (a (b)).
Two seats holding the same assertion compute the same locator, because v/import!
re-canonicalizes every record through the reading build's own constructor.commit-id is the RFC-6962-style
Merkle root over the seat's sorted per-sentex leaf digests — leaf hashing
domain-separated with a 0x00 byte and internal-node hashing with 0x01, so a leaf
can never be forged as an internal node — prefixed "sha256:". Order- and
handle-independent by construction, so two seats that reached the same set of
assertions by different routes compute the same commit id (belief and storage are
order-independent — docs/nmtms.md), and a KB exported, pulled and recovered on
another seat carries the id across. The Merkle shape (over the old flat re-hash) buys
pure auditability: inclusion-proof yields an audit path and verify-inclusion
recomputes the root from just a (locator, proof) pair — no KB — which a flat digest
cannot. commit-id fingerprints knowledge (what two seats compare to agree they
hold the same thing); state-root is a second root whose leaves fold each record's
provenance (:creator + :created + identity), a full snapshot identity like a
git commit (covers who/when), so it moves when provenance moves even when content does
not. publish! / pull! move the bytes (via v/export! / v/import!); the roots
are what say two seats hold the same knowledge (and the same snapshot).dereference finds the sentence in the seat's own KB
and rehashes what it found; a stale or tampered marker fails that check and is
rejected, and a marker the seat cannot resolve means the commit was not received —
never that the marker's payload should be believed. Attribution is trustworthy only
as far as the identity model makes it: a distributed KB inherits the same
cooperative-vs-proof-tier question.Additive, like the other koinii modules: only the public core API plus protocols
(to walk the record store) and resolution (to canonicalize a sentence the store's
own way) — nothing in core loads it.
Koinii cross-seat dereference: the DISTRIBUTED topology, where
independent *seats* — separate processes, each holding its own copy of the KB — stay
in sync by **content-addressed commits** rather than by sharing one live daemon. A
seat asserts a sentence and commits; another seat pulls the same commit and resolves
the same sentence **from its own KB**. The locator travels over a transport; the
proof comes from the KB, and neither seat trusts the marker.
A different deployment shape from koinii's default (N agents funnelling writes through
one single-writer daemon — `docs/koinii.md`, *The deployment shape*). There the
daemon IS the shared KB and dereference is a plain read; here each seat is its own
reader with its own store, and the shared reference point is a commit, not a socket.
Complements, not rivals: the daemon for live co-writing, this for disconnected or
independently-replicated seats.
The spike's vocabulary, mapped to real primitives:
- **seat** — an independent KB-holding process. In this layer a seat is just a `kb`;
every function takes one, exactly as the other koinii modules do.
- **locator / marker** — a content-addressed reference to a canonical assertion (the
`locator`), plus the untrusted transport payload that carries it (the `marker`).
- **transport** — any byte-faithful channel that carries a marker. A marker is a
plain Clojure map, so any transport that ships EDN ships one.
- **the KB** — the sole authority for *meaning*. A marker is never trusted, only
resolved: `dereference` finds the sentence in the seat's own store, reads its
provenance, and hands off to `why` for the proof.
Three ideas, each grounded on a primitive that ships:
- **The locator is content-addressed, not handle-addressed.** A handle is a number
one store minted and does not travel; a locator is a **self-describing** digest — the
literal `"sha256:"` followed by 64 lowercase hex chars — over a sentex's **canonical
identity** (its context, truth polarity, and canonicalized sentence,
`docs/canonicalization.md`). Three best-practice commitments live in that one string:
* **SHA-256, not SHA-1.** A locator is a tamper-detection boundary — `dereference`
rehashes the *resolved* form and compares — and SHA-1 has practical chosen-prefix
collisions, so it is the wrong primitive for this job.
* **Self-describing.** The `"sha256:"` multihash-style tag names the algorithm in
the value itself, so a later migration to another primitive is unambiguous rather
than a silent reinterpretation of 64 anonymous hex chars.
* **A spec'd canonical encoding, not `pr-str`.** The digest input is the explicit,
type-tagged, self-delimiting byte encoding of `canonical-bytes` — independent of
ambient `*print-*` vars and injective across the value space a sentence holds, so
a symbol never digests as the like-spelled string and `(a b)` never as `(a (b))`.
Two seats holding the same assertion compute the **same** locator, because `v/import!`
re-canonicalizes every record through the reading build's own constructor.
- **The commit is a Merkle function of state.** `commit-id` is the RFC-6962-style
**Merkle root** over the seat's *sorted* per-sentex leaf digests — leaf hashing
domain-separated with a `0x00` byte and internal-node hashing with `0x01`, so a leaf
can never be forged as an internal node — prefixed `"sha256:"`. Order- and
handle-independent by construction, so two seats that reached the same set of
assertions by different routes compute the same commit id (belief and storage are
order-independent — `docs/nmtms.md`), and a KB exported, pulled and recovered on
another seat carries the id across. The Merkle shape (over the old flat re-hash) buys
pure auditability: `inclusion-proof` yields an audit path and `verify-inclusion`
recomputes the root from just a `(locator, proof)` pair — no KB — which a flat digest
cannot. `commit-id` fingerprints **knowledge** (what two seats compare to agree they
hold the same thing); `state-root` is a second root whose leaves fold each record's
provenance (`:creator` + `:created` + identity), a full **snapshot** identity like a
git commit (covers who/when), so it moves when provenance moves even when content does
not. `publish!` / `pull!` move the bytes (via `v/export!` / `v/import!`); the roots
are what say two seats hold the same knowledge (and the same snapshot).
- **The marker is untrusted.** `dereference` finds the sentence in the seat's own KB
and rehashes what it found; a stale or tampered marker fails that check and is
rejected, and a marker the seat cannot resolve means the commit was not received —
never that the marker's payload should be believed. Attribution is trustworthy only
as far as the identity model makes it: a distributed KB inherits the same
cooperative-vs-proof-tier question.
Additive, like the other koinii modules: only the public core API plus `protocols`
(to walk the record store) and `resolution` (to canonicalize a sentence the store's
own way) — nothing in core loads it.(commit-id kb)A content-addressed fingerprint of the seat's materialized knowledge — the RFC-6962
Merkle root over its sorted per-sentex content locators, prefixed "sha256:".
Order-independent and handle-independent by construction, so two seats holding the same
stored records compute the same commit id whatever order they were built in, and a KB
exported, pulled and recovered on another seat carries it across — the flow the
distributed topology uses: 'pull the same commit' is a git operation, 'agree on the
commit id' is this.
Scope is every STORED sentex — premises AND anything forward-derived — read as CONTENT
(context/truth/sentence, not provenance). So it fingerprints the materialized state,
not the bare assertions: two seats agree exactly when their stored sets match, which the
pull flow guarantees (pull replicates the store) but which independently-built seats meet
only if they also derived to the same extent (same rules, same *max-depth*). For
attribution-sensitive snapshot identity, see state-root.
A content-addressed fingerprint of the seat's **materialized knowledge** — the RFC-6962 Merkle root over its sorted per-sentex content locators, prefixed `"sha256:"`. Order-independent and handle-independent by construction, so two seats holding the same stored records compute the same commit id whatever order they were built in, and a KB exported, pulled and recovered on another seat carries it across — the flow the distributed topology uses: 'pull the same commit' is a git operation, 'agree on the commit id' is this. Scope is every STORED sentex — premises AND anything forward-derived — read as CONTENT (context/truth/sentence, not provenance). So it fingerprints the materialized *state*, not the bare assertions: two seats agree exactly when their stored sets match, which the pull flow guarantees (pull replicates the store) but which independently-built seats meet only if they also derived to the same extent (same rules, same `*max-depth*`). For attribution-sensitive snapshot identity, see `state-root`.
(dereference kb marker)Resolve marker against the seat's OWN KB — the whole point of the distributed
model, and where the marker's untrustedness is enforced. Returns, on success:
{:resolved? true :handle h :locator <sha256:hex> :sentence S :context C
:truth t :seat <asserter> :provenance <map>}
and on failure {:resolved? false :reason … :locator <sha256:hex>}:
:not-received — the marker's sentence is not in this seat's store. The seat has
not pulled the commit that carries it; it does not fall back to trusting the
marker's payload.:locator-mismatch — the sentence IS stored, but the locator this seat computes for
it does not match the marker's. The marker is stale or tampered: the locator is
self-verifying (rehash the resolved canonical form and compare), and it is the
marker's payload, not the KB, that is rejected.So the marker is never load-bearing: meaning, attribution and (via why-marker) proof
all come from what this seat's KB actually holds.
Resolve `marker` against the seat's OWN KB — the whole point of the distributed
model, and where the marker's untrustedness is enforced. Returns, on success:
{:resolved? true :handle h :locator <sha256:hex> :sentence S :context C
:truth t :seat <asserter> :provenance <map>}
and on failure `{:resolved? false :reason … :locator <sha256:hex>}`:
- `:not-received` — the marker's sentence is not in this seat's store. The seat has
not pulled the commit that carries it; it does **not** fall back to trusting the
marker's payload.
- `:locator-mismatch` — the sentence IS stored, but the locator this seat computes for
it does not match the marker's. The marker is stale or tampered: the locator is
self-verifying (rehash the *resolved* canonical form and compare), and it is the
marker's payload, not the KB, that is rejected.
So the marker is never load-bearing: meaning, attribution and (via `why-marker`) proof
all come from what this seat's KB actually holds.(inclusion-proof kb locator)The audit path proving locator is a leaf of this seat's commit-id tree — a vector of
{:hash <sibling-hex> :side :left|:right} ordered leaf→root, or nil if the seat holds no
record with that locator. The point of the Merkle shape: a verifier fed this path plus
the leaf locator and the published root can confirm inclusion via verify-inclusion
without the KB — which the old flat re-hash could not offer.
The audit path proving `locator` is a leaf of this seat's `commit-id` tree — a vector of
`{:hash <sibling-hex> :side :left|:right}` ordered leaf→root, or nil if the seat holds no
record with that locator. The point of the Merkle shape: a verifier fed this path plus
the leaf `locator` and the published root can confirm inclusion via `verify-inclusion`
**without** the KB — which the old flat re-hash could not offer.(locate kb sentence context)The locator sentence in context would have, computed without requiring it be
stored: sentence is canonicalized through the store's own constructor
(v/canonical-sentex, which sorts a symmetric predicate's arguments against this KB's
taxonomy) and its identity digested. So (locate kb S C) equals (locator-of kb h)
for the handle h that S/C resolves to — the content-address is a function of the
assertion, not of whether or where it was stored, and not of the number it landed on.
The locator `sentence` in `context` **would** have, computed without requiring it be stored: `sentence` is canonicalized through the store's own constructor (`v/canonical-sentex`, which sorts a symmetric predicate's arguments against this KB's taxonomy) and its identity digested. So `(locate kb S C)` equals `(locator-of kb h)` for the handle `h` that `S`/`C` resolves to — the content-address is a function of the assertion, not of whether or where it was stored, and not of the number it landed on.
(locator-index kb)A {locator → handle} index over the seat's own KB — the reverse of locator-of,
built by one walk of the record store. Injective: two sentexes share a locator only
if they share a canonical identity, which the store already deduped to one handle.
This is what lets a bare locator (a marker with no payload) resolve at all, so it
witnesses that the payload marker carries is a convenience, not a trust anchor. Keyed
on the full "sha256:"-prefixed locator string.
A `{locator → handle}` index over the seat's own KB — the reverse of `locator-of`,
built by one walk of the record store. Injective: two sentexes share a locator only
if they share a canonical identity, which the store already deduped to one handle.
This is what lets a **bare** locator (a marker with no payload) resolve at all, so it
witnesses that the payload `marker` carries is a convenience, not a trust anchor. Keyed
on the full `"sha256:"`-prefixed locator string.(locator-of kb handle)The locator of the stored sentex at handle — "sha256:" + hex SHA-256 of its
canonical identity. Independent of the handle, so it is reproducible on any seat that
holds the same assertion. nil if the handle names no record.
The locator of the stored sentex at `handle` — `"sha256:"` + hex SHA-256 of its canonical identity. Independent of the handle, so it is reproducible on any seat that holds the same assertion. nil if the handle names no record.
(marker kb handle)The transportable marker for the assertion at handle — what a seat sends over a
transport so another seat can dereference it:
{:locator <sha256:hex> :sentence <asserted form> :context <ctx> :seat <claimed>}
The :locator is the load-bearing part; :sentence / :context are a lookup payload
the receiver does NOT trust for meaning (it resolves against its own KB and rehashes
what it finds), and :seat is the claimed asserter — the real one comes off the
resolved sentex's provenance. Throws if handle names no record.
The transportable marker for the assertion at `handle` — what a seat sends over a
transport so another seat can dereference it:
{:locator <sha256:hex> :sentence <asserted form> :context <ctx> :seat <claimed>}
The `:locator` is the load-bearing part; `:sentence` / `:context` are a lookup payload
the receiver does NOT trust for meaning (it resolves against its own KB and rehashes
what it finds), and `:seat` is the *claimed* asserter — the real one comes off the
resolved sentex's provenance. Throws if `handle` names no record.(publish! kb dir)(publish! kb dir opts)Write the seat's KB out as a portable export dump in dir, the form a git host
carries: v/export! with :compression :none so the record streams are a
byte-stable function of the KB — gzip stamps a header timestamp, which would make the
same state export to different bytes. dir must be absent or empty. Returns
export!'s summary; the commit the other seats pull is this directory.
Write the seat's KB out as a portable export dump in `dir`, the form a git host carries: `v/export!` with `:compression :none` so the record streams are a byte-stable function of the KB — gzip stamps a header timestamp, which would make the same state export to different bytes. `dir` must be absent or empty. Returns `export!`'s summary; the commit the other seats pull is this directory.
(pull! kb dir)(pull! kb dir opts)Open a pulled commit into the (empty) seat kb: v/import! the dump at dir, which
re-canonicalizes every record through this build's constructor and recovers belief —
the property that makes this seat compute the same locators as the seat that published.
Returns import!'s summary.
Open a pulled commit into the (empty) seat `kb`: `v/import!` the dump at `dir`, which re-canonicalizes every record through this build's constructor and recovers belief — the property that makes this seat compute the same locators as the seat that published. Returns `import!`'s summary.
(resolve-by-locator kb locator)(resolve-by-locator kb locator index)Resolve a bare locator string against the seat's own KB via index (default: a
freshly built locator-index) — the pure content-addressed dereference, with no payload
to distrust. Same success/failure shape as dereference; a locator absent from the
index is :not-received (the seat does not hold the commit that carries it).
Resolve a bare `locator` string against the seat's own KB via `index` (default: a freshly built `locator-index`) — the pure content-addressed dereference, with no payload to distrust. Same success/failure shape as `dereference`; a locator absent from the index is `:not-received` (the seat does not hold the commit that carries it).
(state-root kb)A content-addressed snapshot identity of the seat's exported records — the same
Merkle construction as commit-id, but over leaves that fold each record's provenance
(:creator + :created) in with its identity. Git-commit-like: it covers who and
when, so it moves when provenance moves even if the content (and thus commit-id) does
not. Two seats compare commit-id to agree they hold the same knowledge; they
compare state-root to agree they hold the same snapshot — a clone that pulled and
recovered identical provenance matches here too.
A content-addressed **snapshot** identity of the seat's exported records — the same Merkle construction as `commit-id`, but over leaves that fold each record's provenance (`:creator` + `:created`) in with its identity. Git-commit-like: it covers who and when, so it moves when provenance moves even if the content (and thus `commit-id`) does not. Two seats compare `commit-id` to agree they hold the same *knowledge*; they compare `state-root` to agree they hold the same *snapshot* — a clone that pulled and recovered identical provenance matches here too.
(verify-inclusion locator proof root)PURE verification that locator is included under root given proof — recompute the
Merkle root from the leaf digest of locator and the audit path's sibling hashes, and
compare to root. Takes no KB: (root, proof, locator) is all a verifier needs, which
is the whole reason commit-id is a tree and not a flat digest. Domain separation
(0x00 leaf / 0x01 node) is enforced on both sides, so a sibling cannot be forged
across leaf/internal roles.
Fails closed on a malformed proof. The proof is untrusted transport data, so a
non-hex sibling, a missing :hash/:side, or a non-sequential proof returns false
rather than throwing — an unverifiable proof is not a valid one.
PURE verification that `locator` is included under `root` given `proof` — recompute the Merkle root from the leaf digest of `locator` and the audit path's sibling hashes, and compare to `root`. Takes no KB: `(root, proof, locator)` is all a verifier needs, which is the whole reason `commit-id` is a tree and not a flat digest. Domain separation (`0x00` leaf / `0x01` node) is enforced on both sides, so a sibling cannot be forged across leaf/internal roles. **Fails closed on a malformed proof.** The proof is untrusted transport data, so a non-hex sibling, a missing `:hash`/`:side`, or a non-sequential proof returns `false` rather than throwing — an unverifiable proof is not a valid one.
(why-marker kb marker)Dereference marker and, when it resolves, attach the proof v/why builds for it —
the seam a cross-seat proof-identity layer grows into. The marker names WHAT to
prove by content; the proof itself is the seat's own, drawn from its own justification
graph. Returns the dereference map, with :why added on success.
Dereference `marker` and, when it resolves, attach the proof `v/why` builds for it — the seam a cross-seat proof-identity layer grows into. The marker names WHAT to prove by content; the proof itself is the seat's own, drawn from its own justification graph. Returns the `dereference` map, with `:why` added on success.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |