Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m7s
Content-addressed node = {:op :inputs :params :commutative}; content-id is a
deterministic canonical serialization (sorted param keys; commutative ops sort
inputs). artdag/build validates dangling/cycles, topo-sorts, dedups identical
subgraphs to one id shared across DAGs. conformance.sh + scoreboard (dag 20/20).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
183 lines
4.7 KiB
Plaintext
183 lines
4.7 KiB
Plaintext
; Phase 1 — dag model + structural content addressing.
|
|
|
|
; ---- content-id determinism ----
|
|
|
|
(artdag-test
|
|
"same spec -> same id"
|
|
(equal?
|
|
(artdag/content-id (artdag/node "blur" (list "i1") {:r 3}))
|
|
(artdag/content-id (artdag/node "blur" (list "i1") {:r 3})))
|
|
true)
|
|
|
|
(artdag-test
|
|
"op affects id"
|
|
(equal?
|
|
(artdag/content-id (artdag/node "blur" (list "i1") {}))
|
|
(artdag/content-id (artdag/node "sharpen" (list "i1") {})))
|
|
false)
|
|
|
|
(artdag-test
|
|
"params affect id"
|
|
(equal?
|
|
(artdag/content-id (artdag/node "blur" (list "i1") {:r 3}))
|
|
(artdag/content-id (artdag/node "blur" (list "i1") {:r 5})))
|
|
false)
|
|
|
|
(artdag-test
|
|
"inputs affect id"
|
|
(equal?
|
|
(artdag/content-id (artdag/node "add" (list "i1") {}))
|
|
(artdag/content-id (artdag/node "add" (list "i2") {})))
|
|
false)
|
|
|
|
(artdag-test
|
|
"param key order does not affect id"
|
|
(equal?
|
|
(artdag/content-id (artdag/node "op" (list) {:a 1 :b 2}))
|
|
(artdag/content-id (artdag/node "op" (list) {:a 1 :b 2})))
|
|
true)
|
|
|
|
; ---- commutativity ----
|
|
|
|
(artdag-test
|
|
"commutative op: input order ignored"
|
|
(equal?
|
|
(artdag/content-id (artdag/cnode "add" (list "i1" "i2") {}))
|
|
(artdag/content-id (artdag/cnode "add" (list "i2" "i1") {})))
|
|
true)
|
|
|
|
(artdag-test
|
|
"non-commutative op: input order matters"
|
|
(equal?
|
|
(artdag/content-id (artdag/node "sub" (list "i1" "i2") {}))
|
|
(artdag/content-id (artdag/node "sub" (list "i2" "i1") {})))
|
|
false)
|
|
|
|
; ---- build: success ----
|
|
|
|
(artdag-test
|
|
"build ok for valid dag"
|
|
(get
|
|
(artdag/build
|
|
(list
|
|
(list "a" "load" (list) {})
|
|
(list "b" "load" (list) {:s 1})
|
|
(list "c" "add" (list "a" "b") {})))
|
|
:ok)
|
|
true)
|
|
|
|
(artdag-test
|
|
"node-count counts distinct nodes"
|
|
(artdag/node-count
|
|
(artdag/build
|
|
(list
|
|
(list "a" "load" (list) {})
|
|
(list "b" "load" (list) {:s 1})
|
|
(list "c" "add" (list "a" "b") {}))))
|
|
3)
|
|
|
|
; ---- subgraph sharing ----
|
|
|
|
(artdag-test
|
|
"identical leaves dedup to one node"
|
|
(artdag/node-count
|
|
(artdag/build
|
|
(list
|
|
(list "a" "load" (list) {:s 1})
|
|
(list "b" "load" (list) {:s 1})
|
|
(list "c" "add" (list "a" "b") {}))))
|
|
2)
|
|
|
|
(artdag-test
|
|
"duplicate names map to same id"
|
|
(let
|
|
((d (artdag/build (list (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 1})))))
|
|
(equal? (artdag/dag-id d "a") (artdag/dag-id d "b")))
|
|
true)
|
|
|
|
(artdag-test
|
|
"identical subgraph shares id across dags"
|
|
(let
|
|
((d1 (artdag/build (list (list "x" "load" (list) {:s 7}) (list "y" "neg" (list "x") {}))))
|
|
(d2
|
|
(artdag/build
|
|
(list
|
|
(list "p" "load" (list) {:s 7})
|
|
(list "q" "neg" (list "p") {})))))
|
|
(equal? (artdag/dag-id d1 "y") (artdag/dag-id d2 "q")))
|
|
true)
|
|
|
|
; ---- validation ----
|
|
|
|
(artdag-test
|
|
"cycle rejected"
|
|
(get
|
|
(artdag/build
|
|
(list
|
|
(list "a" "f" (list "b") {})
|
|
(list "b" "g" (list "a") {})))
|
|
:error)
|
|
"cycle")
|
|
|
|
(artdag-test
|
|
"self-cycle rejected"
|
|
(get (artdag/build (list (list "a" "f" (list "a") {}))) :error)
|
|
"cycle")
|
|
|
|
(artdag-test
|
|
"dangling input rejected"
|
|
(get
|
|
(artdag/build (list (list "a" "f" (list "ghost") {})))
|
|
:error)
|
|
"dangling")
|
|
|
|
(artdag-test
|
|
"dangling refs reported"
|
|
(get
|
|
(artdag/build (list (list "a" "f" (list "ghost") {})))
|
|
:refs)
|
|
(list "ghost"))
|
|
|
|
; ---- topological order ----
|
|
|
|
(artdag-test
|
|
"topo order: deps before dependents"
|
|
(let
|
|
((d (artdag/build (list (list "c" "add" (list "a" "b") {}) (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 2})))))
|
|
(artdag/dag-order d))
|
|
(let
|
|
((d (artdag/build (list (list "c" "add" (list "a" "b") {}) (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 2})))))
|
|
(list (artdag/dag-id d "a") (artdag/dag-id d "b") (artdag/dag-id d "c"))))
|
|
|
|
(artdag-test
|
|
"topo order: deep chain"
|
|
(let
|
|
((d (artdag/build (list (list "d" "f" (list "c") {}) (list "c" "f" (list "b") {}) (list "b" "f" (list "a") {}) (list "a" "load" (list) {})))))
|
|
(artdag/dag-order d))
|
|
(let
|
|
((d (artdag/build (list (list "d" "f" (list "c") {}) (list "c" "f" (list "b") {}) (list "b" "f" (list "a") {}) (list "a" "load" (list) {})))))
|
|
(list
|
|
(artdag/dag-id d "a")
|
|
(artdag/dag-id d "b")
|
|
(artdag/dag-id d "c")
|
|
(artdag/dag-id d "d"))))
|
|
|
|
; ---- accessors ----
|
|
|
|
(artdag-test
|
|
"dag-node-by-name returns node spec"
|
|
(artdag/node-op
|
|
(artdag/dag-node-by-name
|
|
(artdag/build (list (list "a" "load" (list) {})))
|
|
"a"))
|
|
"load")
|
|
|
|
(artdag-test
|
|
"resolved inputs are content-ids"
|
|
(let
|
|
((d (artdag/build (list (list "a" "load" (list) {}) (list "b" "neg" (list "a") {})))))
|
|
(artdag/node-inputs (artdag/dag-node-by-name d "b")))
|
|
(let
|
|
((d (artdag/build (list (list "a" "load" (list) {}) (list "b" "neg" (list "a") {})))))
|
|
(list (artdag/dag-id d "a"))))
|