Skip to content

refactor: the dictionary snapshots are build input, so move them to src/dict/ - #455

Merged
oddharsh merged 1 commit into
mainfrom
refactor/dict-into-src
Aug 18, 2026
Merged

oddharsh merged 1 commit into
mainfrom
refactor/dict-into-src

Conversation

@oddharsh

Copy link
Copy Markdown
Owner

www/a-dict/ and www/p-dict/ become src/dict/a-dict/ and src/dict/p-dict/. They hold the previously shipped bytes of the content-hashed shell and of each page, kept so build.mjs can compute dcz deltas against what a returning visitor still holds. Nothing in either directory is ever served.

Fifth slice of lifting the parked bun branch's renames onto main, and the first of three that finish www/.

Being outside www/ beats the .assetsignore entry it replaces

An ignore line stops an upload. Living outside the served tree means the build never stages the files at all — the staged tree loses 130 files that were copied on every build purely so wrangler could then decline to upload them.

The contract test that asserted the .assetsignore entry now asserts the directories are absent from www/, which is the property that actually matters. Same guarantee, one layer earlier.

No served artifact changes

1496 compared, all byte-identical. The only staged differences are those 130 snapshots no longer being copied, and .assetsignore losing two entries that can no longer match anything. Both were already excluded from upload on main, so nothing on the wire moves.

One dead filter removed

build.mjs's view-transition tripwire walked www/ while skipping "a-dict/". With a-dict gone from that tree the exclusion cannot match, and a filter that cannot fire reads as protection that is not there.

Gates

305 tests, build, lint, typecheck, routes:check, pages:check, tools:check, perf-budget, photos:check, check-wrangler, the cal suite, and a wrangler deploy --dry-run.

What remains of the www/ split

piece shape
dictionaries → src/dict/ this PR
prose → src/content/ www/writing, www/md, www/index.md; build inputs, not served paths
pages → src/pages/, assets → public/ the last and largest, and the one that renames the staged root

Doing them separately because the third changes wrangler.jsonc's assets.directory and the build's staging root, which is a different kind of risk from moving files the build merely reads.

…rc/dict/

www/a-dict/ and www/p-dict/ become src/dict/a-dict/ and src/dict/p-dict/. They
are the previously shipped bytes of the content-hashed shell and of each page,
kept so build.mjs can compute dcz deltas against what a returning visitor still
holds. Nothing in either directory is ever served.

Fifth slice of lifting the parked bun branch's renames onto main (#450, #451,
#452, #453), and the first of three that finish www/. Done by hand rather than
cherry-picked, for the reason #453 records: the branch's split commit sits on
the TypeScript conversion and brings 714 conflicts.

BEING OUTSIDE www/ IS A STRONGER GUARANTEE THAN THE .assetsignore ENTRY IT
REPLACES. An ignore line stops an upload; living outside the served tree means
the build never stages the files at all. The staged tree loses 130 files that
were copied on every build purely so wrangler could then decline to upload
them. The contract test that asserted the ignore entry now asserts the
directory is absent from www/ instead, which is the property that actually
matters.

NO SERVED ARTIFACT CHANGES: 1496 compared, all byte-identical. The only staged
differences are those 130 snapshots no longer being copied, and .assetsignore
losing two entries that can no longer match anything.

Also removes a filter in build.mjs's view-transition tripwire that skipped
"a-dict/" while walking www/. With a-dict gone from that tree the exclusion
could not match, and a filter that cannot fire reads as protection that is not
there.

Gates: 305 tests, build, lint, typecheck, routes:check, pages:check,
tools:check, perf-budget, photos:check, check-wrangler, cal, wrangler dry-run.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
aadhar-sh 54b076c Aug 18 2026, 03:32 PM

@github-actions

Copy link
Copy Markdown
Contributor

Wire-size diff vs merge base

1e708d4 → 1931135

Brotli q11, the quality the edge serves. Every number here is deterministic:
an unchanged file produces no row. Advisory — this check fails on nothing.

Client assets

No change. 21 files, 75.10 KiB Brotli total.

Pages

No change. 48 files, 502.10 KiB Brotli total.

Worker bundle

No change. 230.10 KiB gzip.

Dictionary deltas (pd/)

No change. 144 deltas, 456.84 KiB total.

@oddharsh
oddharsh merged commit b531e6c into main Aug 18, 2026
7 checks passed
@oddharsh
oddharsh deleted the refactor/dict-into-src branch August 18, 2026 15:33
oddharsh added a commit that referenced this pull request Aug 18, 2026
www/writing/, www/md/ and the four root .md documents become src/content/. The
writing posts and their posts.json, the hand-authored twins for the three
Worker-rendered pages, and index/README/auth/resume are AUTHORED text, not
assets that happen to sit in the served tree.

Sixth slice of lifting the parked bun branch's renames onto main, and the second
of three that finish www/.

EVERY PUBLIC URL IS UNCHANGED. Unlike the dictionaries in #455, most of this IS
served (/writing/<slug>.txt, /index.md, /resume.md), so build.mjs stages
src/content back into the served tree at the same paths. Source layout and URL
layout are different questions; only the first one moved.

Staged tree byte-identical across 1497 files, except three Worker sources whose
COMMENTS name a moved path. Those reach the bundle and no served asset.

TWO THINGS THE GATES CAUGHT, both from a path sweep that could not tell one kind
of reference from another:

  * gen-md-twins.mjs's HAND_DIR was the string "www/md" with no trailing slash,
    so the sweep missed it and the three hand-authored twins stopped publishing.
    routes:check found it: /security.md, /lens.md, /coffee.md, /around.md and
    /terminal.md all 404.
  * the same script decides a COMMITTED twin wins by looking for it under www/.
    With index.md moved, that lookup silently failed and the generator wrote its
    own homepage twin over the hand-written one: 2170 bytes where the real file
    is 2642. Nothing errored. The byte control is what surfaced it.

Both are the same lesson as the icons.svg path in #452: a path that names a
repository location from inside a program keeps working right up until the
location moves, and the failure is quiet.

Gates: 305 tests, build, routes:check, lint, typecheck, pages:check,
tools:check, perf-budget, photos:check, check-wrangler, cal, wrangler dry-run.

Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
oddharsh added a commit that referenced this pull request Aug 18, 2026
The last of the www/ split. 36 HTML documents become src/pages/; the other 804
files, which are bytes a browser fetches unchanged, become public/. The staged
root renames with them: .build/www is .build/public, and wrangler.jsonc's
assets.directory follows.

Seventh and final slice of lifting the parked bun branch's renames onto main
(#450, #451, #452, #453, #455, #456). The mapping needed no judgement: main's
www/ held exactly 840 files, the branch's two destinations hold exactly those
840, and every one lands in exactly one of them. Every HTML is a page; nothing
else is.

EVERY SERVED ARTIFACT IS BYTE-IDENTICAL, 1497 compared with the root name
normalised. The four remaining differences are path references inside cal,
serendipity and the Worker: three comments and one JSON import specifier.

THE BUILD COMPOSES THE SERVED TREE NOW rather than copying one directory.
public/ + src/pages/ + src/content/ + src/client/ + src/styles/ all stage into
.build/public, so the URL layout is untouched while the source layout says what
each file IS. servedFiles() walks the three authored roots in one place, because
a tripwire that walks only some of them reports a clean tree it never read.

SIX THINGS THE GATES CAUGHT, and the pattern is worth stating: a blanket path
sweep cannot tell a source read from a staged path, an asset from a document, or
a path from a regex.

  * staticShellPages() read www/ for the freshness check
  * the Worker imported ../../www/images/hashes.json
  * gen-md-twins looked for page HTML under www/, then read the generated tier
    from the staged www/ root
  * the page generators in pipelines/ wrote into www/
  * the .src.html twin read its AUTHORED source from the wrong root, so it fell
    into a catch and shipped the STAGED bytes: readable twins carrying rewritten
    /a/ hashes, which is the whole point of the twin lost silently. The build's
    own counter is what showed it, 47 from staged where main says 12.
  * and one false positive: `assert.match(lens, /… 401 && www/)` is a regex whose
    DELIMITER the sweep read as a path separator, rewriting the assertion out
    from under a real variable named www.

Gates: 305 tests, build, lint, typecheck, routes:check, pages:check,
tools:check, perf-budget, photos:check, check-wrangler, cal, wrangler dry-run.

Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
oddharsh added a commit that referenced this pull request Aug 18, 2026
* docs: the layout table describes the tree that now exists

Seven slices moved almost every path in this repository (#450, #451, #452,
#453, #455, #456, #457), and the automated sweeps that repointed code also
walked CLAUDE.md. That left the map wrong in two different ways.

STALE: the table still said public/ holds "pages, client scripts, CSS, photos,
dictionaries". It holds none of the first four now. Rows added for src/pages,
src/content and src/dict; scripts/ folded into the tools/ row; every row's
description checked against the tree rather than against its own history.

FALSE: the sweep rewrote HISTORICAL names, so the file claimed the Worker lived
at `public/_worker.js/` and the photo pipeline at `public/scripts/`. Neither
ever existed. A stale note is a note somebody distrusts; a false one is a note
somebody follows.

The naming note now records the full sequence, holding -> www -> the split, and
says explicitly that the rewrites deliberately left old mentions alone, so
reading `www/` in an older note is correct rather than a typo. It also drops the
"duplicate path" explanation, since scripts/ no longer exists to be confused
with tools/photos/.

And it states the test for where a new file goes, which the table never did: if
a build step transforms it, it is src/; if it ships byte-for-byte, it is public/.

* docs: the intro names the split tree too

The bullet under the header still called public/ the live site including the
_worker.js/ dispatcher, which is two moves out of date: the Worker left the
served tree in #450 and the documents left it in #457. It now names what each
root is for, which is the same question the table below answers per entry.

---------

Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant