Changes touching this path
- the last two readers of the deleted argv shape ask the door instead, and the blocker this ticket named was not the one holding them out: the static lifetime was never in the way, because OPT_IN_HALVES is a const whose flag fields are already static, so the valued union is a const fn fold at an arity derived from the three class lists and a half without a class becomes a build failure rather than a runtime one - what actually kept the perf binaries from naming the door is that loot-net is a dev-dependencies row in their manifest, deliberately since #847, because a real edge would link axum, reqwest and tokio into the gate binary every land builds. so the door moves once more, to loot-core, which every binary-shipping crate already names directly and which is pure std, making this #1628's own criterion applied one crate further rather than a second door - loot-net keeps a re-export shim so no caller changed. the recursive delete is demonstrated rather than argued: --size 64 pinned-checkout scratch bound the scratch slot to 64 and a file planted under a temp tree at 64/counters-repo is gone after a run driven by the real production path, proved non-vacuous by aiming the same call elsewhere and watching the assertion fail; it now binds the checkout the operator typed. the gate's poisoning is worse than this ticket described and its example argv is corrected rather than repeated, since that one is already refused by the strict single-position parse - the argv that genuinely passes needs the forged operand followed by another flag, and before this it wrote a 925 byte measured record to a file named --reps in the working directory while the land-and-stash pairing guard passed, because the stash it checked had been forged out of the message operand. after, it exits 2 naming the pairing and never measures. both call sites were extracted from main first, following #1628's remedy, so a pin can reach what main asks rather than only the door's traversal - and every pin was reverted to prove it red except one that pins fresh rather than the binding, which is documented as such and proven non-vacuous separately. the exemption list is emptied and re-adding a name now costs deleting a working census, since the roll call asserts set equality (#1682)
d7e849b0 · dbf3dbe6… - the door's own docs stop naming the crate it left, and the count this ticket asked to derive is deleted instead - because deriving it the way the ticket suggested would have confirmed the stale number rather than contradicting it. the ticket said loot-cli's census is spelled one way and the others another, so a grep would undercount; loot-first shares loot-cli's spelling, so grepping the others name returns exactly three, which is the wrong number already written on the line. a derived four is right today and the property is right permanently, so the sentence now says every other crate that ships a binary keeps its census in its own crate and the roll call derives the set rather than listing it. the roll call sentence is rewritten as a mechanism rather than a new pointer, since a glob pub use cannot carry a cfg(test) mod: no amount of following crate::flags or loot_net::flags reaches the roll call, and a reader who tries finds nothing with no way to tell whether it moved or never existed. a third stale path the ticket did not name is repointed too, a rustdoc link into the shim, because correcting two of three is the trap this ticket itself cites - and two more staleness sites in the door's own file go with them, a doc counting four binary crates and a fifth, and an expect message still naming the crate the door left. the new pin derives the door's crate from the single is_flag definition and holds two shapes to it, that a re-export names its target in its own header and that every backticked fully-qualified path into the module names the door's crate, with backticked the discriminator between guidance and a call through a re-export both moves deliberately left working. four reverts were each proved red, and a fifth mutation exposed the pin's own vacuity - dropping the shim detector's comment guard left it green because the doc had not spelled the shape it reads, so the shape is spelled and the control now fails. this ticket's premise that both moves left stale docs is also wrong: #1628's header was correct when written and the staleness is entirely #1682's (#1685)
fa895fab · dbf3dbe6…diff - loot clean lands, and the two nevers the ticket asks for are properties of how the candidate set is BUILT rather than filters over one that already exists: the protected set is the union over every change tree in the graph, consulted inside the keep predicate of the tree walk itself, so a recorded path never enters a list at all, and nothing under .loot can be reached because that same walk already skips it at name == DOT ahead of every rule, which is why this file adds no second check free to drift from the first. the walk grew a WalkFilter trait so that skip stayed one line with two implementations rather than a second walk beside it. AC6 is the one that eats work and it has its own fixture: a delta compares path-and-address pairs, so a file the graph records which currently holds an uncaptured edit reads as absent and gets deleted - which is why the set is keyed by PATH and drawn from ANY change rather than the current one. a second fixture pins the other half of that word: a path only the FIRST of two changes records, which a set read off the tip or off surface_target calls unrecorded. both were run red by named mutations before being left green, and deleting the DOT skip put twenty three .loot/objects entries in the candidate list, so the pin is not vacuous. the default is a listing and --force is the only thing that deletes; -n is accepted as the explicit spelling of that default rather than a fourth spelling of the preview idea 1809 is open about, and -n --force is refused because one of the two readings deletes files. -x and -X choose which side of .lootignore the run acts on, and the rules are read by the same parser a capture uses so first-match-wins and the absence of negation hold; -e is repeatable through a new FlagSpec::values that value now delegates to, is parsed by that same parser, holds under -x the way git keeps its own, refuses a leading bang because unlike an inherited ignore file the operator is authoring it right now, and refuses a value spelled like a flag because a valued flag swallowing the bare flag after it has been the defect five times this run. the verb is prose-only and the ceiling moved to 55 with its reason beside it: the shape worth freezing is shared with loot view --prune, which has none, and the column that matters is the per-path spared-reason neither remover computes yet (#1515)
c0b301ed · dbf3dbe6…diff - three seams that promised a door nobody walked through are settled on the honest half of each choice, and two of the five findings measured FALSE against the tree before anything was touched. revset::select has three production call sites now, not one, so the ticket count is stale - but the doc claim was still false, because cat, diff, blame and archive reach resolve_selector directly and heads resolves the at-sign a third way through working_id and finalized_anchor, so the line today is THE GRAMMAR and not THE SELECTOR, and the gap is written down at the module that makes the claim rather than left to the reader. loot_revset::evaluate over a string is DELETED and evaluate_ast takes the name, deliberately not the other way round: pointing select at the string entry would have left evaluate_ast callerless and parse production-callerless, which is the #1553 shape where a narrowing comes back THROUGH A NEW DOOR. Selection::versions goes with zero callers outside its own unit test, while the ordering half of that same finding is refuted rather than obeyed - the BTreeSet in history is a membership filter for retain_versions and not an order discard, and the topological order is load-bearing at format_patch numbering, range_diff pairing and grep row order, so the guarantee is ANCHORED on the Set variant instead of withdrawn from it. Group::arguments needs no pin for a second tailed group because a second tailed group now FAILS THE BUILD: Args::groups counts tailed groups and asserts in const, every leaf Args being a const, so the case the comment assumed impossible is unrepresentable rather than assumed - proved by a compile_fail doctest with a byte-identical positive control that reddens quoting the assert own message, which is what stops a typo from reading as the rule. build_heads stops taking eight positionals, two adjacent closures and three adjacent optional ids, and takes a named-field HeadSources: the transposition that used to compile silently was RED at 6 passed 1 failed as a mutation, and the same transposition written at the call site afterwards is simply meaningless at 7 passed 0 failed. the run then caught its own new door - HeadSources was born pub with zero out-of-crate callers, exactly the class this ticket is about - so it and build_heads are pub(crate) with the reason recorded at the type. the PATHSPEC comment on the ticket is STALE and nothing moved there: #1493 wired the group to five production leaves and already narrowed the present-tense claim in delta.rs (#1563)
4834a7ce · dbf3dbe6…diff - the first review sweep of the night audits the night OWN three lands, and four of the seven findings were MINTED BY THEM - each fixed at the level that makes the claim true rather than hedged. the wildcard-free match doc said a FOURTEENTH variant would not compile, beside an enum that already had FIFTEEN, so the number is gone and the sentence keeps its point: a hand-written count beside code that can grow is the class AGENTS.md names, and this one was wrong the day it was written. the NO_PATHS sentence and the dispatcher minority sentence disagreed because #1569 narrowed one of them and left the other standing, so the surviving sentence states the SHAPE rather than a frequency - zero declared slots plus an open own list - which is what the #1551 PATHSPEC argument actually rests on, and counting the table shows nearly every was false either way you resolve it: twenty-four literal NO_PATHS and twenty-two NO_ARGS against twenty rows whose spec lives elsewhere. the ADR 0085 note fired TWICE on range-diff, which takes two positionals through the one shared door, and the fix is AT THE DOOR with a latch that catches on HAVING SPOKEN rather than on having been called, because latching on entry would let a first side with nothing to say SILENCE a diverging second one - pinned with a one-positional control, since an equals-one assertion passes against an over-eager latch. the fourth finding is the one with a real choice in it: the note measured the bare pair only, while CONTEXT and two doc surfaces read as though the whole HEAD and HEAD~n pair was covered. so the divergence was BUILT before it was believed - two identities, a converge, one merge tip - and there HEAD~1 as a selector refuses naming both parents while the revset walks the first parent through it, with both bare HEADs equal, so the shipped note was SILENT through it. the MEASURE branch was taken over the narrow one: the note asks the bare pair first and then every depth the AST stands on, with both-walks-exhausted counted as AGREEMENT rather than as a note, and the arm that cannot fire today is ASKED rather than asserted, because that is a fact about two functions and not a thing to write down. prose is narrowed at every surface that read wider than the measurement, the log USAGE line included. the three copies of one census derivation become one function, the ordering contract the shared constant carries for exactly ONE of its three readers is now stated, and the const-only condition under the groups assert is named as what would make it wrong later. five mutations with counts read - and ONE CAME BACK VACUOUS FIRST at zero passed against 1175 filtered out, because the census lives in the bin target and the lib filter reached nothing, caught by reading the COUNT rather than the word (#1882)
5fd6a12a · dbf3dbe6…diff - the shorthand whose NAME states the path axis while its SHAPE states the arity axis is DELETED, so the terse spelling is now the one that REFUSES - which was this ticket whole thesis, that the wrong declaration was cheaper to write than the right one and that is why the silent-drop class kept recurring. every site that meant it now types the open constructor out, and the only shorthand left is the one that takes nothing. option A beat option B on BOTH axes, measured rather than preferred: B would have changed the constructor signature, so EVERY open call site owed a reason string - including the path-taking and the genuinely variadic ones - and the two dozen dispatch verbs would each have written the SAME sentence, which is boilerplate that teaches nothing and is itself a hand-maintained population. so A has the smaller blast radius AND the stronger property. the blast radius is ZERO BEHAVIOURAL, because the retired constant was literally that expression: no verb declared arity, no slot kind and no refusal moved - thirty-five declaration sites, eleven imports and about twenty-five prose sites, with the workspace check clean and no new warnings. the exemption list was ALREADY down to its two legitimate names before this began, since #1569 narrowed the other twenty-one hours earlier, so nothing was added to it or taken from it, and the #545 refusal that earns those two their place is untouched by construction - pinned rather than incidental, because the mutation that hands one of them the no-arguments declaration reddens all three censuses. the rename then exposed two more counts standing beside sets that MOVE, and both are fixed rather than carried: a fixture doc claiming all FOUR verbs it exists to serve are exactly this shape, where there are FIVE production attachers and NONE of them is that shape, and a line naming the four verbs that used the retired constant. both now state the rule and count nothing. the new guard refuses BINDING the zero-slot open claim to a name, which is the single edit that would undo this, while deliberately NOT refusing a leaf that spells the claim out at its own spec - the two told apart by what PRECEDES the constructor, with both run through the predicate before its answer is read. its limits are in its own header. and the control that mattered is the second: with the comment-strip removed AND the predicate control disabled, the tree scan names the flags file itself, over the retired declaration QUOTED INSIDE THE SURVIVING CONSTANT OWN DOC - so the strip is load-bearing rather than decorative. the first and third mutations are each other discrimination, one reddening only the tree arm and the other only the binding-versus-spelling arm, and the fourth proves the floor fires at zero files rather than agreeing silently (#1675)
123fdbd4 · dbf3dbe6…diff - the condition that could not be false is gone, and so is the pair that made it possible: merged stops being a FIELD set by hand at three construction sites and becomes a DERIVED method over the one bit that decides it, so the two cannot disagree - unrepresentable rather than guarded. eighteen reads follow it, and eight of those were conjunctions that are now TAUTOLOGIES, reduced to one term rather than left standing to read as two conditions. the test was rebuilt by moving a DIFFERENT AXIS, because a second catch-up can never reach the block at all: the fixture now puts a real second commit on the checkout main, so the DOCK is still behind and the catch-up genuinely runs, writes the tree and reaches the block, while the CHECKOUT is level and the block declines - and deleting the predicate reddens two tests. the DISCRIMINATION is the part worth reading: under that same mutation the OLD test stays GREEN, which is precisely the defect this ticket describes, demonstrated rather than asserted. the printed recipe stops handing the operator a command that ERRORS. the tree delta now returns what was WRITTEN and what was REMOVED apart, and a removal gets a tree read for its proof, because there is no file to hash, and a checkout for its repair - placed BEFORE the merge, since restoring the file is what lets the merge run at all. the plumbing needed a pin of its own, and that is proved rather than assumed: folding removals back into the written set reddens the workspace pin while the rendering pin stays GREEN. the off-main arm gains its PROOF and withholds only its REMEDY, and says that it withholds it and why, because the byte comparison does not turn on where HEAD is while the repair does - with that limit stated in the same list the module other limits live in, rather than left for a reader to discover. the section this run added about careful sentences gets its own grammar fixed, a stray fragment from an earlier draft removed and a clause given its missing object - and NO count added, with a number that was being carried forward replaced by the property, consecutive sweeps each turning one up. the only-shorthand claim is narrowed at all three sites to the width of the check that backs it, which is a claim about ONE declaration and nothing wider. and the tenth copy of the short-hash helper becomes one, with the unguarded universal above it replaced by what it actually is and an explicit note of what it does not cover (#1911)
53ede622 · dbf3dbe6…diff - every top-level verb whose usage is bounded now declares its arity, so loot burn a.txt b.txt refuses b.txt by name instead of burning a.txt and dropping it: twenty-seven verbs were narrowed, each read handler-first, and none reads more than its widest usage line shows - though a flag that narrows a verb shape is not covered, since the arity is one number per verb, so grant --relay and resolve --tool still drop a surplus word and that is filed as #1934. the census stops naming verbs - who owes an arity is DERIVED from USAGE (no ... on a positional token) with the subcommand families and the OPEN_BUT_TAKES_NONE verbs exempt by reference, and the hand-kept COUNTED list and its per-verb paragraphs are gone, their argument folded into the rule. the one USAGE reader gained a separator arm, since a [-- <path>...] tail read as a bracketed flag would have made grep look bounded, and the ... is read off positionals only so the repeatable ignore-rev flag leaves blame bounded. a new pin derives both sides - expected set and invocation width from USAGE, observed from live refusals - and also asserts the wrong-refusal direction: the refused word must be the junk one and a full documented invocation must pass. five mutations went red with counts read, and no in-repo caller passes an extra token (#1928)
3b9b0f9a · dbf3dbe6…diff - the Admitted and VerbRun docs and CONTEXT.md stop saying every argv reader goes through the spec: the readers that parse positionals and flags do, the consents and relay keys now say on their own docs that they scan argv by flag name, and the named exceptions lose their count and point at the census, as bisect dispatch now does. the stale arity-census counts in main.rs and loot-core flags.rs are gone, and the owed-arity rule is one function that the top-tier census and the counting pin both call, and each still went red when burn was re-opened. the flag census and the Admitted census now share one src walk keyed by relative path, and the Admitted census went red on planted leading_word reads in cmd_bundle and verbs/mod.rs, naming the second by its path. the surface.rs privacy argument now matches Repo::surface reaching the walk unpromoted, CONTEXT.md and the resolve comment stop calling its refusal the usage line, the Verb and pick.rs doc comments are separated so rustdoc keeps them apart, and two rewrap leftovers are fixed (#1939)
7b04e214 · dbf3dbe6…diff - review sweep 6 fix-up: ADR 0088 section 4 gains the divergences the sweep found, each checked against the code - the evolog E row printing a raw whole message (#1973), the status and buoy R rows and the tag name column holding free text ahead of the last column, tag and heads naming people by display name with no key in heads json, a sealed diff row printing a bare tier label, telemetry status and off printing a spool dash where V3 says null, and telemetry on beside show as report json with no contract - and says it records what was found rather than proving nothing else diverges. V7 now means no version line or preamble, and the visibility token and Delta renderer member lists point at the code that defines them. the template-flag census gains a twin in loot-first over its FLAGS table, both reading one spelling list now in loot_core flags; the twin went red with --template and with --pretty planted in loot-first tag, and the loot census with -T planted in lane gc (0 passed, 1 failed each). ADR 0023 credits the open flag set to ADR 0047, the OPEN_BUT_TAKES_NONE census is called an ordered comparison, its assertion points at the list instead of naming describe and new, a ceiling raise has one place for its reason, a stale family count and a stale entry position are dropped, rewrap leftovers in ADR 0088 and ADR 0035 are reflowed, CONTEXT.md follows, and owned_lane takes a Removal with named verb and refusing fields instead of two swappable strings. the workspace suite is green (#1974)
ecd53283 · dbf3dbe6…diff - a flag that puts a verb in a shorter shape declares the arity that shape takes, and the door refuses past it: #1928 gave every bounded verb one number, the widest shape its usage shows, so a flag selecting a narrower shape left the surplus word inside that number, admitted by the door and read around by the arm, which is the #1419 class one level down, since loot grant --relay origin a.txt bob junk sealed the grant for bob and never looked at junk. the declaration is Args::narrowed, a flag beside the arity its shape takes, and FlagSpec::arity_for reads a given one ahead of max_positionals rather than through it, which is what lets a shape carry an arity on a leaf that declares none: loot diff attaches the pathspec and counts nothing, while loot diff --conflict <path> reads no selector and no pathspec at all and its surplus word had no number to be past. the refusal is the door own sentence with the shape that was typed named in it, loot grant --relay takes 2 positional arguments, because loot grant really does take three and a refusal saying so would send the operator to check a count that is right; the narrowest declared narrowing wins when several are typed, since refusing against the wider would admit a token neither shape reads, and each is read through given rather than off raw argv, so a flag value spelled like another narrowing does not select it. the ticket offered a check inside the two arms it had found and made the declaration conditional on a third verb turning up in the census, so the census was written first and ran the decision: verbs did turn up beyond the two, one with two narrowed shapes of its own, one already carrying the check by hand, and one whose arity is None and for which a per-arm check would have had to invent a number, so the per-arm answer was a hand-written copy of the door sentence per shape and the declaration won. which shapes those are is the census answer and is in no list: forward, a documented shape typing a flag outside brackets and showing fewer positionals than the widest shape its own spec shows must declare a narrowing on one of those flags at its own count, and the door is then driven at an argv built from that shape and at one word past it; reverse, every declaration must name a flag the spec declares and carry a count some documented shape of that spec shows. a usage line is read against the spec whose arity the door actually enforces for it, the longest-named table row or family leaf its shape opens with, so loot id unlock --permanent is a statement about the arity of id unlock, which is zero and already refused, rather than about id. what the census cannot see is said where it lives: a mode flag documented as a bracketed option on the wide line rather than as a line of its own, which is loot apply --abort junk and loot archive --list junk, both measured still dropping the word, and closing those means splitting usage lines that README and the published CLI page are pinned to, so it is a ticket and not a clause. loot tag --retire gives up the surplus check it had written by hand and declares the narrowing at each spelling instead, and its pin loops the declared narrowings rather than the aliases typed out. the three readings of a usage line shape the censuses want, the positionals, the flags a shape requires and an argv in that shape, are one walk with three projections, because a copy of the bracket rule per reader is a copy that can come to disagree about which tokens a shape claims. red under mutation, counts read each time: the grant narrowing dropped (0 passed and 1 failed in the census, 0 passed and 1 failed at the process), the diff --conflict narrowing dropped (0 passed and 1 failed, 0 passed and 1 failed), both grants narrowings dropped (0 passed and 1 failed, 0 passed and 1 failed), resolve --tool declared to take a count no usage line shows (0 passed and 1 failed), a bracketed flag read as required by its shape (0 passed and 1 failed), no shape reading as requiring a flag at all (0 passed and 1 failed), the -d alias losing its narrowing (1 passed and 1 failed), arity_for ignoring the narrowings (1 passed and 2 failed in loot-core, 0 passed and 1 failed in the census), the refusal no longer naming the shape (1 passed and 2 failed, 0 passed and 1 failed), the narrowing read through max_positionals rather than ahead of it (2 passed and 1 failed, 0 passed and 1 failed), the widest narrowing winning over the narrowest (2 passed and 1 failed), and the check relaxed so a narrowing need not narrow (2 passed and 1 failed in the loot-core doctests). no migration, no wire or format byte moves and no host behaviour moves, since every byte of this is argv on the client side, so this owes no deploy. the workspace suite is green (4027 passed over 125 binaries, 7 ignored) (#1934)
c62387ee · 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.