Changes touching this path

  • the browser builds, seals, signs and publishes a ticket write as one change on the forge head (ADR 0098 §1, §5): the .lootattributes dialect moves from loot-cli policy.rs into loot_codec::attributes, which policy.rs wraps to count the parse, and the tracker file substrate (ids, the file format, layout, the Policy check, the values a write takes and what each write puts in a ticket directory) moves from ticket.rs into a new loot-ticket crate that ticket.rs writes through, so the CLI and the wasm core share one implementation. loot-wasm ticket::build (buildTicketChange) takes the forge /fetch answer holding the head, the generation /ref read it at, .lootattributes and the ticket meta as plaintext and one write of new, comment, resolve, label, wait or edit, refuses what a capture refuses with no override and an embargoed rule, seals each file uncompressed under its first-matching rule, and signs one change on the head under the subject ticket <id>: <verb>, handing back the stow and ingest envelopes, a self-grant per unpublished key for the forge mailbox and the wrapped keys; the fixed ingest and ref fields move to loot_codec::forge_ref, which loot-net writes through. the SDK publishTicket stows, deposits the grants and ingests the change as the only head of the forge, building it again on a 409 or 412, a new ticket keeping its id, up to attempts times. pinned against an in-process forge by four forge_view tests (a clone reads a browser ticket after pull and pull-grants with the CLI fold and a lane reads it through the overlay, a restricted write reads S without the grant, a raced write is rebuilt on the new head, a write the rules do not place is refused) and by an SDK behaviour suite against loot-forge --dev and the release loot, 3 passed; red under eight named mutations, each restored: the subject carrying the write (0 passed and 1 failed), a restricted rule sealed internal (0 and 1), no grant deposited (0 and 1), the policy check skipped (0 and 1), a retry minting a new id (0 and 1), the change not naming the head (0 and 1), meta headers out of order in loot-ticket (37 and 2), and the wrapper not counting the parse (1 and 1). cargo test green, 4713 passed over 145 binaries with 13 ignored, and the SDK gate green with npm test at 148 passed. move and attach are not built for the browser. client only, no deploy (#2431) 24e58969 · dbf3dbe6…
  • review sweep 3 fix-up over #2430 and #2431 (map #2422): the browser ticket builder reads the rules and the ticket files a write answers to from the head it builds on instead of taking them from its caller as text, where a stale or forged .lootattributes handed in could publish what the head rules do not. loot-wasm ticket::reads names the objects a write reads on the head (.lootattributes, and the meta of the ticket it writes to with its body for an edit), the caller fetches them by address, and ticket::build opens each itself under the forge key lane or a key the session keyring holds, inflating a compressed one with a host zstd the caller passes (ADR 0040); a file it reads that no key opens refuses the write. an edit carries what the head held at each file it rewrites, and built again on a moved head that holds another version it answers a collision with both versions and builds nothing, while an append rebuilds freely (ADR 0098 §9, the browser half). the SDK publishTicket takes keyFor in place of context, resolves with the collision rather than publishing, reads again when the head moves between /ref and /fetch, and reports a 401 or 403 at /stow as an AuthError through assertStowAccepted. loot-ticket holds space_in, and its comment, resolution, label and wait files check their own values; the wasm lockout refusal is RepoError::Lockout; forge_fold keeps differs_outside_tickets alone. the spec §0 amendment records what #2430 and #2431 added past it, and CONTEXT.md, ADR 0098 and the SDK README say what changed. red under ten named mutations, each restored: unopenable rules read as none (0 passed and 1 failed), rules not read from the head (0 and 1), a copy handed over taken for the head file (0 and 2), meta not read (0 and 1), no collision check (0 and 1), an append compared like an edit (0 and 1), no inflate (12 and 3), a /ref to /fetch race refused (1 failed and 4 skipped in the SDK suite), a rebuild without its base (1 failed and 4 skipped), and a /stow refusal as transport (1 passed and 2 failed). cargo test green, 4728 passed over 144 binaries with 13 ignored, and the SDK gate green with npm test at 153 passed. client only, no deploy (#2479) 4efb1baa · dbf3dbe6…diff
  • the Tickets view on the private workbench, verdict E of #2411 (ADR 0094, ADR 0098 §1): a view module, its VIEWS line, routes for tickets, tickets/<id> and tickets/q/<query>, and a read route, /api/private/tickets, that answers the files the forge head holds under tickets/ as paths and addresses and each ticket path first touch in the head history with its generation. the browser fetches the objects from the forge by address, opens them with the session keys and folds them in wasm with loot_ticket::fold, the fold loot ticket now folds through too, moved out of loot-cli (ticket_read.rs: readTickets, ticketWants, ticketKinds), so the web reads a ticket as the CLI does and in the same causal order. the page is the conversation page for every ticket and map, a timeline ending in the resolution card, a comment and resolve composer and a right rail; the panel with search, saved views, maps, labels and kinds; and on a map a Conversation and Board switch whose board lays out Waiting, Frontier, In a lane and Resolved under the decisions so far, where a drop onto a card is a wait-on. sealed tickets are withheld rows, and each control names its loot ticket command. a write publishes one change through the SDK publish, now publishTicketWith over an injected core (sdk/src/ticket-publish.ts, assertStowAccepted moved to stow.ts); the pending bar holds writes in flight, and a collision shows both versions and asks. a session whose key is not the namespace owner reads, and lanes, which the web cannot see, are said to be so. connect-src is not widened, since the forge origin it names covers the repo endpoints, pinned by a CSP test, and a built private route loaded in headless Chrome under the enforced policy loaded the view and the wasm core with no violation but the control fetch meant to be refused. public surfaces grow by 229 to 236 B gzip, the route definitions. red under ten named mutations, each restored: the least touch taken as the latest (0 passed and 1 failed), the timeline ordered by name (0 and 1), waiting ignoring closure (0 and 1), the shared fold ignoring a label removal (0 and 2, the CLI label test and the browser read test), a touch outside the head history kept (1 failed and 2 passed), a generation counting a parent never sent (1 and 2), the board waiting column taking the frontier (1 failed and 7 passed), any session writing (1 and 7), an own key held without unsealing (1 failed and 16 passed), and the parent edges swapped in the read route SQL (1 failed and 78 passed over the live Postgres suites). cargo test green, 4739 passed over 145 binaries with 13 ignored, the site gate green at 856 passed, the live Postgres suites at 79 passed, and the SDK suite at 153 passed. owes a site deploy (#2432) 94447d12 · dbf3dbe6…diff
  • the GitHub import, part a of #2433 (map #2422): loot_ticket::import turns a GitHub issue into ticket files, its kind from its wayfinder label, its parent from Child of map #N or (map #N, its waits-on edges from the run after Blocked by less a map edges to its own children, and for a closed issue one resolution whose gist is its title and whose body is the comment nearest the close within an hour. ticket::import_github writes them through the writer loot ticket new writes through, checking every path before writing any, and refuses a position that already holds an import, and the import-github example in loot-cli fetches the issues with gh and runs it, kept out of the verb surface since an import runs once. the files of one import share one position, so an imported id leads with its issue rank by opening and an event name with its rank by GitHub time, and tickets and comments read in GitHub order whether captured or not. this change carries the import itself: all 1355 issues (75 open, 1280 closed; the other numbers up to 2488 are pull requests) as 1355 internal tickets in 5463 files (1355 meta, 1355 body, 675 comments, 1280 resolutions, 488 labels, 310 waits-on edges), with 19 map edges to its own children dropped and 20 closed issues whose resolution says it had no closing comment. read back with the lane-built loot: tickets --state all lists 1356, the 1355 and the test ticket main held, 76 open and 1280 closed; show of map #2422 lists its closed children titles as its decisions; the comments of #1667 and #483 read in GitHub order. loot status in the lane went from 0.44 s to 0.94 s, and a first capture of the same 5463 files in a scratch repo took 0.66 s. spec §1.3, §1.5 and §13 and the CONTEXT.md Ticket entry record migrated-from, github-author, github-closed-as, the ordered leading bytes and the operator decisions. red under named mutations, each restored: ids keeping their drawn lead (3 passed and 1 failed over the import tests, 0 and 1 for the CLI import test), event names keeping theirs (3 and 1, 0 and 1), no closing comment ever found (2 and 2), map edges to own children kept (3 and 1), and a second run not refused (0 and 1). cargo test green, 4749 passed over 145 binaries with 13 ignored, and the site gate green at 863 passed. no deploy owed (#2433) 51f80da3 · dbf3dbe6…diff
  • web move and attach, and the consent a web write needs (map ztrnpqko): the browser ticket builder takes move, which opens each file of the ticket the head holds outside the new space and seals it again for its path there byte for byte, removing the old path and keeping each file name so the history keeps its order, and attach, the declared name over the bytes. consent is an input per path: publish for each path the change writes that the rules publish, demote for each path a move writes out of a group to internal, to public, or to a group the rules cannot show names no one new, and reveal for an attachment path under a secret-shaped name. a write missing any builds nothing and answers each path and why, and a write built again is handed back the event names its first build drew, so it writes the paths consented to. a move out of a group into public asks demote as well as publish, which the CLI move does not, since a device may silence the publish question. the 10 MiB cap is loot_ticket::ATTACHMENT_CAP in the shared writer, so loot ticket attach refuses the same file, and is_secret_name with its set moved from loot-cli policy.rs to loot_codec::attributes, which builds for wasm32. publishTicketWith resolves a write missing consent as a consent outcome before anything reaches the forge, with the consent that answers it and the write to publish again, and the Tickets view shows it as not taken, saying why, until vsropolo asks. ADR 0098 §11, the spec and CONTEXT.md record it. pinned natively against an in-process forge over rules like this repo, with a Restricted path outside tickets/: a move into tickets/security/ and out into tickets/public/ read in order by a clone, the browser read and a lane, each consent refused and then given, the cap, and an attachment the CLI reads byte for byte. red under named mutations, each restored: publish never asked (5 passed and 2 failed), demote never asked (5 and 2), reveal never asked (6 and 1), no cap (0 and 1 in loot-ticket, 0 and 2 in loot-cli), a move drawing fresh names (0 and 1), a move keeping the old paths (0 and 1), an attachment losing a byte (0 and 1), and in the SDK the consent outcome not surfaced (18 and 2), the names not handed back (19 and 1) and the consent not passed (19 and 1). cargo test green, 4757 passed over 144 binaries with 13 ignored, the SDK suite at 176 passed with a lane release build, and the site gate green at 863 passed. owes a site deploy, and the primary binaries a rebuild (wyllqvzy) 73f4a22a · 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.