be log row order is STORE-LAYOUT-DEPENDENT — a be get be://… clone renders the SAME history jumbled (tip row is an ancient commit, dates non-monotonic)
be log over a be://-cloned store lists the SAME commit closure in a jumbled order: the first (tip) row is an ancient commit, not the cur, and the dates run non-monotonic (06Jan, 02Mar, 19Oct24, 28Mar25, 13Apr, 31Aug24, 07May, 11Jun, 12Jun, 03Apr…). The SAME binary over a natively-built store with the SAME closure renders correctly newest-first / time-descending. So the log walk's ROW ORDER depends on the physical store layout (the order objects/graf landed during the wire fetch), not solely on the DAG — a clone scrambles the listing. Distinct from LOG-001 (non-spine greying); this is the ordering of the spine listing itself. Method Issues.
cd ~/treadmill/journal7/beagle && be log — the
beagle sub of a be get be://localhost/journal clone whose be patch be://spot/journal?main! advanced it. cur = 9721f5328b06… (spot's beagle, the post ?#9721f532 row in .be/beagle/refs), but be log prints: 6c969149 06Jan Add cat command to RDX CLI (Claude) ← tip row, NOT the cur, ancient 6faf2fc8 02Mar be docs 0b6cce1b 28Mar spot tweaks 69a72a4f 19Oct24 RDXJ test files initial b0daa83d 28Mar25 fix: missed commit, bug, regression fcfeade5 13Apr Merge branch 'dogs-graf' into dogs-sniff 71f25366 31Aug24 I see the light … — dates non-monotonic throughout.
~/journal/beagle/build/bin/be, built 16:14): `cd
~/journal/beagle && be log — cur 213c9003, log is CLEAN, strictly time-descending: 213c9003 10:53 … / 04aca8e9 10:48 / ae64dc7f 10:34 / 25851a5a 09:52 / 607c3048 09:30 …`. Tip row = the cur, newest-first.
be log | grep -c '^[0-9a-f]' = *1557* in BOTH.
~/journal/beagle is the NATIVE locally-built store; journal7/beagle is a be get be://… CLONE (objects/graf landed in wire-fetch order). The ONLY difference is the store layout → the only variable that can explain the jumble.
reproduces from a fresh be get be://localhost/journal of a diverged journal.
be log renders newest-first / topo-stable from the cur REGARDLESS of how the store
was populated: a be get be://… clone and a natively-built store with the same closure produce the SAME row order (tip row = cur, dates monotonic on a linear spine).
not the store's physical object/graf insertion order.
graf/LOG.c GRAFLog/graflog_branch/DAGTopoSort); keep LOG-001's
non-spine greying intact and at C/JS parity. Repro-first (CLAUDE.md §17): a hermetic fixture that populates a store in a SCRAMBLED object/graf order (mimicking a wire fetch) and asserts be log row order == the natively-built store's (RED today).
graf/DAG.c DAGTopoSort, the closure-orderer): it descended into
a merge commit's parents in *LSM-run scan order*, which is the store's physical ingest order. Chain: topo_parents_of → DAGParents → DAGRange scans the LSM runs newest-first and yields the equal-key (COMMIT,COMMIT) parent edges run-by-run, in place. A merge whose two parent edges landed in DIFFERENT runs (the norm for a be get be://… CLONE — objects/graf arrive in wire-fetch order, scattering across levels) therefore handed back its parents in store-layout order. Plain DAGTopoSort's topo_parents_of did NOT sort the parents (unlike DAGTopoSortTunable's topo_links_of, which calls topo_sort_u64), so the DFS descended into a layout-dependent parent first → the topo order, and hence the reverse-emitted log rows, scrambled with the layout. The DAGAncestors hash SET iteration is NOT the culprit (slot is keyed on the intrinsic commit hashlet); the parent-descent order is.
graflog_branch is now a
pure first-parent walk (NOT the LOG-001 full-closure DAGTopoSort walk described in LOG-001's Outcome — that C change is NOT in this tree, and graf/test/log-merge.sh / GRAFlogMerge are absent). So default be log no longer hits DAGTopoSort and the original jumble does not reproduce on either the old build/bin/be (rebuilt 16:14) or the new build-log/bin/be. But be log:<path> (file history) AND be head still use plain DAGTopoSort, and if LOG-001's closure-topo graflog_branch is re-landed the jumble returns. Fix at the DAGTopoSort primitive so it is layout-invariant for ALL callers (file-history today, branch-history when LOG-001 re-lands).
topo_parents_of (one topo_sort_u64 call),
making the DFS descent — and thus the whole topo order — a pure function of the commit hashlets (content), independent of ingest order. Mirrors the per-kind hashlet sort already in topo_links_of (DAGTopoSortTunable). Tiebreak is content-derived (hashlet); the walk is seeded from the cur's ancestor closure.
graf/test/LOGORD01.c builds the SAME merge DAG
under two LSM-run layouts (native vs scrambled clone) and asserts DAGTopoSort row order is identical + intrinsic (tip=cur, newest-first). RED before fix, GREEN after.
topo_parents_of parent-descent order in
DAGTopoSort); made it intrinsic (hashlet-sorted parents).
~/journal/beagle unchanged (tip = cur 213c9003); ctest green.
-~ JS be/views/log/log.js not present in this working tree (the be/ JS tree referenced
by LOG-001 is not checked out here) — could not cross-check; flagged for the JS owner.
it hard to read what the merge produced; corrected reasoning depends on a trustworthy be log.
graflog_branch was reverted to a first-parent walk after the ticket was filed; the fix is proven at the DAGTopoSort primitive (the shared orderer) instead, which is where the layout dependency actually lives and where LOG-001's closure walk would re-expose it.
be get be://localhost?/beagle clone WITHOUT the be/ submodule cannot configure the
default WITH_JS=ON build (JS-095); built WITH_JS=OFF (348/348 C suite green).
af8e40dd (trunk, FF; full af8e40dd3d4f35c2c88b703b8ad83b34519fa69a).
FIXED. ROOT CAUSE (proven, not asserted): graf/DAG.c DAGTopoSort descended a merge's parents in LSM-run (store-ingest) order via topo_parents_of→DAGParents→DAGRange, which DAGRange scans newest-run-first; a clone scatters a merge's two parent edges across runs, permuting the descent and so the reverse-topo log rows. Plain DAGTopoSort (unlike DAGTopoSortTunable) never hashlet-sorted the parents.
graf/DAG.c): topo_parents_of now hashlet-sorts the parents (topo_sort_u64,
+moved its fwd-decl above the function). Descent — and the whole topo order — is now content-intrinsic, layout-invariant. graf/INDEX.md DAGTopoSort line updated.
graf/test/LOGORD01.c, CMake LOGORD01test in graf/test/CMakeLists.txt):
hand-builds a merge DAG R←A1←A2 , R←B1←B2 , M=[A2,B2] under TWO LSM-run layouts (native: M's parent edges in runs 0/1; clone: swapped) and asserts DAGTopoSort's newest-first order is IDENTICAL and intrinsic (tip=M, root last, every parent after its child). RED before fix (native 60 50 30 40 20 10 vs clone 60 30 50 40 20 10); GREEN after (both 60 50 30 40 20 10).
build-log/bin/be log — journal7 clone tip = cur 9721f532, time-descending;
~/journal/beagle tip = cur 213c9003, time-descending (unchanged). File-history be log:graf/DAG.c on the clone is now deterministic run-to-run. ctest (re-verified at land, 2026-06-26): full suite 348/348 at -j8, incl. LOGORD01test. Built only in build-log; did NOT touch beagle/build.
af8e40dd (clean fast-forward, no SNIFFNOFF; remote
be://localhost tip advanced 213c9003→af8e40dd). Change set: graf/DAG.c, graf/INDEX.md, graf/test/CMakeLists.txt, new graf/test/LOGORD01.c. Filed 2026-06-26 (treadmill session); journal not committed.