DIS-082: append-only weave — body + tok32-pair index, tombs as entries

Now
OPEN

-- design settled with gritzko, 2026-07-30

Today's 'W' blob is rewritten whole on every fold (dog/WEAVE.h:100) because DELETION MUTATES stored tokens: a later commit sets rm and pushes into 'M', so earlier bytes cannot be final. Make deletion its own index entry and the BODY becomes strictly append-only — a commit's text bytes are final forever, the small parent-sorted INDEX merges per commit, and the merge-time renumbering that DIS-081 exists to fix never happens. The shape: a BODY of text pieces, an INDEX of tok32 pairs carrying the CT parent/child relation, and a per-commit table of bounds. 'X'/'K'/'I'/'M'/'C'/'A' collapse into three streams.

Input

Context

The current six-column layout pays for in-place tombstones.

Goals

An append-only format where a commit's bytes are final once written.

Constraints

Weaves are derived data; git is the oplog.

WIP

Streams

Three streams replace the six columns; TLV tags below are PROPOSALS, pin them before coding. The BODY is append-only, the INDEX is SORTED — not the same property.

Entry shapes

The child tok32's TAG field carries the entry TYPE; a syntax tag means an ordinary token, a reserved letter means tomb or terminator.

Reading

Document order is a preorder walk of the CT; visibility is a bound plus an exclusion.

Design decisions

Settled in conversation; the rest is Blockers.

TODOs

Spec first, then reader, then writer, then callers, then cutover. Nothing lands before the parity harness exists.

//DIS-082-jab conversion plan

The jab binary embeds dog and exposes it to JS via jab/weave.hpp (JSC leaves, installed by cont.cpp); JS-side callers live in be/. The old surface is 12 _weave_* leaves; the CFOLD surface is smaller because scope bitmaps, the identity hash and the step cursor all dissolve into commit indices and body offsets.

Blockers and bummers

Outcome

Suggested commit (//DIS-082 wt, staged): DIS-082: CFOLD replaces WEAVE (append-only weave + emit)