Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 50s
serialize.sx emits a topo-ordered (id op inputs params commutative) record list that survives write/read (string-keyed node dicts do not; empty inputs read back as nil and are normalized). wire->dag reconstructs a runnable dag by content-id; wire-verify recomputes ids to reject tampering. dag->string/string->dag for text transport. serialize 13/13, total 128/128. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
63 lines
1.9 KiB
Plaintext
63 lines
1.9 KiB
Plaintext
; lib/artdag/serialize.sx — portable wire form for whole DAGs, so a peer can
|
|
; receive and run a graph it did not author. The form is a topo-ordered list of
|
|
; node records (id op inputs params commutative) — plain lists with keyword-keyed
|
|
; param dicts, which survive write/read (unlike string-keyed node dicts). The id
|
|
; is the content-id, so the form is self-verifying. Depends on dag.sx.
|
|
|
|
(define
|
|
artdag/node->record
|
|
(fn
|
|
(dag id)
|
|
(let
|
|
((n (artdag/dag-get dag id)))
|
|
(list
|
|
id
|
|
(artdag/node-op n)
|
|
(artdag/node-inputs n)
|
|
(artdag/node-params n)
|
|
(get n :commutative)))))
|
|
|
|
; dag -> list of records, in topological order.
|
|
(define
|
|
artdag/dag->wire
|
|
(fn
|
|
(dag)
|
|
(map (fn (id) (artdag/node->record dag id)) (artdag/dag-order dag))))
|
|
|
|
; an empty input list reads back as nil; normalize it.
|
|
(define
|
|
artdag/-rec-inputs
|
|
(fn (rec) (let ((i (nth rec 2))) (if (nil? i) (list) i))))
|
|
|
|
(define artdag/-rec->node (fn (rec) {:inputs (artdag/-rec-inputs rec) :commutative (nth rec 4) :op (nth rec 1) :params (nth rec 3)}))
|
|
|
|
; records -> dag. Local author names are not part of the wire form; the receiver
|
|
; works by content-id. :names is left empty.
|
|
(define
|
|
artdag/wire->dag
|
|
(fn
|
|
(records)
|
|
(reduce
|
|
(fn (dag rec) (let ((id (nth rec 0))) {:names (get dag :names) :order (concat (get dag :order) (list id)) :ok true :nodes (assoc (get dag :nodes) id (artdag/-rec->node rec))}))
|
|
{:names {} :order (list) :ok true :nodes {}}
|
|
records)))
|
|
|
|
; integrity: each record's id must equal the content-id recomputed from its spec.
|
|
(define
|
|
artdag/wire-verify
|
|
(fn
|
|
(records)
|
|
(every?
|
|
(fn
|
|
(rec)
|
|
(= (nth rec 0) (artdag/content-id (artdag/-rec->node rec))))
|
|
records)))
|
|
|
|
; string transport.
|
|
(define
|
|
artdag/dag->string
|
|
(fn (dag) (write-to-string (artdag/dag->wire dag))))
|
|
(define
|
|
artdag/string->dag
|
|
(fn (s) (artdag/wire->dag (read (open-input-string s)))))
|