Changes touching this path

  • a land builds the site and weighs the eager bytes of every published surface, so a redesign cannot spend the byte lead in silence, and the four places that called site/ ungated now say what is true (#1241) 674361ad · dbf3dbe6…
  • the site stops shipping 298 grammars to highlight two languages, and a three-line meta helper stops dragging fifteen more into the entry chunk of every page including the ones with no code at all (#1244) b06ca1b5 · dbf3dbe6…diff
  • the custody sweep residuals are answered on the record: the sealed-path demo is re-run so the evidence page shows the binary it names, the disk scan learns base64 and UTF-16, the pull entry points drop their bool, and the mailbox keeps failing loud by decision (#1232) 333e9517 · dbf3dbe6…diff
  • the site gets a typeface: Geist and Geist Mono self-hosted from a subset derived from the site own characters rather than a stock list that silently drops the arrow the landing page renders, and twenty-one ad-hoc sizes collapse into a six-step scale 43c52bad · dbf3dbe6…diff
  • the hero gets its field: two plumes converge and merge over 210 frames, then the loop stops, the canvas hides and the GPU is released onto a 1.7 KB twin that was already underneath it, and a test refuses the day the twin and the shader that made it stop matching b3f716f7 · dbf3dbe6…diff
  • the evidence page gets the one proof a reader can run: two identities are minted in the browser, a content key is sealed to one of them, and the other is refused by the engine in its own words rather than in ours, with the 161 KB core fetched only when someone presses the button 846010f8 · dbf3dbe6…diff
  • the landing page becomes the Deck: the receipt is promoted into the hero as one frame where the ciphertext and the plaintext of the live object share the same lines and a dragged seam cuts between them, a live stats strip follows, the three ideas and the loop and the recipe become a bento, and a closing plate ends the page - superseding the receipt-below-the-fold placement while keeping the pane semantics, re-pointing the measure-cap pin at the seam, and raising every surface ceiling on the record for the shared stylesheet and routes chunk it costs c25f21d1 · dbf3dbe6…diff
  • the eight per-surface ceilings get their own reasons back instead of one shared paragraph, so evidence again records the grep that proves the engine is never eager, re-run today and widened to name the 182-byte loader that fetches it f0bd3c8d · dbf3dbe6…diff
  • the site chrome becomes an instrument: a slim mono Console bar carries the six links, the release tag it now imports rather than retypes and the account key chip on every page, the footer band collapses into a one-line end-mark that still carries the disclosure route, docs trades its in-page contents list for a prop-driven side navigation any later surface can mount, and the account page is re-presented as a dashboard of key rows and a four-step ceremony with every Clerk call, every byte of crypto and every load-bearing sentence untouched - the #1323 prototype verdict, raising every surface ceiling on the record for the shared stylesheet it costs 786e5a21 · dbf3dbe6…diff
  • the eight per-surface ceilings get their own reasons back instead of one shared paragraph, so evidence again records the grep that proves the engine is never eager, re-run today and widened to name the 182-byte loader that fetches it (conflict resolution: site/budget.json) fba4f79c · dbf3dbe6…diff
  • six entries this run deleted for fixes only unreleased main carries come back marked as such, because the page says it describes v0.4.18 and that is the binary a stranger can install, and a fifth pin holds every one of them until the release that fixes it moves REVIEWED_AGAINST 7adab105 · dbf3dbe6…diff
  • the two nav entries that leave your machine carry an EXP marker, keyed on their own href so the bar still says nothing about who is reading, and a strict 20rem suppression keeps the chip from adding fourteen pixels of horizontal scroll to a Fold 112c1212 · dbf3dbe6…diff
  • the Console bar stops calling the forge a relay and stops asserting an ok no static document can know, keeping only the release tag because that is the one thing up there a test already fetches, and the eight budget reasons stop claiming no new dependency now that lucide costs 682 bytes on every surface fc920df7 · dbf3dbe6…diff
  • the ratchet records a build that exists again, ADR 0006 finally carries the verb that leans on its third case, and three documents stop asserting things the code beside them contradicts including a pin that held the number and not the strictness it was written for 62bf03ff · dbf3dbe6…diff
  • the docs become fifty-six routed entries derived from one registry that the nav, the reading order, the search and the prerenderer all read, so those four can no longer drift apart the way ten hand-listed surfaces already had to be watched; the thirty-eight pages nobody has written yet are real bookmarkable URLs that say what they will cover and carry noindex until they earn a place in an index, rather than dead rows in a sidebar; and the byte gate learns to walk nested surfaces, which is the only reason the fifty-two new pages weigh anything at all instead of shipping past a gate that read one directory level (#1378) 424be083 · dbf3dbe6…diff
  • the foreign grant stops applying itself, and that was a LIVE defect rather than a guard this ticket adds: pullMailbox indexed every verified blob alike and discarded the grantor pubkey, so a grant somebody else deposited in the mailbox was applied SILENTLY the first time any file at its address was opened - the exact opposite of #488's decision that nothing auto-applies. The mailbox is sorted BY GRANTOR now: a self-grant under ADR 0057 still goes straight into the key index, while anything signed by another key becomes an offer in a second map the decrypt path cannot reach, so the property is structural rather than a check somebody has to remember. Restoring the old line turns nine of sixteen cases red, headed by a stranger's key entering the key index, and the positive controls are what make locked a decision rather than a broken fixture: an accepted grant reads open with bytes equal to the content key, and a self-grant in the SAME pull still opens itself. The copy is asserted as RENDERED rather than as source, and the decline half is honest for a reason it states out loud - the only wire act that could take a grant out of your mailbox is an ack, and an ack would delete the blob for every other device you own, so this page does not have one - which is why declining revokes nothing and says so, against an absent-phrase list that refuses has been revoked and no longer has access. Expiry's first line is WELDED to the refusal constant rather than restating it, an expired offer stays visible after a refused accept, and a control files the same grant one second before it expires. The unprovisioned member tier is ASKED rather than remembered: the me route answers whether the read class is live and the browser tests that for exactly true, so a missing field lands on the arm that promises nothing, and the dark arm - the live one today - says the repo answers not yours as a 404 whether or not you have been added. Three things were found on the way and each is measured rather than argued. Importing the fingerprint helper dragged a curve library into the shared entry at eight kilobytes on every PUBLIC route, fixed by moving the function to the dependency-free module beside it. A lazy route was measured and REJECTED at 581 bytes against 270 eager, because the split chunk's manifest outweighs the code it saves, and that is recorded in the route so nobody fixes it back. And the byte record had to be raised, so the raise is SPLIT rather than apportioned: the same tree with this ticket removed already reads a thousand and thirty bytes over the recorded numbers on every surface, which is pre-existing shared-entry drift, where this page itself costs 270. The budget tool had a real bug that recording surfaced - its lowering note is anchored to the end of the line so a later lowering can replace its predecessor, but a raise appended after it buried the note out of that anchor's reach and the next lowering stamped a second one - fixed with a fixture that is red without it (#1640) 152d0635 · dbf3dbe6…diff
  • the last sweep's fix-up, and the item with teeth was a doc that told its reader to make the edit its own route file forbids: the component said it was exported so the route could load it LAZILY, where the route records that lazy was measured and REJECTED at 581 bytes against 270 and says in as many words not to fix it back without re-measuring. It now carries the route's true reason - so a test can render either half without a router - and marks explicitly that this is not a lazy split, pointing at the route for the readings rather than copying its numbers. The receipt showed eight hex characters wearing the class the module reserves for a FULL fingerprint, on the one surface whose whole purpose is an out-of-band fingerprint comparison, with adjacent copy inviting a comparison eight characters cannot support; it now shows the full fingerprint, derived in the accept from the bytes the apply itself re-verified rather than re-shortened in the surface, so the receipt cannot be rendered from the offer the apply was meant to re-check. Dropping the class and keeping eight was rejected because it would make the receipt say LESS about the one thing being checked. Rendered bytes did not really move - three gate builds read the same surface at 199873, 199872 and 199873 against 199872 recorded, and the whole sixty-route spread is minus seven to plus four - so nothing was re-recorded and the two bytes the ticket asked about turn out to be the instrument rather than an unaccounted byte. CONTEXT.md's list of account_of's consumers stops being a third copy and POINTS at the header that owns it, naming the one consumer #1746's own restatement dropped - which is the lesson of this fix-up, since that restatement was itself the remedy for a count-drift finding and drifted in the same way. The budget note is corrected as PROSE with no ceiling and no measurement touched: uniformly on every one of these surfaces was authored from a single weighing, and one surface moved the other way and had its ceiling LOWERED after its page lost six entries. The decline receipt moves into the register module that owns the vocabulary, with an absent-phrase list and a RENDERING control, because an absent-phrase list over copy that never renders proves nothing. And a count of refusals is removed rather than corrected: the numbers are labels for rules and do not line up with the code, since the first propagates from the walk and the fifth leaves from more than one site with different sentences (#1751) 571d3533 · dbf3dbe6…diff
  • the site gets the privacy notice it has been collecting without, and every sentence is written against what is ACTUALLY retained rather than against the pipeline design: 1624 says do not ship the collector before the notice is live and the ordering is the point, and the collector shipped first - this closes that, late, and says so rather than pretending the sequence held. writing it to the design would have published a claim that we collect MORE than we do. the beacon, the download hop and the telemetry channel are unbuilt, and visitor_key, country, device, browser and os have no producer at all, so a notice describing a daily visitor salt or country-level geo would be false in the direction nobody checks. what is actually kept is the access log for 30 days - time, method, address, status, bytes, referring URL, full User-Agent, cache status, response time, and NO client address, written as a literal dash - plus rows derived from it with the referrer reduced to a host and the User-Agent reduced to a coarse category. ⚠ one sentence of my own first draft was false and the scrubber refuted it: I wrote that the log records a route shape rather than the address you asked for, which is true only for repository and private-repository URLs. ordinary page addresses are recorded in full, so the claim understated collection on nearly every request. corrected to name the exception as an exception, checked against scrubPath rather than against memory. the word anonymous is deliberately not used of the log, per 1617 - the rows carry no identifier, but a full User-Agent kept for thirty days could in principle distinguish an unusual browser, and claiming anonymity is the wording that turns a data-protection question into a consumer-protection one on a product sold on privacy. the page explains why it avoids the word instead of using it. the objection is real machinery over a currently empty set, and the page says exactly that. one cookie, set only on request, holding a constant rather than an identifier - the opposite of a cookie that counts you. it suppresses collection that happens in the APP, it cannot reach the nginx access log which is written before the app sees the request, and today the log is the only source. so it presently suppresses nothing, which the notice states plainly rather than implying a working control. every future app-side collector must consult hasOptedOut, which is why it lives in lib rather than inside one caller. the retention number gets the 1779 treatment, because it is the one number here that is a published statement about personal data: 30 lives in site/src/lib/retention.ts, the bound is enforced by RETAIN_DAYS in the scripts repo, and setup-site now refuses to deploy when they disagree - a copy with no check is how the notice quietly outlives the thing it describes, and the dangerous direction is raising retention on the box while the page still says thirty. terms ships beside it with two deliberate absences: no governing law or jurisdiction, and no liability cap - inventing either would be a legal claim written by nobody qualified to make it, and a wrong one is worse than none. what is there instead is factual and checkable, including that backups are OPERATOR disaster recovery and not a per-account restore service, which is ADR 0046 and the opposite of what a reader would assume. contact is security@millerbyte.com, the address that exists and is monitored, rather than a privacy@ alias that would have to be created at the mail host first - publishing an address that does not resolve would be worse than reusing one that does. /trust gets a pointer rather than a second copy, since two copies drift and then one of them is false. the footer carries both links on every surface, which costs about 650 bytes per surface and is recorded in budget.json with that reason, because a notice reachable only by typing its URL is not published in any sense that matters (#1624) 12951042 · dbf3dbe6…diff
  • the privacy notice stops containing four false statements, all of them found by review BEFORE the page was ever published, and the worst of them was the flattering kind: the page said No IP addresses, anywhere on a site sold on privacy, and nginx error log carries client addresses on every failed request for the same thirty days. scripts/lib/nginx-log.js says so in terms - error.log carries its own client ip exposure and is NOT addressed - and the strip step skips it deliberately because an error line leads with a date and the access-log expression would blank the wrong field. so the notice now discloses it in its own paragraph rather than burying it, says it is never read for analytics and never reaches the database, and says we would like to remove it and have not. the second was the exact failure the retention constant was built to prevent, committed in the same change: the page promised the summary rows are kept 30 days and that both bounds are enforced by time, and NOTHING deletes from event. migration 0001 says it outright - until 1759 lands rows land here and nothing is dropped - and that same comment forbids the fix I first reached for, since expiry there is a partition DROP gated on rolled_up_through and NEVER time-based, so a silently failed rollup must accumulate partitions instead of deleting a day nobody aggregated. adding a time-based prune would have contradicted a recorded decision to make a sentence true. the sentence changes instead: the logs are bounded and the rows are not, said plainly, with what they contain so a reader can judge it. third, no cookie set at all unless you ask for one below was false - Clerk is mounted on /account and sets session cookies - and Clerk is also a third party the notice never named. there is now a section on signing in, and a recipients section naming Clerk, the hosting provider and R2. fourth, the log never accumulates a list of the repositories or the paths of files inside them was over-broad: only forge verbs and /private are scrubbed, so browsing a PUBLIC repository logs owner, repo and file path whole, deliberately, because those addresses are already public and are how we tell whether anyone reads what is published. the page now says that instead of denying it. three Article 13 items were simply missing and are added: the right to complain to a supervisory authority naming the ICO, the recipients above, and a rights section. two remain outstanding because they need facts I do not have rather than words - the controller identity and the hosting provider by name - and the page says the true general thing until those land. the standards half found something sharper than a style point: the opt-out component re-implemented the cookie parser with a startsWith, which read loot_no_analytics=12 as an objection where the module correctly refuses it, and hardcoded the value the module names - which meant hasOptedOut had ZERO production callers and ten tests covered a function nothing ran while the page used the untested copy. it calls hasOptedOut now. /trust had retyped the retention number as a literal, escaping both the test and the deploy cross-check, in the same change that built that check; it uses the constant, and the test now scans both pages rather than one (#1624) 810dc185 · dbf3dbe6…diff
  • the docs CLI page stops being a hand-curated list and becomes a SET RELATION against the verb set the CLI declares: the described table stays a curated SUBSET and is stated as one, a name-only index carries the rest, and the check asserts the two are DISJOINT and their UNION EQUALS the declared 81 - so a landing verb with no entry is red, and an invented command is red the OTHER WAY. the oracle is the USAGE string read exactly as the CLI own guards read it, and it qualifies as the set the CLI DECLARES rather than a second list beside it because #66 already pins USAGE set-equal to the dispatch table in BOTH directions - so USAGE simply IS that table rendered as text, and text is what a vitest check can read without putting a Rust build in the site gate path. the page was stale in BOTH directions and the second one is worse: eight verbs were missing, including heads and cat which this ticket named and diff, restore, split, move, notes and range-diff which it could not have known about - but the page was also PUBLISHING THREE COMMANDS THAT DO NOT EXIST, loot dock, loot dock merge and loot docks, retired by #253 and by ADR 0063 and still on the LIVE page telling readers to run them. a full 81-paragraph table was rejected rather than forgotten: it is worse documentation and every docs surface pays the bytes. the check is proved live in BOTH directions with counts read - deleting a name reddens the missing-verb and union assertions, restoring the real retired rows reddens the does-not-ship assertion, a fictional flag reddens the flag check, and mutating the extractor reddens the CONTROL FIRST, which is what stops a broken extractor from reading as agreement. the byte budget REFUSED and the raise is recorded with a measurement rather than an apportionment: fifty-one docs surfaces moved by within six bytes of each other, which says ONE SHARED CHUNK and not fifty growths, because the docs index statically imports every content module so the splat route fetches all docs prose whatever page you asked for - confirmed by what did NOT move, since the non-docs surfaces came in at noise. the recovery path is named and explicitly NOT MEASURED, so the reason records a diagnosis as a diagnosis (#1561) 3e499faf · dbf3dbe6…diff
  • the beacon counts PEOPLE where the log can only count requests, and the notice that describes it was rewritten in the same change because deploying one without the other publishes a falsehood loot#1757, over loot#1620 and loot#1617. POST /api/beacon takes one short message per view and derives SHA-256(daily_salt || ip || ua || site) truncated to 16 bytes, in process, discarding both inputs. It is canonical for uniques and sessions and for nothing else: the log stays canonical for volume, because it sees the ~53 prerendered pages, the cache hits and curl, none of which run any JavaScript. Two sources counting volume would be two numbers to reconcile. The key is length-prefixed per field rather than concatenated, and that is a real defect closed rather than a flourish. One of the fields is the User-Agent, which the CALLER chooses: with plain concatenation ip=1.2.3.4 ua=5 and ip=1.2.3.45 ua= hash identically, so a visitor could be merged onto a neighbour. The mutation that drops the framing reddens exactly that pin and nothing else. Two decisions are recorded rather than defaulted. NO SALT, NO ROW: a beacon row without a key adds to a count of beacon rows while contributing nothing to the only two things this source is canonical for, so it would trade what we came for against a number competing with the log. And the module is EAGER, which is the answer to the ticket first hazard - ADR 0071 weighs the document plus eager assets, so a deferred chunk is paid by every visitor and counted by nobody. Measured at ~450 B on each of 62 surfaces and RECORDED, and loot#1640 is the precedent that makes this more than taste: it measured a lazy route at 581 bytes against 270 eager. The edge half is new and had to be, because this is the site first unauthenticated row-writing endpoint and the site vhost had no rate limiting at all. limit_req at the /api/ PREFIX, not at /api/beacon, so ADR 0074 telemetry arrives protected rather than silently exposed. Idempotence is remove-then- reinsert between markers, and loot#1647 install-detect arm is closed in the same patch since it needed the same only-if-absent vhost step. Its ordering is load-bearing: the blanket header insert runs while only hand-written blocks exist, which makes a duplicate unrepresentable instead of guarded against. Found by RUNNING it, which is the whole argument for the fixture: the marker ended in (generated), which awk read as a GROUP, so the strip silently never fired - the second run appended a second /api/ block while grep -v tore the limit_req line out of the first, leaving a vhost that would have failed nginx -t on the box. Pinned now, with a control proving the predicate can say no. The notice had to move with the code. Five published statements would have gone false, the worst being that these records carry no key and nothing links two requests to the same person. Rewritten to lead with the key, say the secret is DESTROYED rather than merely rotated, and disclose that a visitor spanning midnight is counted twice. FOUR more contradictions were then found only by RENDERING the page, which is the third time that has been the only thing that worked. Objecting still said the log is the only thing we collect from, so this control has nothing to suppress - three paragraphs after the new text says the browser sends nothing when you object. Erasure and Your rights both still claimed nothing is keyed to you. And JSX drops a newline beside a tag, so the page shipped visitorkey and notstored as single words. The font gate then caught a star glyph absent from the shipped subset, which would have rendered as tofu. A test that asserted we do NOT collect a visitor key survived all of this green, because its regex matched one verb phrasing the new prose never uses. It is inverted now: the page MUST name the key, MUST say destroyed, MUST disclose the midnight double-count. Leaving it would have let a later edit delete the disclosure and stay green. 532 site tests, 322 scripts tests, budget green with the notice raise on the record. 3c22dcae · dbf3dbe6…diff
  • the retention number becomes an OUTCOME: a daily rollup writes the marginal totals that survive forever and only then drops raw partitions that are both rolled up and past the window loot#1759, decided by loot#1622 and amended by loot#1625. Until this, thirty days was a sentence: nothing dropped a row and the raw table grew without bound on the Postgres volume the relay, the forge and the site share. The drop is gated on the watermark, never on time alone, and that is the ticket whole thesis. event_drop_expired() in migration 0003 takes NO argument: it reads rolled_up_through from the table, uses its own UTC clock, and applies a retention CONSTANT - so the rollup role cannot widen the drop by lying to it, and with no watermark it drops nothing. A partition is due only when its day is at-or-below the watermark AND its whole day is outside the window, so a stalled rollup ACCUMULATES partitions, which is the observable failure mode we want, rather than deleting a day nobody aggregated. The ticket acceptance test is pinned as written: freeze the watermark and nothing is dropped however old the partitions are. The mutation that makes the rule time-based reddens exactly that pin and its BOTH-conditions sibling and leaves every time-only test green, which is the discrimination the ticket asked for. A day that fails to roll up STOPS the run with the watermark at the last success; skipping it would advance past a day with no aggregates, the silent loss the watermark exists to prevent. Every surviving table is MARGINAL and a test PARSES the CREATE TABLE statements to prove it: at most one dimension beyond (day, class), never two visitor-descriptive columns together, never one with path, and no table carries visitor_key, account_ref or telemetry_id - which is what makes an erasure complete once the raw rows go. class rides every aggregate and agent gets its own per-family table (loot#1625); rule_versions reaches every row so rule boundaries outlive the raw window. No country table, because nothing produces country. A THIRD role, metrics_rollup: SELECT on event, which the writer may never have; write on the rollup tables and the watermark, which the reader may never have; NO grant on daily_salt; and DDL only through two SECURITY DEFINER doors. The partition door moves a day rows out of event_default in one transaction with an explicit UTC bound - p_day::timestamptz would have taken the session time zone and filed one row under two days depending on who created the partition. The TypeScript twin of the drop rule PREDICTS what the database will drop and the summary reports a disagreement loudly with a non-zero exit, because two implementations of a retention rule parting silently is exactly how a retention promise stops being true while every timer reads healthy. The bundle was RUN, not just built: with no credential it starts, reaches main and fails naming the cause, so the cjs/pg hazard the shipper found is absent here. The notice moved with it, and a test that asserted the page must NOT claim a database bound is now inverted: it must claim it, from the shared constant, and must say the deletion is gated on the totals - a page saying only deleted after 30 days would describe the time-based expiry loot#1622 rejected. The account-reference sentences from loot#1758 shortened from as long as the account to at most 30 days, which is stricter and simpler. Rendered and read. One header claiming nothing installs a shipper timer yet, a week after one was installed, is corrected while the rollup was given the same shape. 587 site tests, budget green with the notice raise on the record. 50fe5557 · dbf3dbe6…diff
  • a docs page fetches its own prose and no other page prose, where content/docs/index.tsx imported every content module statically and the one splat route chunk carried all of it: 9,211 B gzip preloaded on every published docs surface, planned pages included, and a paragraph added to one page moved all of them, so the byte budget reported about fifty regressions for a one-page edit and taught its reader to record the raise rather than investigate it. each module now sits behind its own dynamic import that import.meta.glob finds by directory, keyed by the slug first segment, and each exports CONTENT so the index derives the set instead of listing it. measured on one tree before and after: the route shell falls from 9,211 B to 1,244 B gzip, docs/concepts/cas from 210,980 B to 202,288 B and docs/cli from 214,827 B to 206,137 B, the code-block chunk leaving the eager set with the prose; 52 ceilings are re-recorded down, and the whole-file rewrite carries four raises that measured over before this change as well as after, each with its reason. the prerendered document is unchanged, so what defers is the module hydration wants: headless chrome against the built server renders a written and a planned page whole, and every code fence on the quickstart page reaches its client-only highlighted form, which needs the deferred chunk and a real hydration. site/test/docs-content.test.ts holds the property against the built bytes, refusing a page with no prose to look for and prose no search of the assets can find, and budget.mjs names the shape of a wide refusal under the rows. red under mutation: one content module re-coupled statically (1 failed, 4 passed), a module export renamed (2 failed, 3 passed), a body filed under a slug the registry does not call written (2 failed, 3 passed), entity decoding dropped from the marker extractor so the vacuity guard fires (1 failed, 4 passed), the same-growth check dropped from the hint (1 failed, 22 passed), its unrecorded-row guard dropped (1 failed, 22 passed), and the count dropped from its text (1 failed, 22 passed). no migration, no wire or format byte moves and no forge or relay byte moves; the built site changes, so this owes a site deploy. the site gate is green end to end (659 passed over 53 files, 62 surfaces all under ceiling with nothing recorded) and the workspace suite is green (3952 passed over 122 binaries, 7 ignored) (#1878) 678876e6 · dbf3dbe6…diff
  • loot 0.4.21: loot-cli and loot-forge move to 0.4.21 with their two lock entries, the first public release since 0.4.20 and the one that carries the locked-pull fix. format major stays at 14 and the live relay already reports 14, so ADR 0066 has nothing to sequence here, and the top forge migration is still 0017, so this release owes no schema step. the Known Issues page is re-reviewed by running the 0.4.21 binary against a local loot-relayd rather than by re-reading source, and the locked-pull revert NO LONGER REPRODUCES: rehome materialized rather than refusing and put v2 from alice on disk, the converge the note names next answered already on one line and left it there, loot status reported an empty working change and loot log showed the arrived change as the tip, which is the state the printed advice implies, reached by typing the printed advice. so that entry is deleted, and FIXED_IN_MAIN, its HELD_ENTRIES row and pin 5 go with it, on that pin own instruction, leaving loot edit, which reproduced word for word, as the one entry. REVIEWED_AGAINST moves to v0.4.21 and LAST_REVIEWED to 2026-09-19, and the locked-pull paragraph further down the page stops pointing at a deleted entry and says what rehome does now. RELEASE_TAG is deliberately NOT moved: it names what dl.millerbyte.com can serve, and this release has reached nothing yet. the privacy page verb-count claim was re-checked against the binary rather than assumed, since that is what fell over before the last cut, and note_dispatched is called on all three dispatch routes, the table, buoy and bisect, so every verb this release newly publishes is counted. the site byte budget is re-recorded and exactly one ceiling moves, /known-issues lowered from 210944 to 208896 by the deleted entry, with no raise anywhere. tsc, the site suite (659 passed and 61 skipped over 60 files), the build, the byte budget and the published-surfaces pins are green, and the workspace suite is green (3970 passed over 122 binaries, 7 ignored) (#2089) 71ed6938 · dbf3dbe6…diff
  • the docs byte test refuses an empty set before it concludes anything from one, and the sentences #1877 and #1878 left behind stop counting what code can add to: with eagerHrefs matching nothing the eager-asset half of site/test/docs-content.test.ts was true of nothing and green, measured at 5 passed and 0 failed with that mutation in place against 1 failed and 4 passed once the refusal was written, and the same hole over the pages the registry calls written and over the bodies the modules publish is refused too, each proved by running its mutation without the guard (1 passed) and with it (1 failed). sharedChunkHint stops listing its silences, which were more than the list said, and states the property its guards define, with the row floor named SHAPE_ROWS so the doc cites code rather than a digit, and the CONTEXT.md line loses its whenever. tsconfig.test.json and ADR 0071 stop naming the tests that import tools/budget.mjs, a list #1877 wrote and #1878 falsified in the same session, and the ADR carries both survey numbers, 17 raw of which nine were the first draft of that config own fault and eight genuine over five files. the docs splat route stops describing a fallback it did not have: writtenDoc takes the node a missing body renders, so a written page whose module holds nothing under its slug shows the honest planned template rather than a bare title, verified by renaming one body key and reading the prerendered page, which carried the template on the same tree the gate refused (3 failed, 2 passed). the four content modules point at DocContentModule instead of pasting the rule it defines, the byte test failure message stops saying every docs surface where the set is a union over written pages, and the four raises in budget.json carry their own measurement, +239 B on /docs, +613 B on /install, +681 B on /known-issues and +1,444 B on /privacy, each against the figure its previous ceiling was derived from. the second reason claimed for including src is declined at the code with what refutes it: with src out of the include tsc -b reports exactly one error and it is the routeTree augmentation, import.meta.glob being typed by a type library reference that travels with a dependency rather than with an include. no migration, no wire or format byte moves and no forge or relay byte moves; the built site moves a few bytes per docs surface, all under ceiling with nothing recorded, and no page a reader sees changes. the site gate is green end to end (659 passed and 61 skipped over 60 files, 62 surfaces) and the workspace suite is green (3970 passed over 122 binaries, 7 ignored) (#2088) 45b6f3ec · 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.