diff --git a/sx/sx/geography/cek.sx b/sx/sx/geography/cek.sx index 6616c83..a6d84a2 100644 --- a/sx/sx/geography/cek.sx +++ b/sx/sx/geography/cek.sx @@ -711,6 +711,63 @@ (deref saved))))))) + + +(defcomp ~geography/cek/cek-content-address-content () + (~docs/page :title "Content-Addressed Computation" + + (p :class "text-stone-500 text-sm italic mb-8" + "A computation is a value. A value has a hash. The hash is the address. " + "Same state, same address, forever.") + + (~docs/section :title "The idea" :id "idea" + (p "Freeze a scope to SX. Hash the SX text. The hash is a content identifier (CID). " + "Store the frozen SX keyed by CID. Later, look up the CID, thaw, resume.") + (p "The critical property: " + (strong "same state always produces the same CID") ". " + "Two machines freezing identical signal values get identical CIDs. " + "The address IS the content.")) + + (~docs/section :title "How it works" :id "how" + (~docs/code :code (highlight + ";; Freeze a scope \u2192 hash \u2192 CID\n(freeze-to-cid \"widget\")\n;; => \"d9eea67b\"\n\n;; The frozen SX is stored by CID\n(content-get \"d9eea67b\")\n;; => {:name \"widget\" :signals {:count 42 :name \"hello\"}}\n\n;; Thaw from CID \u2192 signals restored\n(thaw-from-cid \"d9eea67b\")\n;; Signals reset to frozen values" + "lisp")) + (p "The hash is djb2 for now \u2014 deterministic and fast. " + "Real deployment uses SHA-256 / multihash for IPFS compatibility.")) + + (~docs/section :title "Why it matters" :id "why" + (ul :class "list-disc pl-6 mb-4 space-y-2 text-stone-600" + (li (strong "Sharing") " \u2014 send a CID, not a blob. " + "The receiver looks up the CID and gets the exact state.") + (li (strong "Deduplication") " \u2014 same state = same CID. " + "Store once, reference many times.") + (li (strong "Verification") " \u2014 re-freeze, compare CIDs. " + "If they match, the state is identical. No diffing needed.") + (li (strong "History") " \u2014 each CID is a snapshot. " + "A sequence of CIDs is a complete undo history.") + (li (strong "Distribution") " \u2014 CIDs on IPFS are global. " + "Pin a widget state, anyone can thaw it. " + "No server, no API, no account."))) + + (~docs/section :title "Live demo" :id "demo" + (p "Change the counter and name. Click " (strong "Content-address") " to freeze and hash. " + "The CID appears below. Change the values, then click any CID in the history " + "or paste one into the input to restore.") + (~geography/cek/content-address-demo)) + + (~docs/section :title "The path to IPFS" :id "ipfs" + (p "The content store is currently in-memory. The next steps:") + (ul :class "list-disc pl-6 mb-4 space-y-1 text-stone-600" + (li "Replace djb2 with SHA-256 (browser SubtleCrypto)") + (li "Wrap in multihash + CIDv1 format") + (li "Store to IPFS via the Art DAG L2 registry") + (li "Pin CIDs attributed to " (code "sx-web.org")) + (li "Anyone can pin, fork, extend")) + (p "The frozen SX is the content. The CID is the address. " + "IPFS is the network. The widget state becomes a permanent, " + "verifiable, shareable artifact \u2014 not trapped in a database, " + "not behind an API, not owned by anyone.")))) + ;; --------------------------------------------------------------------------- ;; Demo page content ;; --------------------------------------------------------------------------- diff --git a/sx/sx/nav-data.sx b/sx/sx/nav-data.sx index 3d46dcb..9f22763 100644 --- a/sx/sx/nav-data.sx +++ b/sx/sx/nav-data.sx @@ -176,7 +176,9 @@ (dict :label "Demo" :href "/sx/(geography.(cek.demo))" :summary "Live islands evaluated by the CEK machine. Counter, computed chains, reactive attributes — all through explicit continuation frames.") (dict :label "Freeze / Thaw" :href "/sx/(geography.(cek.freeze))" - :summary "Serialize a CEK state to s-expressions. Ship it, store it, content-address it. Thaw and resume anywhere."))) + :summary "Serialize a CEK state to s-expressions. Ship it, store it, content-address it. Thaw and resume anywhere.") + (dict :label "Content Addressing" :href "/sx/(geography.(cek.content))" + :summary "Hash frozen state to a CID. Same state = same address. Store, share, verify, reproduce."))) (define plans-nav-items (list (dict :label "Status" :href "/sx/(etc.(plan.status))" diff --git a/sx/sx/page-functions.sx b/sx/sx/page-functions.sx index 91794c1..08f3629 100644 --- a/sx/sx/page-functions.sx +++ b/sx/sx/page-functions.sx @@ -67,6 +67,7 @@ (case slug "demo" '(~geography/cek/cek-demo-content) "freeze" '(~geography/cek/cek-freeze-content) + "content" '(~geography/cek/cek-content-address-content) :else '(~geography/cek/cek-content))))) (define provide