Changes touching this path

  • loot seek answers for a loot repository on a relay or a forge without a working tree and without its bodies, and does so beside #2043 rather than behind it: a loot host, named by a loot+ URL, by an http URL whose info endpoint answers, or by a bare word the ambient repo config resolves as a remote name, is read through a body-less cache position, an ordinary loot store under the cache home that copies the ambient repo keypair, or the one --identity-from names, and never mints one, because a fresh key is 403 at a forge and reads only Published on a relay. each invocation refreshes it with the metadata half of a pull only, the closure-declared fetch every bounded pull starts with, ingested at depth one and with no wants round, through the routed transport a pull already uses, and collects a forge standing self-grants as clone does. a key rides beside its ciphertext, so a body-less change carries no key: a listing gates on the tier the tree records, Internal listed and Restricted or a live Embargo counted sealed, and the real key gate decides after a search or a read has fetched the listable bodies in one batched round, only those the store does not hold. the store already tolerates withheld bodies and this verb never reads one it has not fetched, so the fifth kind of absence #2043 would name is never classified here; what #2043 still owes stays its own. the workspace gains the two thin seams, pull_metadata_via and fetch_objects_via, and a holds check the engine now exports. ADR 0090 records the decision the map left to #2043, in docs/adr where a decision lives: the cache directory is this verb alone, the private key copy is refused for a sealed source and a failed make leaves none behind, offline is a refusal never a stale answer, and grants are collected without acking so a peer grant is never consumed into a cache. the two-axis review before landing put the pull doc back on its function, made the listing gate Internal-only because an embargo key has no bundle lane even after its instant, refused a multi-head remote without --at, excluded burned objects from a prefetch, probed the host once per invocation, made --identity-from a plain word read from the process directory, split collect_grants out of pull-grants with the ack a choice, folded the loot loop into loot_answer beside git_answer with one row push, and pinned the refresh closure declaration, the cache object store through the binary, and a remote name resolving to the same cache. the unit tests pin the seams over the in-memory relay, the tier gate, the object fetch that brings only what was asked and declares the closure, a refresh that sees a later change at depth one, and the cache over a spawned relay carrying the source identity; the spawned-binary pin pushes the fixture to a relay spawned in the test, holds the remote listing to the local one by path and visibility with the sealed path withheld and counted, checks the cache identity is the repo's, reads a body verbatim, refuses from outside any repo naming --identity-from, and answers with it. red under mutation: the metadata pull asking for every object (0 passed, 1 failed), held bodies fetched again (0 passed, 1 failed), the object fetch declaring nothing (0 passed, 1 failed), an embargoed path listable without its body (0 passed, 1 failed), the cache minting an identity (0 passed, 1 failed), a second open making a second position (0 passed, 1 failed), and the refresh skipped (0 passed, 1 failed). 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 (3972 passed over 123 binaries, 7 ignored) (#2092) 669baef4 · dbf3dbe6…
  • loot seek pays fewer round trips: a remote target is answered from its cache inside --fresh <secs> with every round trip the open makes past the record check skipped, today the info probe, the metadata pull and the grant round, and a bare http URL a loot cache already stands for is routed to it before the probe, from a record the cache writes on every refresh, the first included, holding the clock the workspace reads and never a file mtime, and a record that is missing, will not parse or is ahead of the clock refreshes rather than trusts; the answer says so, target.refreshed under --json only under the flag, the key that did not exist before riding the flag that did not exist before as the R row rule has it, and one prose line when the refresh was skipped, on stdout beside the other summary lines and on stderr for a read whose stdout is the bytes; --fresh over a local target is conflicting_flags since there is no refresh to skip and a window that is not a number is bad_flag_value; the window skips the refresh rounds and never the fetch a question needs, and since a host answers an object round with whatever the declared closure lacks, a change pushed since the refresh rides back beside the bodies a search or a read fetched, which ADR 0090 records and the smoke pins rather than hides. the bodies a question needs travel in rounds of seek::OBJECTS_PER_FETCH, 256, through fetch_objects_via whose batch is now the caller's while the pull keeps its own 32, chosen by measurement over a relay spawned in-process holding 400 small bodies, best of three on loopback: 32 per round is 13 rounds and 243 ms, 64 is 7 and 193 ms, 128 is 4 and 158 ms, 256 is 2 and 136 ms, 512 is 1 and 126 ms, the table flattening past 256 while the memory a round holds keeps doubling; the 413 halving the ticket first asked for is not built and the ticket was corrected before the first test, because a fetch request carries ids alone and the response is unbounded, so there is no 413 to fall back from. several --text patterns are one read of each kept object and the union, a line carried once however many matched it so --count counts it once and --max-line cuts it once, with a pattern that will not parse naming itself as it did alone; a repeated --text was accepted before and silently narrowed to its first value, the one shape that moved, and ADR 0023 says so. ADR 0023 records the key and the union, ADR 0090 the window and where the record lives, and CONTEXT the three. pinned on the record round trip and the inclusive window arithmetic, the union over a fixture line two patterns hit, a git cache and a loot cache each answering stale inside a window and fresh outside it, the batch read off the test relay round count with the verb own prefetch one round, and through the spawned binary on a head pushed between two calls, unseen at the recording clock inside the window and seen at a clock outside it, with the refreshed key present under the flag and absent without. red under mutation, counts read each time: a line two patterns hit carried twice (0 passed, 1 failed), only the first --text scanned (0 passed, 1 failed), the window never holding (0 passed, 1 failed), the window exclusive (0 passed, 1 failed), the git cache ignoring the window (0 passed, 1 failed), the loot cache not recorded on the first make (0 passed, 1 failed), the refreshed key written without --fresh on a loot remote (0 passed, 1 failed) and on a git remote (0 passed, 1 failed), a window over a local target accepted and inert (0 passed, 1 failed), the refreshed key dropped from the JSON target (0 passed, 1 failed), the batch argument ignored (0 passed, 1 failed), the verb prefetching at the pull batch (0 passed, 1 failed), a record ahead of the clock trusted (0 passed, 1 failed), the git answer dropping the refresh (0 passed, 1 failed), a stale read saying nothing (0 passed, 1 failed), and a stale read fetching no body (0 passed, 1 failed); the loot-remote key mutation first ran green against a pin that read only the git remote, and the pin was widened before it was believed. 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 (3987 passed over 124 binaries, 7 ignored) (#2108) 83c96c6a · dbf3dbe6…diff
  • the seek cache home is bounded, and loot seek --gc tends it: every remote an agent touches leaves a position under the cache home and nothing bounded it, so the rule is now one function, seek::gc::plan, that the verb and the cap share and cannot disagree on, a position being a directory the two caches make, a .git holding a HEAD or a .loot holding a .loot, with its bytes on disk and the clock of its last refresh read off the #2108 record and never an mtime; a position whose record is older than the age asked for goes, then oldest first by that record positions go until the home is within the cap, and a position with no readable record is never removed by the cap because its age is not known and a cap is not a reason to guess, listed with a dash and removed only on the explicit ask, --older-than 0, which removes every position; a position another invocation is refreshing right now is busy and removed by nothing, since both caches write their record last and a position in use would otherwise be exactly the oldest candidate, so a refresh writes loot-seek-refreshing when it begins and removes it on every exit, a marker older than an hour reading as a crashed refresh; 0 is no cap. on every invocation that refreshed a position the home is measured against LOOT_SEEK_CACHE_CAP, 2 GiB when unset, and the oldest other positions go until it fits, said on stderr in one line, never the position just refreshed whatever its age, and a skipped refresh inside --fresh measures nothing, nor does the ambient repo; the environment cap is read before any target opens so a value that will not parse is bad_flag_value at no round trip, the just-refreshed position is matched on canonical paths so a URL spelled in another case still names its own, a removal that fails is said in the same line and never refuses the answer, and the measure is a walk of sizes and records only, targets read by --gc alone, paid once per refreshing invocation, 2 ms over this desktop cache of three positions and 217 files against the 30 ms process floor, which is the cost of having no size record to trust. loot seek --gc does the same on demand with --older-than <days> defaulting to 30, --cap <bytes> defaulting to the environment, and --dry-run deciding and removing nothing, printing one row per position with kind, bytes, refresh clock, what was done and why, and target, and the home bytes before and after, a failed removal a failed row with the error on the notice channel; beside any question it is refused by code as --schema is, its flags without it the same way, and a value that will not parse is bad_flag_value. its porcelain is two new marks, G and H, under a flag that did not exist before, in their own GC_COLUMNS table the mark census now reads beside MARK_COLUMNS, and --schema files the four flags under maintenance rather than among a question flags, since the SDK reads that set as the fields of a question, which its schema pin holds green unchanged; the shapes are frozen where every seek shape is, in an ADR 0023 amendment, and the one stderr line is recorded against its remote-answer sentence there. pinned pure on the rule, by age, no age, oldest first under the cap, the unrecorded position standing though the home is still over, the explicit ask, the kept position under both, the busy one under all three, a record ahead of the clock, and a tie on the clock going in path order; on the walk over a hand-made home with a bare git repo, a loot position, an unrecorded one, two directories that are not positions, a fresh marker and a stale one, canonical paths and the sizes-only walk; on a failed removal rendered failed with its bytes standing and the removals around it still done; on the schema census over both tables and the maintenance key; and through the spawned binary in the smoke suite over the relay and the git caches it already makes, the cap on an invocation removing the older git position and never the loot one just refreshed, a malformed cap variable refused by code before an unreachable host costs a round trip, the ambient repo measuring nothing, a skipped refresh measuring nothing, --dry-run in porcelain and JSON removing nothing with the H totals the sums of the G rows, a cap the two standing positions just fit removing the older git one in JSON, a cap of one byte unable to reach the unrecorded position, thirty-one days removing by age, a busy marker holding the unrecorded position against the explicit ask until it ages out, and the seven refusals by code. ADR 0090 and ADR 0023 amended, CONTEXT Seek, the usage line and the synopsis. red under mutation, counts read each time: age never removing (0 passed and 1 failed), the cap removing newest first (0 passed and 1 failed), the cap guessing at an unrecorded position (0 passed and 1 failed), the just-refreshed position going by cap (0 passed and 1 failed), the just-refreshed position going by age (0 passed and 1 failed), --older-than 0 not the explicit ask (0 passed and 1 failed), the walk skipping the loot kind (0 passed and 1 failed), the walk reading no record (0 passed and 1 failed), a loot target never read (0 passed and 1 failed), the gc flags landing among a question flags in the schema (0 passed and 1 failed), the H row losing its removed count (0 passed and 1 failed), --dry-run removing (0 passed and 1 failed), the cap on an invocation never running (0 passed and 1 failed), the cap on an invocation removing the just-refreshed position (0 passed and 1 failed), a skipped refresh measuring the home (0 passed and 1 failed), a gc flag beside a question admitted (0 passed and 1 failed), a question beside --gc admitted (0 passed and 1 failed), a busy position going (0 passed and 1 failed), a stale marker busy forever (0 passed and 1 failed), the walk reporting the spelled path rather than the canonical one (0 passed and 1 failed), a failed removal reported as removed (0 passed and 1 failed), the loot refresh writing no busy marker (0 passed and 1 failed), the git refresh writing no busy marker (0 passed and 1 failed), the guard never dropping the marker (0 passed and 1 failed), the busy marker surviving the refresh (0 passed and 1 failed), and the environment cap read after the target opens (0 passed and 1 failed). no migration, no wire or format byte moves, and no host behaviour moves, so this owes no deploy beyond the one #2123 already owes the release. the workspace suite is green (4023 passed over 126 binaries, 7 ignored) and the SDK seek suite is green in the lane (11 passed) (#2125) 70ea581b · dbf3dbe6…diff
  • loot doctor names the deferred absence and every ordinary open refuses a store in it, the first stage of the body-deferring filter: a store whose bodies are fetched on demand now carries .loot/deferred-bodies (the remote and what asked, read fail-closed so a record that will not parse still counts), the seek cache position writes it whenever it opens a position lacking it, doctor reports it as an info bodies line, and Workspace::assemble refuses such a store naming the state for every open except the new Workspace::open_fetching_bodies_at, which the cache opens through, so a verb that would read an unfetched body as absent or sealed is refused rather than answered; a body fetch that fails in the cache now refuses naming the state and the host. ADR 0093 records the state, the refusal at the open and the offline policy (a refusal, never an absence and never a stale answer, reachability never recorded), ADR 0090 gains a #2043 amendment and CONTEXT.md gains the deferred kind under Absence. what #2043 still owes is the filter on a working position, whose flag name is left open, and verbs that fault a body in instead of refusing. red under mutation, counts read each time: the open refusal dropped (0 passed and 2 failed in the seek pins, 0 and 1 through the binary), the record read fail-open (0 and 1), doctor never naming the state (0 and 2), the fetch refusal unwrapped (0 and 1), the record written only when made (0 and 1), each restored to green. a new plain-text store file, no format byte moves and no migration, so this owes no deploy. the workspace suite is green (4313 passed over 138 binaries, 12 ignored) (#2043) ee57a2ef · dbf3dbe6…diff
  • the seek tests no longer write into the cache home of whoever runs the suite, and a cache position with no refresh record is removed when its refresh fails. every loot the seek smoke test spawns is now built by one closure that sets LOOT_SEEK_CACHE to the test home; the unreachable-host refusal ran under the operator home and was the one call in the suite that could make a 127.0.0.1:1 position there, and the --name refusal made none, since it is read off argv before the target opens, so the premise that it did is corrected. the unit test that resolved git+file:///no/such/dir through Target::resolve now opens GitCache under a home of its own. the verb: a fresh make whose refresh fails was already removed, measured through the binary, but a position standing when a round began was not that round make, so a failed refresh removed nothing and the cap never removes an unrecorded position; LootCache::open_in now treats a position with no readable record and no live busy marker as on its first refresh and removes it whole when that fails, recorded as an ADR 0090 amendment and in CONTEXT.md, and gc::busy_at is the busy rule the open and the gc walk both read. pinned in seek.rs by a_position_whose_first_refresh_fails_is_removed_whole and in the smoke test, which seeds such a position in its own home. red first against the unchanged rule (1 passed and 1 failed, the passing one the edited resolver test). red under mutation, counts read each time: the removal keyed on the make alone (unit 0 passed and 1 failed, smoke 0 and 1), the busy check dropped (0 and 1), the record check dropped (0 and 1), no removal at all (unit 0 and 1, smoke 0 and 1), the smoke closure pointed at another home (0 and 1), each restored to green. the listing of the real cache home is unchanged, mtimes and sizes, across the full suite. no migration, no format byte and no published wording moves, so this owes no deploy. the workspace suite is green (4325 passed over 137 binaries, 12 ignored) (#2142) fc5a0816 · dbf3dbe6…diff
  • loot seek --gc exits 1 when a removal it decided failed, with every row and the H row still written and the error still on stderr: gc::Report now implements Emit::exit_code (#1764), 1 when any decision carries failed and 0 otherwise, 1 being the ADR 0025 row for an I/O error and the code the error path in main.rs exits with, the reasoning gates::EXIT_UNRUNNABLE records; the cap after a refresh is unchanged and a failed removal there does not move the question exit. the ticket named the hook #2127, which is loot pipeline, the verb whose code it cites; the hook is #1764. the ADR 0023 #2125 amendment gains the exit sentence, the ADR 0090 #2125 amendment says the invocation exits 1, and the seek module doc scopes its refusal-only exit rule to a question. pinned in a_failed_removal_is_reported_as_failed_and_stops_nothing: the report exits 1, and 0 with the failure cleared. red first against the unchanged code (0 passed and 1 failed). red under mutation, counts read each time: the code fixed at 0 (0 and 1), fixed at 1 (0 and 1), keyed on a decided removal rather than a failed one (0 and 1), each restored to green. through the binary under a scratch LOOT_SEEK_CACHE with one position held open, the lane binary exits 1 and the primary release binary 0, both printing the removed and failed rows. no migration, no format byte and no published wording moves, so this owes no deploy. the workspace suite is green (4325 passed, 0 failed, 12 ignored) (#2154) 1dc9e314 · dbf3dbe6…diff
  • the review-sweep fix-up over #2299, #2142 and #2154. a seek cache round now claims the busy marker before it decides anything: LootCache::claim_and_make creates loot-seek-refreshing with create_new before it asks whether the position stands or makes one, so a position another invocation is making carries a marker from before its store exists, and a round that finds a live one neither makes the position over it (refused, naming the state, when no store stands yet) nor removes it when its own refresh fails; a marker past the hour is taken over. before, the marker was written after the make, and a second round inside that window read the half-made store as a leftover and removed it. a first refresh now means no record file at all (Refresh::absent): the record is written through atomic_write rather than truncated in place and read through read_replaced, so an empty or unreadable record is a refresh that finished and a failed refresh leaves that position standing. pinned in seek.rs by a_make_in_progress_is_not_removed_by_another_invocation, which drives a make through claim_and_make and fails a second round inside it, and by a_record_that_does_not_read_is_not_a_first_refresh; red first against the unchanged rule (1 passed and 2 failed, the make extracted into claim_and_make with the marker still after it). red under mutation, counts read each time: the claim moved after the make (1 passed and 3 failed), begin in place of claim (1 and 3), a round that finds a live marker deciding first on the record (2 and 2), absent read as unreadable (3 and 1), the record written with fs::write (3 and 1), no refusal over a claimed unmade position (3 and 1), a stale marker read as live (3 and 1), each restored to green. the seek unit tests now default to a cache home under the temp directory, pinned by the_unit_tests_cache_home_is_never_the_runners (red with the default dropped, 4 passed and 1 failed). stale sentences fixed: the ADR 0090 #2142 amendment is corrected, the CONTEXT.md seek entry names the marker exception and the gc exit, ADR 0023 scopes the refusal-only exit to a question, root_notice and discovered_store_dot say why the function is free rather than counting callers, the in_progress verb is the verb whose stop created the record and another verb is refused, the last-updated header states its import reach by reachedModules, the seek module doc states the exit property, and a CONTEXT.md rewrap leftover is rewrapped. through the lane binary under a scratch LOOT_SEEK_CACHE, a position with an empty record stands after a failed refresh and a marker-only position is refused with its marker left. no migration, no format byte and no published wording moves, so this owes no deploy. the site gate is green (680 passed and 62 skipped over 62 files, 62 surfaces) and the workspace suite is green (4328 passed over 137 binaries, 12 ignored) (#2303) 4c489c97 · dbf3dbe6…diff
  • the review-sweep fix-up over #2303, #2159 and #2172. the wake-up sender: its client is built with no_proxy, so a proxy named in the environment is not used, pinned in a test binary of its own that sets the proxy variables and sees the request reach the pinned address and not the proxy; refused_wake_address now refuses every address that is not globally routable unicast, an ipv6 address carrying an ipv4 one (mapped, compatible, nat64 64:ff9b::/96, 6to4) judged by the one it carries, so 64:ff9b::a9fe:a9fe is refused, with the refused blocks copied from the iana special-purpose registries at the code and a table of example addresses pinning the rule; name resolution runs on a thread waited on for at most WAKE_TIMEOUT_SECS with the request given what is left, and the wake-ups in flight are bounded by MAX_WAKES_IN_FLIGHT, a resolver that outlives its wait keeping its place until it returns. the ingest kinds trailer is now a byte per head in head order, still absent when no head declares a kind, so each head is given jobs for its own kinds only and no job is made for a kind a head has no step of; the pre-2159 decoder still reads the new payload, the one-byte union shape was in no release, and neither format constant moves, pinned against the marker put_version writes rather than its digits. MetadataStore::ingest answers the jobs its commit wrote (store::Ingested) and a push wakes runners for those alone, so a triple a racing request filed first wakes nobody here; the proposal job half answers no error once the proposal is committed and logs instead. the job_cost no-kind pin now states the property, that the job half calls the store for nothing when nothing is declared, instead of a list of methods. the seek busy marker: one that does not parse is believed until its mtime is past the window, so the instant between its creation and its clock no longer admits two holders, and a marker that cannot be created for a reason other than one standing there is retried and then refused naming the state rather than counted as held; the held-marker comment is scoped to a round that claimed it. the census wire half plants each oracle into every payload sent builds and asks each payload for moving bytes, calls the now-public verbs::sync::forge_declaration instead of a copy, records that the fixture declares no kinds, and records the measured flake rate of its minimum reading (200 runs: 40 of 1600 store builds and 15 of 1600 wire builds above the floor, none red). false sentences fixed: jobs.rs says what a false proposal declaration costs the owner and what the trust floor does and does not stop, ADR 0091 section 7 and its 2159 amendment are corrected with a 2307 amendment and the reads-not-writes scope of the job cost measurement, ADR 0090 and ADR 0004 gain corrections, CONTEXT.md names the per-head trailer, the census module doc states the property instead of naming places, and an in_progress rewrap leftover is rewrapped. red under mutation, counts read each time, each restored to green: no_proxy dropped (0 passed and 1 failed), the 2159 refusal rule restored (2 and 2), embedded forms unrecognised (3 and 1), 6to4 unrecognised (3 and 1), the resolver thread not holding its place (0 and 1), the ceiling ignored (0 and 1), the resolve wait unbounded (0 and 1), the trailer encoding the union (25 and 2), the forge unioning kinds across heads (1 and 3), the memory ingest answering every handed job (4 and 2), the push waking for planned jobs (5 and 1), the proposal refusing after a failed job write (3 and 2), the job half reading with nothing declared (3 and 1), an unparseable marker read as idle (1 and 1), a failed create counted as held (1 and 1), the census reading the bundle alone (9 and 4), every payload a copy of the bundle (10 and 3), the ingest payload emptied (11 and 2). no migration, no format byte and no published wording moves; the forge binary changes, so the sender and per-head jobs are live once the forge is redeployed. the workspace suite is green (4360 passed over 138 binaries, 12 ignored), and green under bash ci/local.sh against Postgres 18 (#2307) 665b3cec · dbf3dbe6…diff
  • the review-sweep fix-up over #2307, #2176 and #2193. a seek busy marker is believed while its clock is within the window of the reader clock on either side, so the round that claims first with the later clock is no longer taken over, and a marker that does not parse is dated by its mtime against that same now. loot propose --decline takes the version it declines, the full tip --show prints or a selector naming a version held here, following the grammar that already reads a version where a change id is expected; a change id is refused, the CLI finds the row standing at that tip and refuses when none visible does, so a revision made after the owner read the proposal is not declined. two act flags on loot propose refuse through ProposeAct::from_args, where the first one checked ran. the format-constant pin compares the marker of each trailer and act payload with the one a client from before #2159 wrote, recorded in the frozen codec copy, so a bump of either constant reddens it; a push declaring each head its own kinds is pinned through a two-head repo; the decline cost pin asserts the whole call sequence with the gate calls measured alone; the forge door tests ask every route in Route::ALL, now public, that the router mounts. each GATES row declares what its finding is read off (Judged): a finding off files gets a merged remedy that goes to loot edit at once, with no re-run and no file lock, and the pre-land pass rather than each finding says nothing has been signed or published, so the merged pass no longer prints it beside a signed merge; the #2193 census reaches each spawn after passing ones and holds every Judged declaration against the spawner. false sentences fixed in ADR 0055, 0075, 0090 and 0091, workflow.md, npm_not_started and the census doc, including a network-specific NAT64 prefix, which the wake-up rule cannot recognise; the forge refusals of withdraw and decline spell the tip as a version id; the cmd_propose doc sits on cmd_propose; the wake slot test waits for its places to come back. red under mutation, counts read each time, each restored to green: a marker ahead of the clock read as dead (2 passed and 1 failed), the unparseable marker dated by the system clock (2 and 1), the decline signing the tip the forge holds (4 and 1), a change id accepted (4 and 1), two acts not refused (4 and 1), FORMAT_MINOR at 1 (1 and 2), the push unioning kinds (0 and 1), a second read in the decline (0 and 1), /propose/read mounted without the door (0 and 2), the pre-land state line dropped (2 and 1), the files remedy replaced by the run remedy (2 and 1), the second perf spawn failure a finding (2 and 1), the site row declared Files (2 and 1). no migration, no format byte and no wire byte moves; the forge refusal wording changes, so that is live once the forge is redeployed, the decline argument once the CLI is released, and a land runs the primary release loot-first, so the gate changes are live only once those binaries are rebuilt. the workspace suite is green (4392 passed over 139 binaries, 12 ignored), and green under bash ci/local.sh against Postgres 18 (#2325) ff3b789d · 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.