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.