;; lib/mod/wire.sx — portable decision wire format for federation transport.
;;
;; fed.sx shares decisions as in-memory dicts and leaves mod/fed-send! as the
;; transport seam. This is the bytes that cross it: a versioned, pipe-delimited
;; line encoding the verdict a peer needs (report id, action, rule) — enough to
;; trust-gate and apply/advise, without shipping the whole proof tree. The
;; loaded env has no string split, so split is built over slice/len.

(define
  mod/split-loop
  (fn
    (s ch n start pos acc)
    (if
      (= pos n)
      (append acc (list (slice s start n)))
      (if
        (= (slice s pos (+ pos 1)) ch)
        (mod/split-loop
          s
          ch
          n
          (+ pos 1)
          (+ pos 1)
          (append acc (list (slice s start pos))))
        (mod/split-loop s ch n start (+ pos 1) acc)))))

(define
  mod/split-char
  (fn (s ch) (mod/split-loop s ch (len s) 0 0 (list))))

(define
  mod/decision->wire
  (fn
    (d)
    (str "MOD1|" (get d :report-id) "|" (get d :action) "|" (get d :rule))))

(define
  mod/wire-valid?
  (fn
    (w)
    (let
      ((parts (mod/split-char w "|")))
      (if
        (= (len parts) 4)
        (= (nth parts 0) "MOD1")
        false))))

(define
  mod/wire->decision
  (fn
    (w)
    (if
      (mod/wire-valid? w)
      (let ((parts (mod/split-char w "|"))) {:action (nth parts 2) :wire true :rule (nth parts 3) :report-id (nth parts 1)})
      nil)))
