Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 40s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
149 lines
3.9 KiB
Plaintext
149 lines
3.9 KiB
Plaintext
;; Phase 4 — federated documents: trust-gated peer ops + concurrent-external-
|
|
;; edit conflict resolution via the CRDT.
|
|
|
|
(st-bootstrap-classes!)
|
|
(content-bootstrap-blocks!)
|
|
(content-bootstrap-doc!)
|
|
(content-bootstrap-render!)
|
|
|
|
(define same? (fn (a b) (= (get a :elements) (get b :elements))))
|
|
|
|
;; base shared document, then a local edit
|
|
(define
|
|
base
|
|
(crdt-insert
|
|
(crdt-insert
|
|
(crdt-empty)
|
|
"h"
|
|
"heading"
|
|
(crdt-pos 1 0)
|
|
(list (list "level" 1) (list "text" "T"))
|
|
1
|
|
0)
|
|
"p"
|
|
"text"
|
|
(crdt-pos 2 0)
|
|
(list (list "text" "Body"))
|
|
1
|
|
0))
|
|
(define local (crdt-update base "p" "text" "local" 5 1))
|
|
|
|
;; ── provenance ──
|
|
(content-test
|
|
"authored tags author"
|
|
(get (content/authored (crdt-op-delete "h") "ed") :author)
|
|
"ed")
|
|
(content-test
|
|
"signed tags sig"
|
|
(get (content/signed (crdt-op-delete "h") "ed" "sig1") :sig)
|
|
"sig1")
|
|
(content-test "trusted? yes" (content/trusted? (list "ed" "al") "ed") true)
|
|
(content-test "trusted? no" (content/trusted? (list "ed") "mal") false)
|
|
|
|
;; peer ops: ed is trusted, mal is not
|
|
(define
|
|
peer-ops
|
|
(list
|
|
(content/authored
|
|
(crdt-op-update "p" "text" "peer-ed" 7 2)
|
|
"ed")
|
|
(content/authored
|
|
(crdt-op-insert
|
|
"x"
|
|
"text"
|
|
(crdt-pos 3 0)
|
|
(list (list "text" "X"))
|
|
8
|
|
2)
|
|
"ed")
|
|
(content/authored (crdt-op-delete "h") "mal")))
|
|
|
|
(define res (content/merge-peer local (list "ed") peer-ops))
|
|
|
|
;; ── trust gate: only ed's ops applied ──
|
|
(content-test "accepted count" (len (content/accepted res)) 2)
|
|
(content-test "rejected count" (len (content/rejected res)) 1)
|
|
(content-test
|
|
"rejected is mal's"
|
|
(get (first (content/rejected res)) :author)
|
|
"mal")
|
|
|
|
;; ── resulting document ──
|
|
(define rdoc (crdt-materialize "d" (content/peer-state res)))
|
|
(content-test "untrusted delete blocked: h survives" (doc-has? rdoc "h") true)
|
|
(content-test "trusted insert applied: x present" (doc-has? rdoc "x") true)
|
|
(content-test "result order" (doc-ids rdoc) (list "h" "p" "x"))
|
|
(content-test
|
|
"trusted edit wins (ts7 > ts5)"
|
|
(str (blk-send (doc-find rdoc "p") "text"))
|
|
"peer-ed")
|
|
|
|
;; ── order-independence of accepted peer ops ──
|
|
(define res-rev (content/merge-peer local (list "ed") (reverse peer-ops)))
|
|
(content-test
|
|
"peer merge order-independent"
|
|
(same? (content/peer-state res) (content/peer-state res-rev))
|
|
true)
|
|
|
|
;; ── trust = nobody → nothing applied, state unchanged ──
|
|
(define res0 (content/merge-peer local (list) peer-ops))
|
|
(content-test
|
|
"no trust accepts none"
|
|
(len (content/accepted res0))
|
|
0)
|
|
(content-test
|
|
"no trust rejects all"
|
|
(len (content/rejected res0))
|
|
3)
|
|
(content-test
|
|
"no trust state unchanged"
|
|
(same? (content/peer-state res0) local)
|
|
true)
|
|
|
|
;; ── pluggable predicate gate (acl-on-sx hook) ──
|
|
(define
|
|
res-pred
|
|
(content/merge-peer-with
|
|
local
|
|
(fn (op) (= (get op :author) "ed"))
|
|
peer-ops))
|
|
(content-test
|
|
"predicate gate == list gate"
|
|
(same? (content/peer-state res-pred) (content/peer-state res))
|
|
true)
|
|
|
|
;; ── conflict on concurrent external edit: local vs external, same field ──
|
|
;; external (peer) state edits p concurrently with a later ts; CRDT reconciles.
|
|
(define
|
|
external
|
|
(crdt-update base "p" "text" "external" 9 2))
|
|
(content-test
|
|
"conflict LWW deterministic"
|
|
(str
|
|
(blk-send
|
|
(doc-find (crdt-materialize "d" (crdt-merge local external)) "p")
|
|
"text"))
|
|
"external")
|
|
(content-test
|
|
"conflict merge commutes"
|
|
(same? (crdt-merge local external) (crdt-merge external local))
|
|
true)
|
|
(content-test
|
|
"conflict merge idempotent"
|
|
(same?
|
|
(crdt-merge (crdt-merge local external) external)
|
|
(crdt-merge local external))
|
|
true)
|
|
|
|
;; concurrent external edit with LOWER ts loses to local
|
|
(define
|
|
external-old
|
|
(crdt-update base "p" "text" "stale" 3 2))
|
|
(content-test
|
|
"older external loses to local"
|
|
(str
|
|
(blk-send
|
|
(doc-find (crdt-materialize "d" (crdt-merge local external-old)) "p")
|
|
"text"))
|
|
"local")
|