Liking cljdoc? Tell your friends :D

vaelii.koinii.deref

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, 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 vaelii.core/digest hashes — 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 belief. 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:". The leaves are the records the seat believes, not everything it stores: a defeated default is retained on purpose and is no part of what the seat holds, so two seats that agree on every belief compute one id however differently their stores were built. Order- and handle-independent, so two seats that reached the same beliefs 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. A sentence that names a sentex by (sentexHandle n) — every koinii response act — digests the named record's own identity in place of n (v/digest), so a reply is located by its target and two seats that built one conversation in different orders agree on it. The Merkle shape 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. Resolution is scoped to BELIEF for the reason the commit is: a record the seat stores but does not believe is no part of what it holds, so dereference declines it exactly as inclusion-proof declines to prove it. A locator alone resolves nothing: the marker's sentence and context find the record, and the locator checks it. dereference also fails closed on a malformed payload, as verify-inclusion does on a malformed proof: a marker that is not a map, whose :locator is not this format, or whose sentence the engine declines to be asked about is ANSWERED :malformed rather than allowed to throw the engine's refusal out of the resolve path — a peer must not be able to crash a receiving seat by sending garbage. 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 — the record walk is handles / sentex, and the locator is digest / digests, so a seat digests what the store itself would. Beside it, koinii types. Nothing under vaelii.impl, and 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, 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 `vaelii.core/digest` hashes — 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 belief.**  `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:"`.  The leaves are the
  records the seat **believes**, not everything it stores: a defeated default is retained
  on purpose and is no part of what the seat holds, so two seats that agree on every
  belief compute one id however differently their stores were built.  Order- and
  handle-independent, so two seats that reached the same beliefs 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.  A sentence that names a sentex by `(sentexHandle n)` — every koinii
  response act — digests the named record's own identity in place of `n`
  (`v/digest`), so a reply is located by its target and two seats that built one
  conversation in different orders agree on it.  The Merkle shape 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.  Resolution is scoped to BELIEF
  for the reason the commit is: a record the seat stores but does not believe is no part
  of what it holds, so `dereference` declines it exactly as `inclusion-proof` declines to
  prove it.  A locator alone resolves nothing: the marker's sentence and context find the
  record, and the locator checks it.  `dereference` also **fails closed on a malformed
  payload**, as `verify-inclusion` does on a malformed proof: a marker that is not a
  map, whose `:locator` is not this format, or whose sentence the engine declines to be
  asked about is ANSWERED `:malformed` rather than allowed to throw the engine's
  refusal out of the resolve path — a peer must not be able to crash a receiving seat by
  sending garbage.  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 — the record walk
is `handles` / `sentex`, and the locator is `digest` / `digests`, so a seat digests
what the store itself would.  Beside it, koinii `types`.  Nothing under
`vaelii.impl`, and nothing in core loads it.
raw docstring

commit-idclj

(commit-id kb)

A content-addressed fingerprint of the seat's believed knowledge: the RFC-6962 Merkle root over its sorted per-sentex content locators, prefixed "sha256:". Order- and handle-independent, so two seats believing the same records compute the same id (a (sentexHandle n) inside a sentence digests the record it names, v/digest), and a KB exported, pulled and recovered on another seat carries it across.

Scope is every BELIEVED sentex, premises and forward-derived alike, read as CONTENT (context/polarity/sentence, not provenance). A stored-but-defeated sentex is not a leaf, so two seats agree exactly when their believed sets match: the pull flow guarantees that, and independently built seats meet it only if they derived to the same extent (same rules, same *max-depth*). For attribution-sensitive identity, see state-root.

A content-addressed fingerprint of the seat's **believed knowledge**: the RFC-6962 Merkle
root over its sorted per-sentex content locators, prefixed `"sha256:"`.  Order- and
handle-independent, so two seats believing the same records compute the same id (a
`(sentexHandle n)` inside a sentence digests the record it names, `v/digest`), and a KB
exported, pulled and recovered on another seat carries it across.

Scope is every BELIEVED sentex, premises and forward-derived alike, read as CONTENT
(context/polarity/sentence, not provenance).  A stored-but-defeated sentex is **not** a
leaf, so two seats agree exactly when their believed sets match: the pull flow guarantees
that, and independently built seats meet it only if they derived to the same extent (same
rules, same `*max-depth*`).  For attribution-sensitive identity, see `state-root`.
sourceraw docstring

dereferenceclj

(dereference kb marker)

Resolve marker against the seat's OWN KB, where the marker's untrustedness is enforced. Returns, on success:

{:resolved? true  :handle h  :locator <sha256:hex>  :sentence S  :context C
 :polarity t  :seat <asserter>  :provenance <map>}

and on failure {:resolved? false :reason … :locator <sha256:hex>}:

  • :malformed: not a marker, with :problem naming the part: :not-a-map, a :locator that is not "sha256:" + 64 hex, :no-sentence / :no-context, or the engine's refusal type (:shape, :unsupported-context). Fails closed: a hostile marker is answered, never allowed to throw out of the resolve path. Distinct from :not-received: one peer is out of sync, the other sends garbage.
  • :not-received: the sentence is not in this seat's store; the marker's payload is not trusted instead.
  • a target's reason, with :target naming the sender's handle number: a :targets record this seat does not resolve, or a malformed target marker (local-handle). A :targets value that is not a map of integers to markers, or a chain deeper than max-target-depth, is :malformed with :problem :targets.
  • :not-believed: the sentence is stored and not believed (docs/nmtms.md). The record has no leaf in the commit-id tree, so resolving it would hand back a record the seat can produce no proof of.
  • :locator-mismatch: stored and believed, but the locator this seat computes differs: the marker is stale or tampered.

Meaning, attribution and (via why-marker) proof all come from this seat's KB.

Resolve `marker` against the seat's OWN KB, where the marker's untrustedness is enforced.
Returns, on success:

    {:resolved? true  :handle h  :locator <sha256:hex>  :sentence S  :context C
     :polarity t  :seat <asserter>  :provenance <map>}

and on failure `{:resolved? false :reason … :locator <sha256:hex>}`:

- `:malformed`: not a marker, with `:problem` naming the part: `:not-a-map`, a `:locator`
  that is not `"sha256:"` + 64 hex, `:no-sentence` / `:no-context`, or the engine's
  refusal type (`:shape`, `:unsupported-context`).  **Fails closed**: a hostile marker is
  answered, never allowed to throw out of the resolve path.  Distinct from
  `:not-received`: one peer is out of sync, the other sends garbage.
- `:not-received`: the sentence is not in this seat's store; the marker's payload is not
  trusted instead.
- a target's reason, with `:target` naming the sender's handle number: a `:targets` record
  this seat does not resolve, or a malformed target marker (`local-handle`).  A `:targets`
  value that is not a map of integers to markers, or a chain deeper than
  `max-target-depth`, is `:malformed` with `:problem :targets`.
- `:not-believed`: the sentence is stored and not believed (`docs/nmtms.md`).  The record
  has no leaf in the `commit-id` tree, so resolving it would hand back a record the seat
  can produce no proof of.
- `:locator-mismatch`: stored and believed, but the locator this seat computes differs:
  the marker is stale or tampered.

Meaning, attribution and (via `why-marker`) proof all come from this seat's KB.
sourceraw docstring

inclusion-proofclj

(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 does not BELIEVE a record with that locator. A verifier fed this path, the leaf locator and the published root confirms inclusion via verify-inclusion without the KB. It folds the same believed leaves as commit-id, so a stored-but-defeated record answers nil.

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 does not
BELIEVE a record with that locator.  A verifier fed this path, the leaf `locator` and the
published root confirms inclusion via `verify-inclusion` **without** the KB.  It folds
the same believed leaves as `commit-id`, so a stored-but-defeated record answers nil.
sourceraw docstring

locateclj

(locate kb sentence context)

The locator sentence in context would have, computed without requiring it be stored (v/digest's three-arity): (locate kb S C) equals (locator-of kb h) for the handle h that S/C resolves to.

The locator `sentence` in `context` **would** have, computed without requiring it be
stored (`v/digest`'s three-arity): `(locate kb S C)` equals `(locator-of kb h)` for the
handle `h` that `S`/`C` resolves to.
sourceraw docstring

locator-ofclj

(locator-of kb handle)

The locator of the stored sentex at handle (v/digest): independent of the handle, so reproducible on any seat that holds the same assertion. nil if the handle names no record.

The locator of the stored sentex at `handle` (`v/digest`): independent of the handle,
so reproducible on any seat that holds the same assertion.  nil if the handle names no
record.
sourceraw docstring

markerclj

(marker kb handle)

The transportable marker for the assertion at handle, which a seat sends over a transport so another seat can dereference it:

{:locator <sha256:hex>  :sentence <asserted form>  :context <ctx>  :seat <claimed>
 :targets {n <marker> …}}

The :locator decides it; :sentence / :context are a lookup payload the receiver does NOT trust (it resolves against its own KB and rehashes), and :seat is the claimed asserter, the real one coming off the resolved sentex's provenance. Throws if handle names no record. :targets carries the marker of every record the sentence names: a reply's sentence holds (sentexHandle n) with this seat's number, which a seat that built the same conversation itself numbers differently. dereference resolves each target on its own seat first and substitutes the handle it finds. The key is absent when the sentence names no stored record; a handle already on the chain being built is left out (marker-at).

The transportable marker for the assertion at `handle`, which a seat sends over a
transport so another seat can dereference it:

    {:locator <sha256:hex>  :sentence <asserted form>  :context <ctx>  :seat <claimed>
     :targets {n <marker> …}}

The `:locator` decides it; `:sentence` / `:context` are a lookup payload the receiver does
NOT trust (it resolves against its own KB and rehashes), and `:seat` is the *claimed*
asserter, the real one coming off the resolved sentex's provenance.  Throws if `handle`
names no record.  **`:targets` carries the marker of every record the sentence names**:
a reply's sentence holds `(sentexHandle n)` with this seat's number, which a seat that
built the same conversation itself numbers differently.  `dereference` resolves each target
on its own seat first and substitutes the handle it finds.  The key is absent when the
sentence names no stored record; a handle already on the chain being built is left out
(`marker-at`).
sourceraw docstring

publish!clj

(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 writes a header timestamp). dir must be absent or empty. Returns export!'s summary; the commit the other seats pull is this directory. :compression is fixed: anything but :none is refused (:koinii/compression-fixed); a caller that wants a compressed dump wants v/export!. Every other export! option passes through.

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 writes a header timestamp).  `dir` must be absent or empty.  Returns
`export!`'s summary; the commit the other seats pull is this directory.
**`:compression` is fixed**: anything but `:none` is refused
(`:koinii/compression-fixed`); a caller that wants a compressed dump wants `v/export!`.
Every other `export!` option passes through.
sourceraw docstring

pull!clj

(pull! kb dir)
(pull! kb dir opts)

Open a pulled commit into the seat kb: v/import! the dump at dir, which re-canonicalizes every record through this build's constructor and recovers belief, so this seat computes the same locators as the publisher. A seat that is a fork takes the dump as its base and keeps its own writes and their attestations over it (identity/rebase!); any other seat must be empty (:not-empty). Every provenance :principal is dropped (:drop-principal?). A seat registering a reasoner set other than the publisher's is refused (:reasoner-mismatch); {:reasoners :stored} registers the publisher's set. Returns import!'s summary.

Open a pulled commit into the seat `kb`: `v/import!` the dump at `dir`, which
re-canonicalizes every record through this build's constructor and recovers belief, so
this seat computes the same locators as the publisher.  A seat that is a fork takes the
dump as its base and keeps its own writes and their attestations over it
(`identity/rebase!`); any other seat must be empty (`:not-empty`).  Every provenance
`:principal` is dropped (`:drop-principal?`).  A seat registering a reasoner set other
than the publisher's is refused (`:reasoner-mismatch`); `{:reasoners :stored}` registers
the publisher's set.  Returns `import!`'s summary.
sourceraw docstring

state-rootclj

(state-root kb)

A content-addressed snapshot identity of the seat's believed records: the Merkle construction of commit-id over the same believed set, with leaves that fold each record's provenance (:creator + :created) in with its identity. It moves when provenance moves even if commit-id does not. Two seats compare commit-id to agree on knowledge and state-root to agree on the snapshot. It is belief-scoped for commit-id's reason, so the two roots cover one set of records.

A content-addressed **snapshot** identity of the seat's believed records: the Merkle
construction of `commit-id` over the same believed set, with leaves that fold each
record's provenance (`:creator` + `:created`) in with its identity.  It moves when
provenance moves even if `commit-id` does not.  Two seats compare `commit-id` to agree on
*knowledge* and `state-root` to agree on the *snapshot*.  It is belief-scoped for
`commit-id`'s reason, so the two roots cover one set of records.
sourceraw docstring

verify-inclusionclj

(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. Domain separation (0x00 leaf / 0x01 node) is enforced on both sides. Fails closed on a malformed proof: a non-hex sibling, a missing :hash/:side, or a non-sequential proof returns false, not a throw.

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.  Domain separation (`0x00` leaf / `0x01` node) is
enforced on both sides.  **Fails closed on a malformed proof**: a non-hex sibling, a
missing `:hash`/`:side`, or a non-sequential proof returns `false`, not a throw.
sourceraw docstring

why-markerclj

(why-marker kb marker)

Dereference marker and, when it resolves, attach the proof v/why builds for it — the extension point 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 extension point 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.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close