combine

fun combine(other: Draft<*>): Draft<Unit>

Merges this Draft and other into a single dependency DAG with two independent branches — no edges connect the two branches, so their DraftStage.Embroider nodes can be consolidated into a single Raft round by the G3 planner.

The result element type is Unit: the combined draft represents a plan holding both pipelines, not a single typed output. The stages view lists both branches' stages in topological order (all of this branch, then all of other).

NodeId remapping: other's NodeIds are offset by this.nodes.size to guarantee uniqueness. Every predecessor reference in other's nodes is offset by the same amount so the graph structure is preserved exactly.

Independence guarantee: no node in other's remapped branch references a node in this branch as a predecessor, and vice versa — the two branches remain disconnected in the merged DAG.

See also

for accessing both branches' coordination stages. The optimize rewrite (in :kuilt-warp-planning) applies branch-aware optimisation per branch.

Samples

val docs = Warp.shuttle(OpId("source.docs"))
    .map(OpId("map.score"))
    .embroider(OpId("embroider.rank"))
val scores = Warp.shuttle(OpId("source.scores"))
    .filter(OpId("filter.nonzero"))
    .embroider(OpId("embroider.vote"))

val combined: Draft<Unit> = docs.combine(scores)

// Both branches' embroideries are present — independent, no edges connect them.
check(combined.embroideries.size == 2)
check(!combined.isMonotone)