Changes touching this path

  • loot duplicate: copy a change with a new change-id (#398) 36c1463b · dbf3dbe6…
  • the allowlist parsers get one home in loot-net, which un-forks six copies and restores the OpenSSH form loot-relayd had silently narrowed back to hex a day after #1086 widened it (#1167) a702c5dd · dbf3dbe6…diff
  • a verb run from a subdirectory finds the repo instead of advising an init that would nest a second one, path arguments rebase from the cwd the way a tester types them while view's globs stay root-relative, and the resolved root is named on stderr whenever cwd is not it eca43819 · dbf3dbe6…diff
  • a flags value stops being read as a flag, because `FlagSpec::given` asks in flag position the way `positionals` already does and every verb-local scan in both binaries is deleted behind a census that refuses the shape — which is what had `loot tag -m "-d"` signing a retirement, `loot describe -m "--no-snapshot"` silently skipping the capture, and `loot-first land --allow-publish "--skip-tests"` skipping the gate that is its whole job (#1612) b40e1843 · dbf3dbe6…diff
  • the valued half of the argv door gets a floor: FlagSpec grows value() and message() so a valued flag's payload is stepped over by the spec that declared it rather than found by a bare scan of raw argv, and all 29 readers move onto it along with six more the ticket's list had missed, which is what left loot ferry --dock --git-dir yielding a --git-dir nobody typed while its --json twin was the single case anyone had pinned; and the census meant to stop this class recurring widens from the previous bug's exact spelling to the class itself and gains a positive control, which caught two further hand-rolled scans in help_sub and resolve_tool_path and took the crate from eight offences to zero (#1652) f86ffb25 · dbf3dbe6…diff
  • the draft rule stops being a claim about planners and becomes a property of the ONE SEAM EVERY REFIT CROSSES: refuse_building_on_the_draft is asked unconditionally as the first statement of apply_refit, over a new minted_edges whose match is WILDCARD-FREE, one arm per variant, each declaring the pre-existing parents it would record on. the proof is a MUTATION THAT DOES NOT COMPILE - adding an eighth variant fails with non-exhaustive patterns AT minted_edges, so a seventh Refit cannot forget the rule the way a census or a call-site list would have let it. the two planner calls STAY and are documented as ORDERING ONLY, naming an illegal destination before a clash set is computed, so forgetting one costs a MESSAGE rather than the rule. and duplicate is ruled a DEFECT rather than a named exception, because the artifact it shipped was genuinely broken: the copy is SIGNED so it travels, and it named as parent a version resolve_live_version excludes BY CONSTRUCTION - loot show on that parent exits 1 with no live version matching - with latent harm besides, since any later describe, squash or abandon of the draft makes it permanent rather than repairable by a later loot new. #398 SURVIVES CONTACT and its hard constraint was in a COMMENT its resolution never restates: duplicate must not reproduce a change at its own parent, because a content-addressed version id would collide, which is why the jj default of the source own parents is unreachable here and why #398 reached for the draft at all - the anchor satisfies that constraint just as well and is a version a receiver can resolve, so nothing in #398 required the draft specifically. the planner is no longer TOLD which version the draft is, its view loses that field entirely, which is the narrowing made structural rather than promised. two user-visible changes are stated rather than slipped in: a duplicate with work in progress now lands BESIDE the draft on the finalized anchor rather than on top of it, and --after @ now REFUSES. seven mutations, six red with the counts read and one a compile error, and the two halves are separable - blanking the declaration reddens both pins while neutralising the seam call reddens only one (#1841) 56bc591f · 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
  • 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
  • a verb arm now receives the argv door answer instead of the raw slice: VerbRun takes an Admitted value, the rebased tail bound to the spec of the row it was dispatched from, and its readers are the only way in, so argv[0] or argv.first() in an arm fails to compile (both planted, read as E0608 and E0599). spec_of is test-only and its 104 production lookups read through the admitted spec; six of the seven raw-index arms (bundle, grant-status, embargo-status, attest, resolve, completions) read positionals through the door and relay reads its leading word through a named exception; subcommand families resolve their leaf into a new Admitted, and bisect and buoy are handed one ahead of the table. the two named exceptions, leading_word for relay and bisect and pass_through_tail for the bisect run command, plus the one process argv read, are held to a named set of functions by a new census that went red on a planted leading_word read in cmd_bundle, and the source walker consumer header now counts it. refusals and output are unchanged by every suite and by a read of each migrated arm, with one exception found on the way: resolve with a trailing --tool and no command read --tool as the file and now refuses with the usage line, pinned by a new test. CONTEXT.md gains the Admitted argv term; loot-first keeps its own spec_of and DECLARED_READS is untouched (#1929) d92e95f2 · 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.