plan: don't calcify P0.2 — artdag may grow to contain business logic (phase AX)

Per the user: the execute-fold-vs-artdag split from P0.2 is a capability SNAPSHOT, not a permanent
boundary. artdag MAY grow +{effect,branch,each} node-kinds; business logic then migrates onto it to
inherit the DAG-engine superpowers — content-addressed memoization (recompute only on input-CID
change), optimize (fuse/dedup/dce), schedule, and above all FEDERATION (a flow result reused across
peers by content-id — the federation vision, for free). The capability model makes the migration
seamless (same DAGs + seam; the runner just advertises more). Named the real design work: dynamic
control in a static DAG (branch prunes a path); effect nodes non-cacheable vs pure nodes memoized.
Demand-driven (phase AX); execute-fold stays the lean default for cheap synchronous flows. Annotated
the P0.2 finding + flows.sx header so the finding doesn't harden into dogma.

Doc/comment-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 14:38:36 +00:00
parent e38a8381d4
commit 564fa7dd7d
2 changed files with 30 additions and 0 deletions

View File

@@ -6,6 +6,10 @@
;; artdag runner (dataflow, memoized/parallel). The DIFFERENCE is which capabilities their nodes
;; need. A node declares its capability; a runner ADVERTISES what it supports; the binder checks
;; required ⊆ advertised (fail fast); so the sync/durable/distributed choice is DERIVED from the DAG.
;; NOTE (plan phase AX): this execute-fold-vs-artdag split is a capability SNAPSHOT, not a boundary
;; — artdag MAY grow +{effect,branch,each} node-kinds and business logic then migrates onto it (to
;; inherit content-addressed memoization / optimize / FEDERATION). The capability model makes that
;; migration seamless; the execute-fold stays the lean default for cheap synchronous flows.
;; ── capability typing: a node kind → the capability it needs ──────────
(define host/flow--node-cap

View File

@@ -140,6 +140,12 @@ fed-sx yet — those are adapter phases (RA/TA). Every piece swaps later; the DA
exec-runner (would need Erlang, RA). flows 7/7, blog 203/203, conformance 591/591.
IMPLICATION for RA/TA: the Erlang runner isn't a "different flow language" — it's the SAME op-DAG
with +{suspend} nodes; RA is the runner that advertises suspend + wraps flow_dispatch.
CAVEAT (don't calcify this finding): execute-fold-vs-artdag is a CURRENT capability SNAPSHOT, NOT
a permanent boundary. artdag MAY GROW control-flow node-kinds (a runner advertising +{effect,
branch, each}), and business logic then MIGRATES to artdag to inherit content-addressed
memoization / optimize (fuse/dedup/dce) / schedule / FEDERATION (a flow result reused across peers
by content-id — the federation vision, free). The capability model makes that migration seamless
(same DAGs, richer runner; the execute-fold is just the pragmatic sync runner NOW). See phase AX.
- [ ] **P0.3 — wire the seam on the live host.** A local-SX trigger registry (on-publish →
publish-DAG), an in-process transport (a KV-backed log), the host as effect driver. In edit-submit
detect the draft→published TRANSITION (prev≠published & new=published — fire-once), build the
@@ -176,6 +182,19 @@ fed-sx yet — those are adapter phases (RA/TA). Every piece swaps later; the DA
blockers (er-scheduler context). Needs the ACTOR MODEL real (:actor was a P0 placeholder —
peer_actors / follower_graph / per-author identity).
## AX — artdag GROWS control-flow (business logic MIGRATES to artdag) [DEMAND-DRIVEN]
Today artdag is pure dataflow and the execute-fold is the synchronous control-flow runner. That's
a capability snapshot. When a business flow WANTS the artdag engine's benefits — content-addressed
memoization (recompute only on input-CID change), optimize (fuse/dedup/dce), schedule, and above
all FEDERATION (a flow result reused across peers by content-id) — grow artdag's node vocabulary
so its runner advertises `+{effect, branch, each}`, and the SAME behavior DAGs migrate onto it
(the capability model makes this seamless; the seam + DAGs don't change). Two real design pieces:
(1) DYNAMIC control in a static DAG — a `branch` PRUNES a path (conditional nodes make downstream
nodes live/dead; content-addressing holds on the taken path); (2) EFFECT nodes vs memoization —
pure nodes memoize, `{effect}` nodes are marked non-cacheable (must run / be idempotent). Build
when a flow's cost, reuse, or cross-peer sharing makes the execute-fold's re-run-everything
insufficient — not before. The execute-fold stays the lean default for cheap synchronous flows.
## RX — celery-sx runner (DEMAND-DRIVEN, not scheduled)
Build the distributed/durable runner adapter the moment a real DAG needs heavy compute /
long-running-retryable tasks / cross-machine fan-out (the artdag/JAX media case, or federated
@@ -190,6 +209,13 @@ covers everything until a DAG's cost/latency/placement forces the substrate.
activities), so business logic can change state, which federates, which triggers more flows.
## Progress log (newest first)
- 2026-07-02 — DON'T-CALCIFY note (user: "artdag may in the future contain business logic"). The
execute-fold-vs-artdag split from P0.2 is a capability SNAPSHOT, not a boundary. Added phase AX:
artdag grows +{effect,branch,each} node-kinds and business logic migrates onto it to inherit
content-addressed memoization / optimize / FEDERATION (flow result reused across peers by CID —
the federation vision, free). Design work named: dynamic control (branch prunes) in a static DAG;
effect nodes non-cacheable vs pure nodes memoized. Demand-driven; execute-fold stays the lean
default. P0.2 finding + flows.sx header annotated so the finding doesn't harden.
- 2026-07-02 — P0.2 DONE + the hypothesis CONFIRMED (and refined). The synchronous publish workflow
is NATURAL as an execute-fold composition (seq/effect/alt), NOT artdag dataflow (no branch there).
So business-logic = art-dag holds at the abstraction (content-addressed op-DAG) but the SYNCHRONOUS