be log / jab log follow non-spine (merge) parents too, rendering non-spine commits in greybe log (and the JS jab log) walk only the FIRST-PARENT spine, so commits merged in as a second (or later) parent never appear — even though they are fully reachable. Live: a merge 213c9003 whose 2nd parent is d6f7e138 (DIS-053) → be log | grep d6f7e138 is EMPTY; the commit is reachable (a parent of cur) but off the first-parent line be log prints. Goal: log also follows non-spine parents so merged-in commits show, rendered in GREY to distinguish them from the first-parent spine. Both the C (graf/LOG.c) and JS (be/views/log/log.js) versions, at parity. Method: Issues.
be log: graf/LOG.c GRAFLog walks the first-parent chain only (note the
"Hard cap on the first-parent walk" ~:51); graflog_render_commit /
graflog_pack tag each row with a tok32 tag (L/W/S) the theme colours.jab log: be/views/log/log.js mirrors GRAFLog (one row per commit,
newest-first) — the same first-parent-only walk.213c9003 (parent1 04aca8e9, parent2 d6f7e138). be log
shows the parent1 spine; d6f7e138 (parent2, DIS-053) is reachable but absent.
be map: (graf/MAP.c GRAFMap) shows the full branch tree, but log itself
never surfaces merged-in commits.be log and jab log follow non-spine parents (a merge's 2nd+ parents and their
chains), so merged-in commits appear in the listing — reachable history is
visible, not only the first-parent line.#N count / first-parent cap) so a
merge-heavy/deep DAG doesn't explode; apply a sensible cap across the non-spine
walk too. Topo- or time-order the combined listing.dog/THEME for C, be/view/theme.js for JS),
NOT a hand-rolled SGR; the plain (non-colour) sink stays uncoloured. Keep the tag
in parity across C and JS.DAGParents / DAGAncestors / DAGTopoSort in graf/);
no new graph index. ABC style; ragel/typed only. Repro-first (CLAUDE §17).#N cap.Q tok32 slot ("unk/dir" = grey,
FG16(90)) — already grey in BOTH dog/THEME (C binding paints it) AND
be/view/theme.js, so NO new tag/theme edit was needed; whole non-spine row
is Q-tagged.Q, ALIGNED to the landed JS choice (same tok32 byte).
Q reused, no new slot/SGR change; dog/THEME doc-comment only. Non-spine row:
EVERY span tagged Q; spine keeps per-column tags.DAGTopoSort) emitted reversed = newest-first (as file-history). Topo (not time)
keeps tied-author-ts merges deterministic (be-log-projector #N cap relies on it).
Spine = first-parent chain from the commit BODY. Bound: #N AND LOG_MAX_WALK
over the closure; index-miss → linear fallback. Differs from JS time-interleave.jab log (via
log.js branchHistory) OMITS C1 pre-fix (RED proven), shows it GREY after.graf/LOG.c GRAFLog/graflog_branch walks the full closure (DAGAncestors
+ DAGTopoSort, bounded); non-spine rows greyed via graflog_pack tag Q.be/views/log/log.js follows non-spine parents (bounded), greys them via
tag Q; NO be/view/theme.js edit needed (Q already grey there).Q match, order may differ
on tied-ts merges. Revive as its own ticket if byte parity ever matters.Q, but row order can differ on a tied-author-ts merge. Acceptable for
now (colour, not order, marks merged-in); a strict byte-parity test is deferred.bc040627 "LOG-001 jab log follows
non-spine parents, greyed"; C dog 21ffe0c4 / beagle pin 7f9163dd
"LOG-001 be log follows non-spine parents, greyed". Audit 2026-07-07: code
verified in-tree (graf/LOG.c DAGAncestors+DAGTopoSort walk, LOG_TAG_GREY 'Q',
graflog_branch_linear fallback, graf/test/log-merge.sh; log.js nonspine rows).
Byte-parity test deferred (see TODOs). CLOSED.be/views/log/log.js — branchHistory
(:170 rewrite, +non-spine BFS) returns [{sha,nonspine}]; appendRow (:340)
greys a non-spine row with tag Q; handler (:411) normalises rows. Test:
be/test/log/nonspine.js (+be/test/CMakeLists.txt reg) — RED pre-fix,
GREEN post-fix; full be/ suite green (only the pre-existing bro-universal
xfail-inversion remains). Grey tag used: Q. STOPPED before commit (human gates).graf/LOG.c graflog_branch walked the
first-parent spine only, so a merge's 2nd+ parent was reachable but never listed.
FIX (graf/LOG.c): graflog_branch (:395) takes the FULL closure
(DAGAncestors), topo-sorts (DAGTopoSort), emits newest-first; spine marked via
body first-parent (graflog_first_parent :339); non-spine greyed with tag Q
(LOG_TAG_GREY ~:221); index-miss → graflog_branch_linear. dog/THEME.c/.h
doc-comment only. REPRO graf/test/log-merge.sh (CMake GRAFlogMerge): hermetic
2-parent merge — 2nd-parent surfaces + greys, spine primary, plain uncoloured.
RED proven (linear path → "2nd-parent absent"); GREEN after. ctest 378/378.
Grey tag Q. STOPPED before commit (human gates).