host: universal content-address (CID) on every post
Every object (content/type/relation post) now carries a stable :cid = hash of its canonical, key-sorted content. The runtime has no hash primitive, so host/blog--canon (recursive, sorts keys -> identical across processes regardless of dict insertion order) and a tail-recursive double-hash (host/blog--hash-go / host/blog--cid-of) are built in SX. The slug (a name) and any prior :cid are excluded -> the CID hashes content only. git-shaped: slug = mutable name -> CID = immutable content identity. Single choke point host/blog--write! stamps the CID on every record write; routed all three write sites (put!, set-schema!, seed-rel!) through it. Accessors host/blog-cid and host/blog-by-cid (reverse lookup). +6 conformance tests (blog suite 134/134). Plan: new 'Content-addressability is universal' section (CID model, git-shape, federation: types flow across fed-sx as shared content-addressed vocabulary; structure/behaviour trust-split). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,38 @@ itself in its own graph.
|
||||
|
||||
Supersedes the hardcoded `:candidates "types"/"tags"/"all"` field of `host/blog-rel-kinds`.
|
||||
|
||||
## Content-addressability is universal (foundational)
|
||||
|
||||
**Every object carries a content-address (CID) — content-posts, type-posts, relation-posts,
|
||||
constraint-posts, all of them.** A CID is the hash of the object's *canonical* form: a recursive,
|
||||
**key-sorted** serialization (so insertion order, and any process-seed-dependent dict ordering, is
|
||||
irrelevant — identical content always yields an identical CID). The runtime has no hash primitive,
|
||||
so the canon serializer + a tail-recursive double-hash are built in SX (`host/blog--canon`,
|
||||
`host/blog--cid-of`); the slug is excluded from the hash (it's a *name*, not content).
|
||||
|
||||
The model is **git-shaped**: the **slug is a mutable name → CID** (a branch pointing at a commit);
|
||||
the **CID is the immutable content identity** (the commit). Editing a post mints a new CID; the slug
|
||||
follows. Type evolution is the same — a type *version* is content-addressed, instances reference the
|
||||
version they were created against. Two objects with identical content *are* the same object (same
|
||||
CID) — correct content-addressing semantics.
|
||||
|
||||
**Why it's foundational (federation).** A CID is a **global, location-independent identity**, so:
|
||||
|
||||
- **Types flow across `fed-sx`.** The same type *definition* on any node has the same CID → a
|
||||
**shared, content-addressed vocabulary**. Federated *instances* reference type CIDs, so a receiving
|
||||
node can *interpret* them. This is linked-data/RDF realised on the post graph, and it generalises
|
||||
ActivityPub itself: AP has a *fixed* type vocabulary (Note/Article/Person, Create/Follow/Like) —
|
||||
the metamodel makes that vocabulary **extensible and user-defined**.
|
||||
- **Structure / behaviour trust-split** (the federation boundary): type **structure** (schema,
|
||||
relations, signatures) is declarative and federates *freely* — sharing a definition is sharing a
|
||||
hash. **Behaviour** (Slice 9 lifecycles/effects) does **not** federate naively: you never run a
|
||||
remote node's lifecycle with *your* effect primitives (their "ship" could `charge-card`).
|
||||
Behaviour federates only under high trust, with the effects **re-bound** to local, audited
|
||||
primitives (their orchestration, your effects). `fed-sx` is already trust-gated — that's the lever.
|
||||
|
||||
Build order: stamp a stable CID on every object first (additive — slug-addressing stays the working
|
||||
key), then a `cid → slug` index, then migrate references / type versioning, then federation.
|
||||
|
||||
## North star — the metamodel as a system-construction kit
|
||||
|
||||
The destination this is all heading toward: the host stops being "a blog" and becomes a
|
||||
|
||||
Reference in New Issue
Block a user