Changes touching this path
- the forge's published surfaces render themselves anonymously, and each response's cache class rides out of the selector that produced it (#751)
#749 built the read tier and nothing called it. This is the six surfaces
#466's table named -- profile, repo home, tree, blob, history, diff -- as
SSR routes over that tier, plus robots and a per-owner sitemap.
Three properties are structural rather than configural, which was the point:
STRICTLY ANONYMOUS (#486 Q4). No handler in site/src/server/forge.ts reads
a request, a header, a cookie or a token; each takes only what the URL
already says. So 'never serve one identity's view to another' is a fact
about the module's signature rather than a cache rule someone must
remember. Adding an identity parameter is the one edit that would break it.
THE CACHE CLASS IS CARRIED, NEVER RE-DERIVED. resolveSelector already
answers how a resolution may be cached; routes read loaderData.cache and
map it in one place. That is what keeps the ADR 0032 trap shut: a
change_id LOOKS like an address but is the durable handle carried across
amends, so it resolves 'revalidate', and a pinned version_id is the only
cache-forever class. Asserted twice -- a unit test on the header text, and
a live render proving one URL family splits three ways.
HONEST RENDERING (#497). A locked path shows its visibility tag and no
bytes; grant_log is never queried, so a grantee set cannot leak from a
surface with no way to learn one. Burned reads as a tombstone, sealed as
'Not published', absent as absent -- three outcomes a blank page would
have made indistinguishable. The 404 is deliberately one 404: 'no such
repo' and 'metadata private' must not be told apart.
Also here: a published-only repo (metadata private, paths published) gets
its index and nothing else -- no tree, no history, no diff -- which is
0005's barrier showing through the UI unchanged. Per #748 the profile
lists metadata-public repos only, there is no global directory, and the
sitemap is therefore per-owner: readable at a known URL is not consent to
be advertised.
vite.config.ts grows the prerender deny-list its own comment called
unnecessary -- true until a route read a database.
Acceptance: 49 tests green (31 new pure ones; the 8 read-tier tests against
a throwaway 0001-0005 cluster), npm run build clean with exactly the five
authored surfaces prerendered, and a 34-assertion end-to-end smoke -- real
sealed bytes through R2 -> decrypt -> unzstd -> highlighted HTML, all three
cache classes, every honest-rendering outcome. The client bundle carries no
pg, no SQL and no credential.
Publication: README.md, LICENSE-MIT and LICENSE-APACHE reach @world here,
the set .lootattributes has declared since #750. Operator-authorised at the
landing sign; nothing else in the tree changes tier.
2aa21bbe · dbf3dbe6… - the change ledger becomes the history surface, banded by what the server can read (#760)
8ad80be0 · dbf3dbe6…diff - every key an account ever held keeps resolving: migration 0008 publishes the one retired-to-canonical pairing the 301 itself discloses, and /k/<retired> redirects everywhere in one seam (#927, executing #506)
3a0fee42 · dbf3dbe6…diff - the landing hero becomes the receipt: one published object rendered as the ciphertext this host stores beside the plaintext a key opens, live from the forge, and no panes at all rather than invented ones (#1046)
c729cf41 · 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.