An index is a dog's read side: sorted runs of fixed-width integer key/val records, the lookup mirror of the PackLog. Keeper's object index, Spot's trigram index, and Graf's DAG index share one shape: NNNNN.<dog>.idx runs on ABC's LSM/SST/HIT. The goal is append-fast writes, binary-search reads, no in-place rewrite: it grows by flushing a run, shrinks only by merging. The method: sort a batch into a run, binary-search newest-wins, and merge size-tiered once a younger run outgrows 1/8 of its elder.
Every dog needing lookups keeps NNNNN.<dog>.idx runs beside its data, numbered by the same store-wide seqno as pack logs; only the key/val widths differ.
keeper.idx: key=hashlet60|type4, val=offset40|file_id20|flags4 — object location by sha prefix.spot.idx: trigram and symbol runs mapping code features to the blobs holding them; --fork N stripes the build.graf.idx: DAG edges only, (COMMIT,COMMIT) parent and (COMMIT,TREE) root-tree; path resolution stays in keeper.Keys are fixed-length integers (u64, u128, sha256-shaped), so a run is an ABC SST: a sorted key-value table with an embedded skiplog, deterministic to the byte.
A write sorts the batch and flushes one run; a read mmaps every run and binary-searches each, so reads never block on compaction and writes never touch a live run.
Runs accumulate until they break the 1/8 size-tiered invariant; compaction then merges the youngest violators into one run — the LSM way to bound run count.
KEEPCompact merges the youngest stack until it holds..idx, unlink consumed sources, swap the shard's run mmaps — invoked from KEEPClose.A lookup is a range query, not a point query, since keys pack a sub-field and callers hold a prefix; the whole project pool is one search space.
[p<<4, p<<4|0xf], spanning all object types at once.(file_id, offset) hit feeds the PackLog read, which chases the delta chain bottom-up.