Changes touching this path
- evidence: open the perf gate's prove-it run (#638)
b31adba4 · dbf3dbe6… - loot-perf: name the fixture commit for what it is (#638)
Perf-Baseline: reset the fixture commit message is part of the serialized change record, so naming it moves bundle_bytes by 21 bytes on a fixed tree
44bee9fb · dbf3dbe6…diff - evidence: the perf gate blocks a real counter move and the trailer clears it (#638)
f81b8442 · dbf3dbe6…diff - evidence: the series, the alarm going quiet, and what the gate really costs (#638)
4c144a32 · dbf3dbe6…diff - evidence: close the perf-gate run — the load-skip case, the full series, the real cost (#638)
e1212d24 · dbf3dbe6…diff - evidence: repair the series table and complete it with the fifth land (#638)
8e83202d · dbf3dbe6…diff - loot push: send the change delta once per push, not once per 32-object batch (#680)
The defect, receiver-counted (#633) by the CLI tier (#635): a push of the
2000-file fixture put 14.4 MB on the wire for ~0.5 MB of bundle, because
every 32-object batch re-carried the full change delta — O(batches x delta)
where O(delta) is available, the same shape #98/#99 fixed one level up.
bundle_wanted_batched now builds the first bundle exactly as before (change
delta, attestations, purge lane, first object batch) and every follow-up as
object-only: the batch ciphertext plus the public keys for exactly those
objects. Keys stay per-batch because a receiver files a riding key only for
an object stored from the same bundle; everything else lands with bundle
one, ahead of all object bytes (the sequential send in cmd_push is
load-bearing).
Compatibility class: no format change in either direction. A Sync frame
with changes=0 has been a valid encoding since v1 (the golden fixtures pin
it) and stow stores objects without requiring a change in the same bundle,
so the deployed relay ingests the new shape on its existing path — and an
old client re-sending the delta every batch stays accepted (pinned by a
forge test). bundle_impl is untouched, so single-bundle products —
bundle_bytes, the fetch server, the metadata-only /ingest bundle — are
byte-identical.
Resume after interruption still works and is tested: an interrupted push
leaves the relay with an incomplete closure, negotiation_have (#217)
refuses to claim such heads, and the re-run re-offers the delta in its own
first bundle — once per attempt, never once per batch.
Forge: /stow defers the change at batch one and no longer resolves it
alone; the closing /ingest (whole delta, all keys, unchanged) does. An
object arriving in a change-less follow-up takes introduced_by from the
envelope pusher — same key as the author on a self-push. Documented at
loot-forge::ingest and in the ADR 0024 amendment.
Measured with loot-perf-cli from this lane against a loopback relay,
small_files/2000, reps 2, idle box: wire_bytes 14392934 -> 600236 bytes
(-95.8 percent), bit-exact story unchanged (0 discarded batches).
1f59fa97 · dbf3dbe6…diff - forge: the migration ledger records a statement checksum and refuses silent divergence (#720)
1f851cda · dbf3dbe6…diff - loot push: send the change delta once per push, not once per 32-object batch (#680)
The defect, receiver-counted (#633) by the CLI tier (#635): a push of the
2000-file fixture put 14.4 MB on the wire for ~0.5 MB of bundle, because
every 32-object batch re-carried the full change delta — O(batches x delta)
where O(delta) is available, the same shape #98/#99 fixed one level up.
bundle_wanted_batched now builds the first bundle exactly as before (change
delta, attestations, purge lane, first object batch) and every follow-up as
object-only: the batch ciphertext plus the public keys for exactly those
objects. Keys stay per-batch because a receiver files a riding key only for
an object stored from the same bundle; everything else lands with bundle
one, ahead of all object bytes (the sequential send in cmd_push is
load-bearing).
Compatibility class: no format change in either direction. A Sync frame
with changes=0 has been a valid encoding since v1 (the golden fixtures pin
it) and stow stores objects without requiring a change in the same bundle,
so the deployed relay ingests the new shape on its existing path — and an
old client re-sending the delta every batch stays accepted (pinned by a
forge test). bundle_impl is untouched, so single-bundle products —
bundle_bytes, the fetch server, the metadata-only /ingest bundle — are
byte-identical.
Resume after interruption still works and is tested: an interrupted push
leaves the relay with an incomplete closure, negotiation_have (#217)
refuses to claim such heads, and the re-run re-offers the delta in its own
first bundle — once per attempt, never once per batch.
Forge: /stow defers the change at batch one and no longer resolves it
alone; the closing /ingest (whole delta, all keys, unchanged) does. An
object arriving in a change-less follow-up takes introduced_by from the
envelope pusher — same key as the author on a self-push. Documented at
loot-forge::ingest and in the ADR 0024 amendment.
Measured with loot-perf-cli from this lane against a loopback relay,
small_files/2000, reps 2, idle box: wire_bytes 14392934 -> 600236 bytes
(-95.8 percent), bit-exact story unchanged (0 discarded batches). (conflict resolution: docs/benchmarks/series.jsonl)
4603ab55 · dbf3dbe6…diff - loot-perf: run_cli probes the machine as found, ahead of its own build and fixture wake (#704)
5e49dfb6 · dbf3dbe6…diff - loot adopt: the git-first catch-up fast-forwards content-identical work unsigned and names foreign paths (#705)
044c84ac · dbf3dbe6…diff - forge: /stow answers the relay StowReport JSON so forge-routed pushes report wire bytes (#647)
431ade3f · dbf3dbe6…diff - land gate: never rewrite the tree being signed, never trust a stashless verdict (#698, #723)
132e06ba · dbf3dbe6…diff - forge: /stow answers the relay StowReport JSON so forge-routed pushes report wire bytes (#647) (conflict resolution: docs/benchmarks/series.jsonl)
0a6f1514 · dbf3dbe6…diff - loot adopt: the git-first catch-up fast-forwards content-identical work unsigned and names foreign paths (#705) (conflict resolution: docs/benchmarks/series.jsonl)
534a61b3 · dbf3dbe6…diff - loot-perf: run_cli probes the machine as found, ahead of its own build and fixture wake (#704) (conflict resolution: docs/benchmarks/series.jsonl)
c0176a93 · dbf3dbe6…diff - push negotiates the change lane against the relay /haves so a small land ships its delta, not 7 MB of re-sent history (#728)
2df34147 · dbf3dbe6…diff - loot-first: land folds a pre-finalized change so the perf point rides it (#725)
d98f26f6 · dbf3dbe6…diff - loot-first: land folds a pre-finalized change so the perf point rides it (#725) (conflict resolution: docs\benchmarks\series.jsonl)
3d4e3e86 · dbf3dbe6…diff - push negotiates the change lane against the relay /haves so a small land ships its delta, not 7 MB of re-sent history (#728) (conflict resolution: docs/benchmarks/series.jsonl)
f599f30c · dbf3dbe6…diff - release: bump loot-cli and loot-forge to v0.3.0 for a relay+forge redeploy
15ba4ad7 · dbf3dbe6…diff - a view step refuses over work no change records, and a primary finalize says so on stderr (#436)
a3248ede · dbf3dbe6…diff - ADR 0042 + spec: loot's native tracker is a directory of sealed paths in the repo's own tree (#599)
c8fa1b26 · dbf3dbe6…diff - loot <verb> --help prints that verb's usage block plus its accepted flags, not all ~80 verbs (#585)
b87eae53 · dbf3dbe6…diff - a view step refuses over work no change records, and a primary finalize says so on stderr (#436) (conflict resolution: docs\benchmarks\series.jsonl)
62ade8bc · dbf3dbe6…diff - the relay expands a pulling client's declared heads, so a one-behind pull ships its delta and not the whole change lane (#734)
e3f7604c · dbf3dbe6…diff - the forge stops shipping keys for retracted publications, and publication finally has a producer (#709)
ddcf4de9 · dbf3dbe6…diff - a ferry pass refuses to project over an open conflict, so a catch-up after a resolve can no longer land the side nobody chose (#653)
a9b5fd64 · dbf3dbe6…diff - a land from the primary refuses when the git checkout is parked on another branch, so a projection can no longer write across someone else's work (#618)
Level A of #618, first half. `reconcile_onto` materializes the reconciled tree
over the running position's disk; from the primary that disk is the shared
checkout, the one position that also carries a .git. Parked on another session's
branch it takes landed content across their working copy — observed live, the
primary ended up holding main's content against research/tracker-prior-art, and
only luck (their work was committed and pushed) made it harmless.
`projection_target` (policy.rs) decides from two facts: the position running the
land, and the branch its checkout is on. A lane's projection writes its own tree
and leaves the primary for its own `loot adopt` (#265), so the guard is silent
there rather than crying wolf on the normal way to work. Off-branch from the
primary refuses, naming the branch; --allow-off-main is the break-glass. An
unreadable branch (detached HEAD, no .git, a git that failed) proceeds but says
the guard did not run, so a broken git cannot mute it silently.
The refuse/proceed decision is carried out on Gate::Proceed's new `note` rather
than re-derived by the caller, so what gets reported cannot drift from what was
decided.
Level A's second half — refuse a primary tree dirty with content that is not
this land's — is deliberately absent: from the primary the implicit snapshot
(ADR 0030) has already captured that dirt into the landing change, and dirt
arriving after the review round is already refused by review_currency (ADR
0033). The residual, recorded in policy.rs: a land with no reviewed_version
takes Currency::Current unconditionally, so that path is still unguarded.
Levels B and C remain open.
c1148309 · dbf3dbe6…diff - release: bump loot-cli and loot-forge to v0.3.1 for a relay+forge redeploy
beab8725 · dbf3dbe6…diff - a land from the primary refuses when the git checkout is parked on another branch, so a projection can no longer write across someone else's work (#618)
Level A of #618, first half. `reconcile_onto` materializes the reconciled tree
over the running position's disk; from the primary that disk is the shared
checkout, the one position that also carries a .git. Parked on another session's
branch it takes landed content across their working copy — observed live, the
primary ended up holding main's content against research/tracker-prior-art, and
only luck (their work was committed and pushed) made it harmless.
`projection_target` (policy.rs) decides from two facts: the position running the
land, and the branch its checkout is on. A lane's projection writes its own tree
and leaves the primary for its own `loot adopt` (#265), so the guard is silent
there rather than crying wolf on the normal way to work. Off-branch from the
primary refuses, naming the branch; --allow-off-main is the break-glass. An
unreadable branch (detached HEAD, no .git, a git that failed) proceeds but says
the guard did not run, so a broken git cannot mute it silently.
The refuse/proceed decision is carried out on Gate::Proceed's new `note` rather
than re-derived by the caller, so what gets reported cannot drift from what was
decided.
Level A's second half — refuse a primary tree dirty with content that is not
this land's — is deliberately absent: from the primary the implicit snapshot
(ADR 0030) has already captured that dirt into the landing change, and dirt
arriving after the review round is already refused by review_currency (ADR
0033). The residual, recorded in policy.rs: a land with no reviewed_version
takes Currency::Current unconditionally, so that path is still unguarded.
Levels B and C remain open. (conflict resolution: docs/benchmarks/series.jsonl)
fffe4498 · dbf3dbe6…diff - a change records when it was authored, so a projected commit stops reading '6 years ago' on GitHub (ADR 0043)
loot changes carried no timestamp, so the git bridge fabricated one:
BASE_EPOCH + generation, one second per ancestor depth from a 2020 epoch.
All 526 commits sat inside seven minutes of September 2020. Earlier repairs
(#626's floor, the missing-generation refusal) fixed ORDERING and never
touched the absolute date, which is why this kept coming back.
ADR 0028 inherited the no-timestamp constraint rather than choosing it. The
real reason is upstream: a version id is blake3 over authored content, and a
clock inside that hash gives two peers different ids for identical content,
destroying the dedup and convergence of ADR 0001/0004.
So authored_at rides the label seam ADR 0029 already cut for change_id --
covered by the finalize signature (no relay can restamp it) but never folded
into the version id. The wasm golden vectors prove the separation held:
FROZEN_VERSION_ID, FROZEN_OBJ_ADDR and FROZEN_SIGN are byte-identical, and
only the version marker and one presence byte moved.
Advisory, and never an ordering input: a self-reported clock is a claim, not
evidence (ADR 0025). in_order/ids_topo, buoy and path_touch.ordinal are all
untouched, the forge indexes nothing on it, and the projection floors it past
every git parent so ancestry holds whoever's clock is wrong.
Format v11: additive for readers (a v<=10 change decodes as None and an absent
timestamp adds nothing to the signed message, so every existing signature
still verifies), breaking for writers, so loot-cli and loot-forge go to 0.4.0
in lockstep. Forge migration 0004 stores it as bigint, not timestamptz --
signed data must round-trip bit-exact or pullers reject the change.
Only new work gets real dates. Every commit on main predates v11, main is
push-fast-forward-only, and backfilling would fabricate the very claim this
replaces.
Perf-Baseline: reset the change body grew one presence byte, plus eight where a timestamp is present, so bundle_bytes/store_bytes/wire_bytes step once at the v11 boundary
eaa56d99 · dbf3dbe6…diff - a resolution records which side it answered, so catching up after resolving no longer re-raises the path (#744); ADR 0039 says what the one-commit promise actually guarantees (#653)
b837289e · dbf3dbe6…diff - a resolution records which side it answered, so catching up after resolving no longer re-raises the path (#744); ADR 0039 says what the one-commit promise actually guarantees (#653) (conflict resolution: docs\benchmarks\series.jsonl)
f8a85d84 · 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.