Changes touching this path
- day 0: loot hosts loot
f4c30e75 · dbf3dbe6… - evidence: crew minted and verified (#86)
1fada823 · dbf3dbe6…diff - hard embargo engine/wire lands (#14, format v5)
7784bcac · dbf3dbe6…diff - normalize working tree to LF: byte-stable co-located bridge (.gitattributes -text)
e58fdda6 · dbf3dbe6…diff - S0: stable-change-id data model + FORMAT_MAJOR 6 (#143)
Implement the durable change-id data model per ADR 0029 — the keystone the
jj-ergonomics trio (map #142) builds on. Two ids per change: the existing
content-derived **version id** (`ChangeNode.id`, unchanged role: dedup, DAG
edges, sync addressing) and a NEW random 16-byte **change id**, a durable
handle stable across a working change's re-snapshots.
- `ChangeNode` gains additive `change_id: Option<[u8; 16]>`; never folded into
any hash.
- The Workspace mints a fresh change id when a change begins and carries it
across every re-snapshot (`snapshot_allowing` reads the prior working node's
id before dropping it; `record_carrying` carries, `record` mints when
authored). Keyless/bridge/legacy changes stay `None`.
- Finalize signs over `version_id ‖ change_id` (new `change_signing_message`);
`verify_authored_change` checks the same. A legacy change (`change_id = None`)
signs over the version id alone, so pre-v6 signatures still verify unchanged.
All four CLI finalize paths widened (finalize_working, sign_change, resolve).
- Wire/durable codecs carry the change id after author+sig, gated on major >= 6
(`put_change_id`/`read_change_id`); idempotent on re-receipt.
- FORMAT_MAJOR 5 -> 6; legacy decodes as `None`, no backfill. v6 goldens added,
v5 kept as decode-compat.
Parents, dedup, sync addressing, convergence: unchanged (they key on the
version id). No display/verb changes — that is S2.
Tests: change id stable across re-snapshots while version id rewrites; keyless
mints none; v6 signed-over-both-ids verifies through apply; relabelling the
change id after signing is rejected; v6 bundle/graph round-trip; v<=5 loads as
legacy. Verified end-to-end via the CLI (alice bundles a v6 signed change, bob
applies and verifies).
f253ce09 · dbf3dbe6…diff - Merge pull request #157 from Connor-Miller/s0-stable-change-id-format-6
S0 — Stable-id data model + FORMAT_MAJOR 6 (keystone) (#143)
Git-Author: Connor Miller <53197564+Connor-Miller@users.noreply.github.com>
419d6996diff - loot edit: amend a finalized change; supersession travels as signed predecessors (ADR 0032, #171)
Implement the amend model: `loot edit <change-id>` reopens a finalized
tip change as the working change - a sibling (parent = its parent, tree
carried address-for-address, durable handle kept) whose `predecessors`
names the reopened version - so once `loot new` signs the amend, the
claim that X-prime replaces X is signed data that travels, not a
local-only abandon.
- Format: FORMAT_MAJOR 6 -> 7 (ADR 0019). ChangeNode.predecessors:
Vec<Oid> rides the bundle + durable graph after the change id,
canonically sorted, empty = ordinary; folded into the version-id
computation (a no-op amend still mints a distinct version) AND into
the finalize signature (version_id || change_id || predecessors) -
ingest trusts received ids, so stripping/forging a supersession claim
on the wire must break the signature directly. v7 reads v<=6 as
predecessors-empty; goldens updated, v5/v6 kept decode-compat.
- Liveness (amends ADR 0029's definition): superseded - named as a
predecessor by any in-graph same-cid version, regardless of that
supersessor's own abandoned/superseded state - joins abandoned as a
live-view filter in divergence detection, versions_of_change, and
log/status rows. Abandon means kill, never revert.
- Converge: converge_heads drops superseded heads before collapsing
forks (a solo amend lands at peers as a clean replacement, never
content-merged with the version it replaced); dock merge adopts an
amend of our tip as a fast-forward and treats the mirror case as a
no-op (supersedes() requires the claim to sit ON the other line).
- The verb: a named Workspace mutation; refuses on an in-progress or
uncaptured working tree (the documented ADR 0030 exception - edit
replaces the working change and never implicit-captures), on a
divergent handle (abandon first), and on descendants (tip-only v1).
One undoable op (ADR 0031); output through the render String seam.
- dock switch: an idle dock no longer parks a tip-duplicate working
child on its tip (the finalize_capturing duplicate-drop now runs
there too) - the stray polluted the tip descendants and, post-0032,
would have content-merged against amends.
Tests: engine liveness + canonical hashing + signature strip/forge;
codec round-trips + v7 goldens; workspace edit e2e / guards / undo /
dock-merge FF / converge drop. Live-verified on the built binary
(edit -> amend -> new; guards; undo). 366 tests + clippy clean.
8176f2e0 · dbf3dbe6…diff - Workspace accepts its clock; lane flag-gate goes pure so cmd_* tests never touch a real .loot (#322)
20ac82e1 · dbf3dbe6…diff - Grant expiry: optional expires_at on GrantEntry and tag-3 wire (#20)
a01c3d53 · dbf3dbe6…diff
Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.