Changes touching this path

  • loot tutorial: guided nine-step walkthrough of the core model in a temp dir (#24) 9bae4337 · dbf3dbe6…
  • loot tutorial: remove the temp tree on Ctrl-C (#513) fa318ba8 · dbf3dbe6…diff
  • the readiness wait stops being a wall-clock BUDGET over a polled directory and waits on the child OWN first line instead - a strictly stronger condition, because the banner is printed AFTER the signal handler is armed while the temp tree appears EARLIER, in sandbox create. so the directory only ever proved the run had STARTED, and a 500ms sleep stood in for and-by-now-it-is-probably-armed: signalling inside that sliver tests the GAP rather than the fix, which is why the wait was load-bearing and is REPLACED here rather than deleted. the banner is a pub const so the test waits on the VALUE rather than on a copy of the sentence, and the ordering it depends on is PINNED - and that pin is shown load-bearing rather than decorative, because moving the banner above the arming leaves the very test it protects GREEN on an idle machine. the damage would have been an INTERMITTENTLY red test, not an obviously broken one. the measurement behind all of this was REDONE rather than relayed, because the tree it was supposedly taken on DID NOT COMPILE - probes whose definitions had been deleted and whose uses were left behind - so nothing about it had ever been built, let alone run. 534 loaded runs against 12 idle, the test binary invoked DIRECTLY rather than through cargo so no rebuild could contend, under up to three concurrent cold workspace builds at 100% CPU. the correction is MATERIAL: the worst whole-test reading goes from 22.75 to 61.4 seconds, 2.7 times worse, and signal-to-exit from 18.3 to 29.8, 1.6 times worse - while the IDLE column reconciles exactly, which is what says the earlier figures sampled a quieter machine rather than a different test. two findings come out better than the ones they replace. the old 30-second budget is not marginal but EXCEEDED OUTRIGHT: three of 534 readiness readings blew past it at 61.3, 60.4 and 50.7 seconds, a 0.6 percent outright loss, reproduced rather than inferred. and the sibling one assertion below it was 215 MILLISECONDS short of being the same bug, at 29.8 against its own 30. so both clocks are re-derived as BACKSTOPS rather than budgets, and deliberately to the SAME number, because the measurement shows a machine that intermittently stops scheduling this child for tens of seconds and which slice a given stall lands in is LUCK - sizing each against only its own sample understates both by exactly the amount that sample under-sampled. the budgets-versus-backstops distinction is stated once for both: a budget is sized to how long the work ought to take and is therefore a claim about the machine, while a backstop is sized to nothing, exists only for states where no progress will ever be made, and must be far enough out that crossing it says WEDGED and never BUSY. the sibling sweep is recorded in the file so it is not redone from zero, and it was READ rather than line-window grepped - the rust suite comes out clean, every other bounded wait being over an in-process thread already awaited on a condition, or a LOWER bound, or iteration-bounded, or slack over a kill rather than a cold start. and one loaded run of the 534 failed UNEXPLAINED, in 0.48 seconds so not a clock at all, before the harness captured panic text, never recurring in the 510 that followed with capture on. it is recorded as what it is: a SECOND load-sensitive failure mode in this test, which this change does not close and must not be read as having closed (#1693) 0d517bfe · dbf3dbe6…diff
  • a const inserted BETWEEN a doc block and its function had silently stolen two of them, and the consts move above the blocks so each documents its own subject again: diff_spec gets back the section recording that diff is a POINT VERB AT EACH ENDPOINT - the deliverable of the very ticket whose edit displaced it - and archive gets back its omit-versus-refuse argument, its two inherited limits and its pathspec section. each const gains a doc about ITSELF, saying what the string holds and who interpolates it, which is the shape the two siblings that were already right had. a THIRD site of the same shape was found by sweeping for it rather than by assuming the two were all, and it is from August rather than from this run. the nothing-catches-this claim is MEASURED rather than asserted: re-inserting the defect gives zero build warnings, zero rustdoc diagnostics at the site and a fully green suite, because intra-doc links still resolve. and the guard question is answered honestly as REVIEW rather than a gate - the mechanical heuristic yields seventeen candidates workspace-wide, all seventeen were READ, and exactly ONE was real, so a gate built on it would ship sixteen hand-maintained exemptions of noise, which is the roster class this run has been burned by five sweeps running. the sha-shortening item finishes the EXTRACTION rather than fixing the sentence, and on evidence found before deciding: one arm of the same enum already called the helper while another sliced flat, two arms of one message shape disagreeing about the same value. the doc stops saying every, states the property, names what each of the two sweeps covered, names the non-scope, and says OUTRIGHT that nothing enforces the scope - a hand-written slice still compiles and review is all there is - with its surviving headline claim, a prefix and never a panic, pinned for the first time. and the ticket OWN PREMISES were refuted twice, which is the part worth carrying forward. the diff exemption was DEAD rather than load-bearing: deleting it leaves the test green, and an instrumented run prints diff answering thirty-six bytes, because loot diff leaves the second endpoint at the pending state and an empty WORKING CHANGE is not an empty DELTA - so it is deleted rather than justified, with the reason recorded at the site. and the claim that all twenty-five selector-taking verbs read the selector HEAD is false, because edit refuses it through a THIRD resolver - measured against the built binary, and now pinned with a control rather than left as prose. the unpublished figure behind a 215-millisecond claim is rounded to the table rather than published unmeasured, and the removals proof gives BOTH its outcomes a meaning, pinned by a mutation whose sibling stays GREEN (#1917) 0ad19cad · dbf3dbe6…diff
  • the tutorial interrupt handler reports what the removal did instead of that it reached the line, asks again when a concurrent writer takes the first ask, and the interrupt test pins the message against the filesystem rather than the tree alone. arm_signal_cleanup discarded the result of remove_dir_all and then printed the removed line regardless, so that line was a report of reaching that point over a tree that is where the private keys of both demo identities and the decrypted .env live (#513): the count-attempted-vs-done class in operator-facing output, and why Test - landed main went red five times through the 2026-09-16 run with the removed line and exit 130 both passing above the assertion that failed. the CI failure itself is NOT reproduced here and is not claimed to be, since that path is the linux runner, so what is measured on this windows desktop is the mechanism and the decision. a throwaway probe made remove_dir_all fail under a concurrent writer with DirectoryNotEmpty (os error 145), the windows spelling of the ENOTEMPTY the ticket reasons about: one attempt left the tree behind in 33 of 400 rounds at a 50 write burst and in 299 of 300 at 200 writes, three attempts 50ms apart left it behind in 0 of 200 and 0 of 300, and a writer that never stops defeated every attempt count measured, which is why the failure line exists rather than a fallback nobody expects to see and why both constants are the values they are. that table is recorded on SWEEP_ATTEMPTS as a measurement rather than as something re-derivable from the source. sweep_interrupted_tree takes its removal as a parameter because the handler ends in std::process::exit and cannot be called from a test at all, so the arm that reports a failure is reachable there and nowhere else; the failure line names the path, the error and that a later run reaps it, in the register of the note the handler already prints when it cannot arm, and writeln! over println! plus the discarded results after the report are untouched. red first, both ways: the discarded result put back reddens the refusal pin (8 passed, 1 failed, printing the removed line over a tree nothing removed), the attempt count at one reddens the retry pin and the real-writer pin (7 passed, 2 failed, the second naming os error 145 under a live writer, and 10 of 10 red run alone), and through the integration test, the handler removal forced to fail reddens it naming the refusal in the words of the handler (2 passed, 1 failed) while that mutation plus the pre-fix reporting reddens it naming a removal line over a tree still there (2 passed, 1 failed), which is the CI shape reached deliberately on windows. the real-writer pin stops its writer on the first attempt rather than after a fixed burst, because the burst version outlasted the sweep inside a full workspace run and went red, the load-sensitivity of #1693; it therefore does not guard the spacing, which is stated on SWEEP_SPACING and rests on the probe, with the spacing at zero measured green 5 of 5. the pre-interrupt tree.exists vacuity guard stays, and it is what makes the CI reading trustworthy. no migration, and nothing outside the tutorial verb moves, so this owes no deploy. the workspace suite is green over two consecutive runs (3863 passed over 119 binaries, 7 ignored) (#2037) 413891ed · dbf3dbe6…diff
  • the readiness waits over a spawned binary in sdk stop being budgets and start ending on the host itself, and the reason they were never seen to fire is now written where a reader meets them: every behaviour suite that stands a relay up polled a real loot serve behind Date.now() plus 20 seconds, which is a SMALLER budget than the 30 seconds that already lost in #1693 over a LARGER startup, and the 60 second beforeAll hook outside it sat inside the same measured spread, so raising the inner number alone would have left the effective bound where it was. the new sdk/test/spawned-host.ts has three endings and only the last is a clock: the probe succeeding, which is the condition these suites actually need since it proves the host ANSWERS rather than that it printed a line; the child exiting, reported with its code instead of polled at for the rest of the wait, seeded from the childs recorded state as well as its future exit event so a host already gone is not waited on; and a backstop carrying the same 600 seconds tutorial.rs carries, off the same saturated measurement and for the same reason, with the hook timeout derived strictly larger so the named refusal wins the race. the fixture generator imports that module rather than restating it, which node does by stripping the types itself. THE BEHAVIOUR SUITES CANNOT PIN ANY OF THIS AND THE CONTROL SAYS SO: with the condition deleted outright the whole sdk suite still read 11 files passed, because an idle machine has the relay up before the next await, so a dedicated pin over a spawned node child carries it instead. red under mutation, counts read each time: the exit ending deleted failed two of the three pins on vitests own timeout (2 failed and 1 passed, both at 5000ms, the wait running on to the backstop), the already-gone seed dropped failed the third alone (1 failed and 2 passed), and the probe discarded so the wait returns on the first look failed all three (3 failed and 0 passed, asked 1 against 3 and two promises resolving instead of rejecting), each restored to 3 passed and the sdk suite to 129 passed over 12 files. the gate question is NOT answered here and #2080 still owns it, but the sdk README now states what decides it and gives the grep that checks it rather than listing the workflows, and tutorial.rs stops naming budgets that no longer exist. no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4178 passed over 133 binaries, 9 ignored) (#1914) 2cac70f9 · dbf3dbe6…diff
  • the second failure mode in the tutorial interrupt test stops being uncharacterized, because a message for it already existed in main CI and what it shows is a handler reporting a CALL rather than a PATH: run 35373927304 on 5e66658 went red on ubuntu-latest in 0.24 seconds with the interrupted - removed line on stdout and that path still on disk, at the agreement assertion, on a head that already carried the #2037 fix - so the change read as closing this did not, and the two sightings the ticket comment carries are the pre-#2037 assertion and are the defect #2037 named. what is established is the disagreement and nothing past it: why remove_dir_all answered success is NOT known and is not written down as if it were. so sweep_interrupted_tree asks the filesystem after a removal reports success and prints the refusal when the path is still there or cannot be read, which is the property #2037 asserted and did not reach, and the interrupt test says what a surviving tree held instead of printing true. THE SATURATION HALF IS A NEGATIVE RESULT STATED WITH ITS COUNT: 150 runs with capture on from the first, under up to four concurrent workspace builds at -j 6 over a scratch copy, against 12 idle, none failed, plus 300 more under a load generator discarded for measuring 7.9 percent busy while it spent its wall clock deleting a 16 GB target directory. the load that did run was bursty rather than sustained and the file says so, a median of 3.6 percent against a peak of 99.8, while the spread moved from 0.38 to 0.44 seconds idle to 0.48 to 126.4 loaded - and none in 450 does not retire one in 534, which is recorded too. two smaller corrections ride along, both read off runs: the fixture behind a tree already gone reports as removed answered NotFound over a directory it had left standing, so it pinned the mapping and never the filesystem, and the sentence saying the swept sandbox holds one heartbeat file missed the empty alice directory that walk mints ahead of its first prompt. workflow.md gains the shape its own falsifier asked to be told about, a test that fails at a closing assertion because the process it drove reported the state that assertion checks. red under mutation, counts read each time: the filesystem confirmation deleted failed the new pin (10 passed and 1 failed, the removal line over a tree still there), the old fixture restored failed the already-gone pin (10 passed and 1 failed, the refusal naming the path), and through the integration test a handler whose removal does nothing failed it naming the remnant as still there holding alice and heartbeat (2 passed and 1 failed), each restored to 11 passed and to 3 passed. 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) (#1916) 2c05fdc7 · 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
  • the tutorial interrupt handler halts the writers the tutorial started before it sweeps the tree: a step loot subprocess is spawned, registered and reaped under a lock the handler takes and never releases, so the handler kills and reaps it and the walk blocks at the lock rather than fail its step and exit beside the handler, and the relay thread runs under loot_net::serve_until, a new stop that closes the listener and lets the requests in flight finish, which the handler asks for and waits on within 2 s. reproduced on Windows before the fix: with nothing injected, 7 of 15 runs interrupted as the clone started ended wrong (exit 1 with no handler line, a refusal, or the removal line over a tree holding config/loot/telemetry, which a loot process writes through create_dir_all), and 15 of 15 ended right after it; the relay thread held by temporary sleeps in its start-up or in a stow across a held handler put the relay store back under the removal line 5 of 5 each, right after; a subprocess in a process group of its own, standing in for kill -INT on unix, held the tree 5 of 5, right after. the halt adds under a millisecond at an idle prompt. serve_on, and so loot serve, keeps plain axum::serve. pinned by an interrupt mid-clone over three concurrent runs, a relay halt that leaves nothing serving, and a halt that ends a subprocess nothing signals. red under mutation, counts read each time: the handler without its claim and halt (6 of 6 runs red, 15 of 18 inner runs wrong), the relay started without a stop (0 passed and 1 failed), the halt skipping the relay (0 and 1), the halt without its kill (0 and 1), the holder name selecting nothing (0 and 1), each restored to green. no migration, no format byte and no published wording moves, so this owes no deploy. the workspace suite is green (4397 passed over 138 binaries, 13 ignored) (#2311) f4a9172d · dbf3dbe6…diff
  • revset_everywhere names each scratch directory by a per-process counter rather than the clock, so two tests asking for the same row no longer share one copy: on Windows SystemTime ticks in 100 ns steps and the tests here reach scratch(archive) together, so a second caller could empty the first caller copy and fill it with another fixture store, which answers no change matching word for word. reproduced by overwriting one copy with another fixture by hand, and by naming scratch by process id alone (5 passed and 5 failed, the historic test failing at loot archive with the #2258 message). pinned by concurrent_scratch_callers_never_share_a_directory, red under the old clock naming in 18 runs of 18 (0 passed and 1 failed, 9 to 14 of 400 directories handed twice), restored green. ci/test-main.sh runs the workspace suite with --no-fail-fast and runs the site live suites after a red workspace suite, recording a failed suite and exiting non-zero naming it, while a failed provisioning step still stops the run; the bare step-or-record form was measured exiting 0 over a failed step, so a suite step runs in a subshell with set -e. the published_surfaces pin reads the --no-fail-fast line (5 passed and 1 failed with the flag removed). no migration, format byte or wire byte moves. the workspace suite is green under bash ci/local.sh against Postgres 18 (4431 passed over 138 binaries, 13 ignored; site live suites 7 files passed) (#2258) e39a6465 · 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.