;; content-on-sx — federated documents: trust-gated peer-authored ops.
;;
;; A peer-authored op carries provenance (:author, and a :sig stub). We never
;; auto-accept: a peer op is applied only if it passes a trust gate. The gate is
;; a predicate (fn op -> bool) so acl-on-sx can inject real trust facts later;
;; the convenience form takes an explicit trusted-actor list (the stub).
;;
;; Accepted ops flow through the CvRDT merge (Phase 3), so concurrent local and
;; external edits reconcile deterministically (same-field LWW, order-independent).
;;
;; Requires (loaded by harness): crdt.sx (and its deps).

;; tag an op with provenance
(define content/authored (fn (op author) (assoc op :author author)))

(define
  content/signed
  (fn (op author sig) (assoc (assoc op :author author) :sig sig)))

;; explicit trust stub: membership in a trusted-actor list
(define content/trusted? (fn (trust author) (crdt-member? author trust)))

;; general form: accept? is a predicate (fn op -> bool). Applies accepted ops
;; through the CRDT; quarantines the rest. Returns
;; {:state :accepted (ops) :rejected (ops)}.
(define
  content/-merge-peer-loop
  (fn
    (state accept? ops accepted rejected)
    (if
      (= (len ops) 0)
      {:state state :accepted (reverse accepted) :rejected (reverse rejected)}
      (let
        ((op (first ops)))
        (if
          (accept? op)
          (content/-merge-peer-loop
            (crdt-apply state op)
            accept?
            (rest ops)
            (cons op accepted)
            rejected)
          (content/-merge-peer-loop
            state
            accept?
            (rest ops)
            accepted
            (cons op rejected)))))))

(define
  content/merge-peer-with
  (fn
    (state accept? ops)
    (content/-merge-peer-loop state accept? ops (list) (list))))

;; convenience: trust = list of trusted actor ids
(define
  content/merge-peer
  (fn
    (state trust ops)
    (content/merge-peer-with
      state
      (fn (op) (content/trusted? trust (get op :author)))
      ops)))

(define content/accepted (fn (res) (get res :accepted)))
(define content/rejected (fn (res) (get res :rejected)))
(define content/peer-state (fn (res) (get res :state)))
