Changes touching this path

  • a pull declares its ancestor closure instead of bare heads, so a server behind the client stops re-sending the whole history to say nothing new: the live forge no-op drops from 15.6s to 1.85s with no redeploy, and the wire gains an opt-in timing instrument (#1258) c1971c5e · dbf3dbe6…
  • the pull declaration becomes an enum a subset cannot alias through, which also stops a fresh clone re-downloading the full delta every batch, the wire timing line gets named fields, and the reap window scalar stops sharing its name with the pair type (#1284) 3b657494 · dbf3dbe6…diff
  • a relay or forge answer that keeps arriving is read whole however long it takes, and one that stops fails on a named budget instead of hanging. reqwest blocking client defaults to a 30 s timeout that wire.rs believed it never set, and bytes() held it over the whole download, so loot clone failed with it did not answer in time while the answer was still arriving. transfers now carry a 30 s silence budget on the client and read the body read by read, so it bounds each wait for bytes and not the download; a probe keeps its deadline as a request timeout over the whole request. a timeout now names the limit that fired, no answer began within, no bytes for, or a probe deadline, claimed only when the failing wait lasted it, and no timeout says the relay is cutting the response. red first, the shipped binary clone through a local proxy throttled to 3 kB/s failed at 30 s with the ticket message; the lane binary cloned it (70 s body) and failed a proxy that stalls mid-body after 30 s naming the budget, and a read-only depth 1 clone of the live relay took its 53.7 MB answer in about 118 s. red under mutation: the body read through bytes() (2 passed, 1 failed), the transfer budget as a request timeout (2 passed, 1 failed), a client with no timeout (1 passed, 2 failed, both hung to the guard), a probe deadline on the client (0 passed, 1 failed), the budget claimed without the wait check (0 passed, 1 failed), and the timeout remedy put back on the cut sentence (0 passed, 1 failed). no wire or format byte moves and no forge or relay byte moves; the client binary change owes a release. the workspace suite is green (3942 passed over 123 binaries, 7 ignored) (#2064) ef88503d · dbf3dbe6…diff
  • a lander can no longer read a pre-land finding as the refusal whose recovery is to change nothing, and the gate claims no verdict only when neither run reached one. the no-verdict refusal opens on a heading of its own, pre-land cargo test: NO VERDICT, and a finding keeps the old heading and never says in words of its own that the compiler did not answer, so the crash it quotes from the first run cannot be mistaken for the other refusal; land-change keys its two recoveries on those headings. a build failure and then a crash is now a finding, not no verdict: the first diagnostics are the only verdict either run reached and the crash neither confirmed nor cleared them, so telling the lander there is nothing to fix would claim more than the gate knows. a re-run that cannot start cargo now says a re-run happened, leaving the merged-tree remedy to #2066. afk-loop reads the verdict line through land-change instead of keeping a second list of values, the --skip-tests block stops stating the CI net as a fact and names ci/local.sh for when the job does not run, and the claims that the job is only cargo test are narrowed to what ci/test-main.sh runs. red first: a finding carrying the no-verdict words, a build failure and a crash judged as no verdict, and a re-run spawn failure that never said a re-run happened (0 passed, 3 failed). red under mutation: the finding rendered with the retry evidence (2 passed, 1 failed), the no-verdict guard dropped from the first run (1 passed, 2 failed), the re-run note dropped from a spawn failure (2 passed, 1 failed), and the deadline dropped from the new wire pin (0 passed, 1 failed). the ticket premise about a deadline ceiling is corrected: in reqwest blocking a request timeout replaces the client per-wait timeout, so a deadline is not undercut by the transfer budget, and a local server pins that. the smells are taken: the fake spawner stdio choice is an enum, wire post takes a budget as get does, Endpoint get sends in one place, the transport remedy sentence is written once, add_attestation is add_attestations with one record, and CargoTestFailure Other is named Finding. no migration, no wire or format byte moves and no forge or relay byte moves, so this owes no deploy. the workspace suite is green (3946 passed over 122 binaries, 7 ignored) (#2071) bb8acc52 · dbf3dbe6…diff
  • a transfer waits for its answer on a budget read off the bytes it is sending, not on one constant: reqwest blocking holds a single wait over connecting, the whole upload and the peer working on it, so the number #2064 kept for the header wait was never a limit on silence but a floor under the uplink rate this client will tolerate, and below that rate a healthy push is refused while its bytes are still going out, which a push batch capped at an eighth of MAX_BODY_BYTES makes reachable rather than hypothetical; the silence half stays a constant, because a body read returns the moment any bytes arrive and there the number really does bound inactivity. wire::transfer_budget is the floor plus room for the upload at UPLINK_FLOOR, rounded up to a whole multiple of the floor because a budget is a client and a client is a connection pool, so an exact budget would mint a pool per body size, and the rounding costs a peer that says nothing at most one extra floor of waiting; bytes past what any loot host accepts buy none, so the wait stays bounded by the body. the budget now rides the response it produced, through Answered, so a body read is measured against the number reqwest held that request to rather than one the reader recomputes, which would otherwise repeat the #2064 error in the opposite direction. measured before choosing a number, with LOOT_NET_TIMING=1 on this desktop: the fault-injection pushes are hundreds of bytes and answer in tens of milliseconds, the eighty-change push at about 170 kB answers in under a second, and under two concurrent workspace builds, heavier than the load the refusing land ran under, the worst answer was 64 ms and thirty-three rounds of that binary went green; so 30 s was never marginal for a local relay, and the land #2079 escalated on was the process not running rather than the relay being slow, which is recorded beside TRANSFER_IDLE and leaves the ticket open for it. whether a wall-clock budget failure should be classified the way #1873 classified a compiler that did not answer is decided no, recorded beside Refusal in orchestrator.rs: that classifier reads stderr and a failing test panic is on stdout, widened to the whole run the text it would key on is minted by transport_text and asserted verbatim by the budget tests next door, so a genuine failure of one would read as not a finding, and the claim itself would be false because the compiler answered and the suite answered. red under mutation, counts read each time: the budget ignoring the bytes sent (9 passed and 3 failed), the body read recomputing the budget from the floor instead of carrying it (12 passed and 1 failed), the rounding dropped for exact seconds (12 passed and 1 failed), and the cap at MAX_BODY_BYTES removed (0 passed and 1 failed). no migration, no wire or format byte moves, and no host behaviour moves because the change is entirely on the client side of the transport, so this owes no deploy and rides the next release. the workspace suite is green (4011 passed over 125 binaries, 7 ignored) (#2079) 8e8a873d · dbf3dbe6…diff
  • a census door is one statement rather than one line, a transfer budget can no longer round below its own floor, and the pool split by body size is measured before it is kept: loot-cli temp_root_census read a forwarder as a body of two lines, so spawn_lane was a door only because its arguments happened to fit on one, and wrapping that call took it out of the door set with every site that reaches a refusal through it, while the property test stayed green and the only thing that fired was the blind-instrument clause naming workspace harbor.rs, which is a fact about where #2113 was found rather than a reading of what a door is; measured, the wrap took the walk from 26 door calls over 10 files to 24 over 9, and with the fix in place the same wrap reads 26 over 10 again. a body is now the one statement its lines join into, however many lines the arguments take, and a forwarder whose call is wrapped joins the fixture the file supplies, while a statement spelling a brace of its own stays outside the set the way the line count left it, said where a reader meets it. transfer_budget tested the floor in milliseconds against zero, so the branch written for a floor that cannot be stepped in fired for every floor under a millisecond and handed back the bytes own whole seconds, which is Duration ZERO for any body under an uplink floor and therefore below the floor rather than above it; the step is read in nanoseconds now, the resolution a Duration keeps, and the budget is built from nanoseconds rather than by multiplying the floor by a count that has to fit a u32, with the pin widened from the one floor where the old reading held to a run of floors from a nanosecond up. the pool keyed by transfer budget was decided on a measurement rather than on prose: a push shaped run of a probe, batches at the cap a push fills to and a short remainder keys two budgets and opens two connections at a host that counts them, so the repeated full batches share a pool and the bill is one connect per extra size class, once per host per process and never one per request, against the 160 ms a fresh HTTPS connection costs on the live hosts; keying on something size independent was checked against the vendored reqwest 0.12.28 and is not on offer, because a request own timeout becomes the async side total limit and is handed to the response body, which is #2064 exactly, and read_timeout lives on the async ClientBuilder alone and nowhere under blocking, so the choice is this keying or no per transfer budget at all, and the narrowing is now said at the client instead of waiting to be rediscovered. store_rename_census keys a row on a fn name where Rust makes a name unique inside an item scope rather than inside a file, so rather than read scopes textually and risk putting a wrong function name in a table that exists to be read by review, the case is held out of reach by a guard refusing a rename that sits in a name its own file declares more than once. the readings that had grown byte identical copies across the censuses, the source walk, the comment stripper, the qualifier test and the function header reader, now live in one file every caller compiles, by path across the package boundary the way loot-first already reaches loot-perf, and loose_object_removal_census gives up its narrower header reading for the shared one, which moves nothing in its expected set. loot-core temp_root_census gains the membership rule its what it cannot catch list had been standing on without one. red under mutation, counts read each time: the line count reading put back into sole_statement (2 passed and 1 failed), the step read in milliseconds again (0 passed and 1 failed), the pool keyed on a constant so one connection serves both classes (0 passed and 1 failed), no pool at all so five requests open five connections (0 passed and 1 failed), a second archive_keypair declared beside the renames in loot-identity (3 passed and 1 failed), and the shared qualifier test made to read no bare word, which reddens two packages from one edit (1 passed and 2 failed in loot-cli, 1 passed and 3 failed in loot-core). no migration, no wire or format byte moves and no forge or relay byte moves, since the budget arithmetic is entirely on the client side of the transport, so this owes no deploy. the workspace suite is green (4013 passed over 125 binaries, 7 ignored) (#2126) c5061276 · dbf3dbe6…diff
  • the browser sdk transport stops waiting on a silent host indefinitely, because fetch has no timeout of its own and in a browser nothing stands in for one: HttpRelayTransport now aborts through a watchdog that waits for an answer to begin for its idle budget plus the upload at the uplink floor, then re-arms on each chunk of the body, so an answer that keeps arriving is not cut for its size and one that stops fails once the idle budget passes with no bytes, the same policy #2079 gave the native client, with TRANSFER_IDLE_MS mirroring wire::TRANSFER_IDLE and each side now naming the copy on the other. a budget that runs out throws a TransportError naming which wait it was and how long, and the adapter passes that through instead of relabelling it as an unreachable host, one rule in errors.ts asked by every catch around a transport call. TWO OF THE THREE ITEMS ARE REFUTED RATHER THAN BUILT: the forge blocking clients the ticket named both sit inside cfg(test) modules, in the tree today and at the rev the ticket was filed on, and the forge talks to its object store only through loot_s3::S3Client, which already names its own 60 second timeout; and the upload side header wait was fixed under #2079 by the byte-derived transfer budget, whose refusal already names the answer budget. the frozen-tab limit is written down rather than fixed, since a timer on the page loop measures the page clock and not peer silence, which is #2079 in a browser. red under mutation, counts read each time: the re-arm moved outside the read loop failed the steady-answer pin (6 passed and 1 failed), the answer wait ignoring the bytes failed two (5 passed and 2 failed), the watchdog verdict dropped failed all three budget pins on a bare AbortError (4 passed and 3 failed), and the adapter relabelling every throw failed the pass-through pin (0 passed and 1 failed), each restored. the sdk suite is green against release binaries built in the lane (137 passed over 13 files), no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4179 passed over 133 binaries, 9 ignored) (#2070) f6348ba0 · dbf3dbe6…diff
  • the tutorial interrupt red #1916 read as a removal that lied is a tree made again after the sweep: on the linux runner std remove_dir_all answers success only once the root is gone, the captured transcript prints the first prompt ahead of the handler line, and walk, still running on the main thread beside the handler, opened with a create_dir_all over alice that minted the root back before ask beat the heartbeat into it. two delays injected into that sequencing reproduced the red and its alice, heartbeat remnant on this desktop with confirm_gone in place, so that check alone would not have closed it; Sandbox::create now makes alice before the handler is armed, the same two delays pass, and a unit pin drives the sweep, the walk and the beat in that order. what stays open is said at the fix: other writers, the relay thread and the loot subprocesses among them, can still put a path back mid-step. the CI run recorded the two readings and not the sequencing, so the mechanism is established by reading and by the reproduction rather than observed there, and workflow.md stops calling the report and the look one moment. the loot-s3 client keeps its 60 s budget for want of any measured rate to its bucket, but a request that runs out now names it and what it covers, where reqwest said error sending request or error decoding response body with no word of a deadline. the sdk doc stops claiming the native policy: the formula is copied, native allows the send budget between answer chunks where the sdk allows idleMs, the rounding differs, wire.rs now points back at the copy, and the unit test reads the floor from its constant. smaller: the engine.rs verdict compares the band against the band, the measure.rs refusals state a property instead of counting callers, the fixture generator import note sits at the import, and transportFailure takes a role rather than a string. red under mutation, counts read each time: create_dir_all put back in walk (11 passed and 1 failed, holding alice and heartbeat), the s3 timeout naming removed (12 passed and 2 failed), the sdk upload rounded down (6 passed and 1 failed), each restored to 12, 14 and 7 passed. no migration and no wire or format byte moves; the forge and relay deployables word a timed out object store request differently once next deployed, and no code in the tree matches on that text, so this owes no deploy. the workspace suite is green (4192 passed over 133 binaries, 9 ignored) and the sdk suite is green (137 passed over 13 files) (#2254) bdeb6a0c · dbf3dbe6…diff
  • a network budget refusal now says how long the wait lasted beside the limit, and a relay loot-net serves writes a received line and an answered line per request under LOOT_NET_TIMING=1 on the client clock, because the #2079 stall is unreproduced and nothing on record could say where its time went. the wait is timed around the whole send while the reqwest limit starts inside it, so time well past the limit was spent in this process rather than waiting for the host. the relay lines landed in the failing test captured output beside the client lines when a panic was put after a push and removed, and the land-shell use of the flag is written into workflow.md. no retry is built and no cause is claimed. a workspace run went red once on both format_skew_gate tests under load, one printing the wait lasted 5.5 s on its 5 s probe, and both passed alone: that file now prints what its stub took. the seek smoke test drops the flag from the loot it spawns, since it pins their stderr and failed with the flag set. red under mutation, counts read each time: the wait printed as the limit (1 passed and 1 failed), the wait stored as the limit (0 passed and 1 failed), the relay layer not attached (0 passed and 1 failed), no line on arrival (0 passed and 1 failed), each restored to 2, 1, 1 and 1 passed. no migration and no wire or format byte moves; a relay prints lines only with the flag set, so this owes no deploy. the workspace suite is green (4196 passed over 133 binaries, 9 ignored) (#2079) ac8afc4b · dbf3dbe6…diff
  • loot-s3 gives an object-store request a budget that grows with its body in place of one 60 s deadline over the whole transfer. a get now reads its answer read by read, so the 60 s client timeout, renamed IDLE_BUDGET, bounds silence and not length: an answer that keeps arriving is read however long it takes, and one that stops fails after IDLE_BUDGET and names how many bytes it got. a request that sends a body is held, as its own request timeout, to upload_budget: IDLE_BUDGET plus the whole seconds of the body at UPLINK_FLOOR_BYTES_PER_SECOND, a copy of the native uplink floor of 256 KiB a second. reqwest blocking sends the body inside the one wait for the answer to begin, so an upload can have a deadline and not a silence limit, as in loot-net (#2079), and that reasoning is recorded at the code. the formula is copied from loot_net::wire::transfer_budget with pointers both ways rather than moved to loot-core or reached through a new loot-net edge: the copy drops the rounding that keys a connection pool and the cap a loot host enforces, bounds the send alone, and a shared home would tie the rate for a client link to a loot host to the rate for a server link to its bucket. no rate for that link was measured, since no script in the scripts repo measures one; the floor is the native choice, not a measurement. a timeout on each wait names its budget and what it covers. pinned over loopback peers: a large get that stalls mid-body, a get whose answer keeps arriving past the idle budget, a put the store reads slowly past it, a large put the store stops reading, and the formula on its own. red first (13 passed and 5 failed). red under mutation, counts read each time: the get read by one bytes() wait (17 passed and 2 failed), no deadline on a request with a body (17 and 2), the body earning nothing (16 and 3), the body capped at 64 MiB (18 and 1), part seconds rounded up (17 and 2), a deadline on every request (18 and 1), a read timeout not recognised (17 and 2), the put deadline not named (17 and 2), each restored to green (19 passed). no migration, no format byte and no published wording moves; loot-forge links loot-s3, so this is live once the forge is redeployed, and loot-relayd links it too but the relay the scripts repo deploys is loot serve, which does not. the workspace suite is green (4370 passed over 138 binaries, 12 ignored) (#2309) ac9b9c50 · dbf3dbe6…diff
  • the browser SDK budget refusal prints how long the wait lasted beside the limit, as the native refusal has since #2079, and names it as read off the page clock: the wait runs from the moment its timer was armed, the whole request for the answer and the time since the last bytes for a silence mid-answer, so a frozen or throttled tab shows as a wait well past the limit. budgetRanOut and transport_text_from point at each other. a forge loot-forge serves writes the received and answered lines a relay writes under LOOT_NET_TIMING=1, opening loot-net: forge, through loot_net::timing_layer, which the relay now attaches through too; with the flag unset serve_until passes no sink and the forge serves the router app builds with no layer added. pinned by a stalling loopback peer across a blocked page loop and across a silence after a streamed answer, and by a forge with a timing sink. red first (7 passed and 2 failed). red under mutation, counts read each time, each restored to green: the wait printed as the limit (8 and 1), the wait timed from the first arm (8 and 1), the clock label dropped (7 and 2), the forge passing no sink (0 and 1), the forge named relay (0 and 1), the arrival line naming relay whatever the server (0 and 1), the layer ignoring its sink (0 and 1 on the forge, 2 and 1 on the relay). CONTEXT.md and workflow.md record it. no migration, no format byte and no wire byte moves; the SDK refusal text changes and the forge writes lines only under a flag the scripts repo never sets, so this owes no deploy. the workspace suite is green (4398 passed over 139 binaries, 13 ignored), the sdk suite 141 passed over 13 files, tsc clean (#2313) 1b9a9597 · dbf3dbe6…diff
  • the review-sweep fix-up over #2308, #2310, #2311, #2312 and #2313. the lock note beside a failed test is said only on a Windows land: loot-hygiene failed_tests now takes whether the run was on Windows, since os error 5 and 32 are an I/O error and a broken pipe on macOS and Linux, and loot-first passes cfg!(windows); both answers are pinned on this host, red under mutation with counts read each time (recognised everywhere 2 passed and 1 failed, nowhere 0 and 3, loot-first passing false 1 and 4). the plain pre-land test finding now prints the re-run-first recovery the merged pass prints, for each gate row that runs programs and rides the merged pass, derived from the row and pinned whole (no triage 3 and 2, ignoring the merged pass or the row judgement 4 and 1 each, the order swapped 4 and 1). the timing line noun is a ServerKind enum whose relay and forge lines are pinned byte for byte (a misspelled noun 7 and 1), and the loot-s3 put refusal calls the idle duration the idle budget and keeps floor for the rate (the old word 18 and 1). tutorial.rs qualifies the #2311 halt as run on Windows and reasoned elsewhere, and a reap failure no longer prints could not run; ADR 0075 names the graph read by MetadataStore::repo_change_graph and its callers rather than a list that missed propose::admit; sync.rs states the store property the scoped forge offer rests on and what would break it, and its round-zero comments speak of the remote; land-change SKILL.md, workflow.md and ADR 0055 carry the re-run-first order and the Windows-only note. the (idle, uplink_floor) data clump in loot-s3 is left as it is. no migration, format byte or wire byte moves; the loot-first change is live once the primary release binaries are rebuilt. the workspace suite is green (4406 passed over 139 binaries, 13 ignored) (#2348) 77d9c94c · dbf3dbe6…diff
  • every compiled-in and current-tense loot host moves to loot.build (map #2412, ADR 0099): loot --help names security@loot.build and https://loot.build/trust, ALPHA_PROMISE_URL is https://loot.build/install and the telemetry DEFAULT_ENDPOINT https://loot.build/api/telemetry, so the next release carries them; the site install one-liners, R2_BASE and HOP_BASE (https://dl.loot.build, https://loot.build/dl), the metrics SITE_SCOPE and own-host referrer, the disclosure links on trust, terms, privacy and known-issues, and the install, quickstart and guides pages follow, with the privacy and terms markers moved to 25 September 2026 and re-pinned since readers see the new address; README, CONTEXT.md (the forge door now forge.loot.build), the release checklist, site CI and test fixtures follow, and the two specs carry a note instead of a partial rewrite. the destination census gains build in WEB_TLDS, without which security@loot.build would be invisible to its bare-host clause, and exempts the two shipped lines that tld makes read as hosts (state.build, r.build()) by their exact text; ADR 0074 section 9 says twelve-entry to match. 37 lines still name millerbyte.com outside ADR bodies, evidence, research and scratch, each kept on purpose: dated history, millerbyte.com the site and its @millerbyte/ui tokens, the two noted specs, and relay-era tooling with no successor host, filed as #2438. census red with build dropped from WEB_TLDS, restored; site gate 819 passed and within budget; workspace suite 4559 passed over 142 binaries, 13 ignored (#2418) c5663115 · 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.