GENERATED VIEW · PRIVATE ARCHIVE · DO NOT SERVE
RobCo Industries · Archive Museum

record.md



BUGS

bugs/vanishing-addresses/record.md

sha256 2ebfcd6e75c07775 · 4086 bytes · original held in the private archive

--- title: The Vanishing Addresses status: SEALED repo: archive observed: 2026-07-20 caught_by: measuring the same history query with and without --no-renames and getting two different answers one_line: Doc pages were named by content hash, so every edit moved a page's address and every regen dropped the old one — and the tool that mined the old addresses silently under-counted them. guard_location: museum/generate.mjs · redirect ledger · lines ~310 and ~1741; migrateRedirectLedger() verified: fresh + bare-derived clones regenerate identically; a redirect stub confirmed resolving to its new nested page over HTTP exhibited: true lesson: A content-derived address moves on every edit and rots every inbound link; and a history-mining mechanism can silently miscount — always pass --no-renames when mining git log --diff-filter=A over similar-shaped generated files. provenance: - commits 43390e6 + 0f3d846 (this archive) - Claude memory record museum-path-based-naming-and-redirects - museum/redirect-ledger.json (the committed ledger) --- ## What happened Document pages were named `docs/<sha256(rawBytes)[:12]>.html` — the generator content-hashed its **inputs**, so **every edit moved the page's address**, and every regeneration dropped the old one. Across this repo's own history, **389 distinct hash addresses** have existed. Worse, and this is the second half of the specimen: the first mining pass to recover the old addresses found only **305** of them. Git's content-similarity rename detection was pairing unrelated generated pages as "renames" of each other — they share large boilerplate around a short doc body — and hiding the rest from `--diff-filter=A`. A mechanism built to lose nothing was itself quietly losing 84 addresses. ## How it was caught The address-instability was caught by the owner-facing naming review. The **miscount** was caught by measuring the same history query with and without `--no-renames` and getting two different answers (305 vs the true 389). ## The guard Two guards. **(1)** Pages are named from the document's **archive path**, mirroring the archive's directory tree — the address only moves if the document itself is renamed. A runtime `seenSlugsLower` check aborts the build if two paths ever fold to the same address case-insensitively (Windows checkouts fold case). **(2)** Every old hash address ever published is frozen in a committed `redirect-ledger.json`, mined once with `--no-renames` on both `git log` calls; each old address whose document still exists gets a meta-refresh redirect stub at the old path, every build. HTML stubs (not Cloudflare `_redirects`) so old bookmarks resolve even on a raw `file://` open. ## What the guard costs A 389-entry ledger committed forever, plus a redirect stub file per live old address in every build — paid so that no link anyone ever saved can rot. The `--migrate-redirects` ritual is a maintained code path (though it should not need to run again, since path-based naming produces no new hash addresses). ## Containment Verified per the project standard: fresh GitHub clone **and** bare-clone-derived clone, both `git status` clean at stamp `80bf9bb · f64fb7397980c9cb`, byte-identical to each other and to two back-to-back local regenerations; 4,986 internal links checked, 0 broken; a redirect stub confirmed resolving to its new nested page when served over HTTP. One gap recorded honestly by the source: a `file://` click-through of the meta-refresh itself was **not** separately re-verified by screen automation that session (relying on meta-refresh being a protocol-agnostic HTML mechanism) — worth a real desktop-browser check next time. ## Provenance Commits `43390e6` + `0f3d846`; `museum/redirect-ledger.json`. Full account, including the owner's three-option choice and the `--no-renames` lesson, in the Claude memory record `museum-path-based-naming-and-redirects`. Mockup specimen 06 corroborates (its figures "390 / 306" are off by one from the memory record's audited "389 / 305"; this record uses the memory record's numbers).
STAMP · generated for RELEASE v2.8.5 commit 06e5180 (06e51801b38a) · archive input-tree hash c07fbfbdd2e1ddeb · 754 files · no wall-clock timestamp (regenerates identically when nothing changed).