dog/WEAVE; delete graf/WEAVE
Repoint graf at dog/WEAVE and delete graf/WEAVE.{c,h}. GET, REBASE, BLAME, DIFFREF and LOG call the new API; the parent-closure WEAVEApply path becomes WEAVEMerge + scope bitsets resolved at the graf/DAG boundary. Finishes the move, updates both INDEX.md, and retires the superseded tickets. Gates on DOG-003/DOG-004.
graf/GET.c (build_tip_weave*), graf/REBASE.c, graf/BLAME.c
(GRAFFileWeave), graf/DIFFREF.c, graf/LOG.c.
GRAFFileWeave folds the closure via WEAVEApply/Diff; this becomes
WEAVENext along first-parent + WEAVEMerge at merges, scope from the DAG.
be-patch-15 step 2 fails 5/5 under the dog cut-over. DIS-045
PROVED the dog engine correct — dog/test/WEAVE03 drives step-2 as a shared-base 3-way merge (base F2 → ours, base F2 → theirs, then WEAVEMerge) and gets 08.lib.want_step2.c byte-exact (322/322, 4.7M fuzz). So the fault is graf's GLUE: WEAVEApply-against-parent-closure replay is NOT byte-identical to that first-parent WEAVENext+WEAVEMerge shared-base model for the ancestor-skip topology. Fix the modeling, not the engine.
dog/WEAVE; graf/WEAVE.{c,h} deleted; suite green;
graf blame/diff/merge + be get/be patch byte-parity (modulo capped).
ancestor u64 ids → commits[] indices once per op (reuse DAGAncestors).
fold ours AND theirs onto the SAME merge-base weave (the skip ancestor, NOT a per-branch closure replay), then WEAVEMerge; that is what the engine is byte-parity-correct for. Make GRAFFileWeave's glue match it.
be-patch-15 step 2 5/5 fail through the graf glue (the dogengine is already pinned by WEAVE03 — isolate the closure→fold model).
shared-base 3-way at ancestor-skip merges (per WEAVE03).
graf/WEAVE.{c,h}; update graf/INDEX.md + dog/INDEX.md.correct, the fault is the graf cut-over glue (closure replay ≠ shared-base 3-way). Watch DIS-041 (FF-weave needs indexed commits) during GET cut-over.