GRAF-002: lazy commit indexer for first-touch/mtime (p1/p2/p3/p4)

Now:
OPEN

A lazy, watermark-driven commit indexer that extracts each commit ONCE into the graf .graf.idx LSM family, so first-touch/mtime queries run index-only (no keeper inflate). Record set: p1 parentage, p2 commit->tree, p3 LAZY tree-child edges (/todo/BLAME/BLAME-002 shape, new-node-only), p4 commit-ts. First-touch = a p1 walk with p2/p3 descent-by-name, ts read from p4 (NOT a seek). Unifies today's three independent DAG walkers: /todo/LIST/LIST-001 (shared/lastcommit.js), log:path file-history (views/log/log.js fileHistory), and the wanted mtime-sorted todo board.

Input

Context

Three consumers re-derive the same per-commit tree-diff on demand, none cached; graf.js (GRAF-001) only caches ahead/behind pairs.

Goals

An index that answers "newest commit that changed path P, and its ts" with ONE seek, built incrementally, sized by diff volume not tree count.

Constraints

Reuse the existing LSM/idxmaint plumbing and graf's 60-bit hashlet identity; keep the change unrelated to the ahead/behind pair cache.

WIP

Design decisions

Record set: p1 parentage, p2 commit->tree, p4 commit-ts (sentinel+DAG), p3 = TREE-CHILD edges (content-addressed, NOT change postings — AMENDED 2026-07-23, see below). Rulings pinned below.

TODOs

-v Core scaffold + hermetic test landed (in-process, WRONG p3 =

change postings). Reworking to tree-child p3 per the amendment.

- Rework shared/commitindex.js p3 => tree-child edges

combine(parent_tree_h60,name)->child_h60, lazy new-node-only via a store.readTree walk; strip ts from p3; drop the blob-0 tombstone.

- firstTouch(path) = p1 walk + p2/p3 descent-by-name, ts from p4,

keeper-inflate fallback on a p3 miss over a covered tree set.

- Watermark/coverage is per-COMMIT (p2 sentinel); rebase/reset re-

walks tip->first-covered by construction (no forward-range rebuild).

- changedpaths integ: an INDEX-BACKED reader (resolve child by

(tree_h60,name) via p3, inflate on miss) fed to changedpaths' existing readTreeRecursive reader slot — the ONE shared descent. Indexer materialises p3 by its own tree walk, NOT changedCommits.

- Wire the mtime todo board (todo recent, lowercase arg route in

views/todo/todo.js) onto firstTouch, wtlog blend on top.

- Migrate lastcommit.js (LIST-001) + log:path fileHistory onto the

index reader with keeper-inflate fallback on any coverage miss.

- Parity test vs the on-demand walkers on a real repo (journal).

Blockers and bummers

Outcome

Nothing landed yet. Suggested first commit once the indexer + board land: GRAF-002: lazy commit indexer, change postings, mtime todo board.