Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 46c1b05cb44875d4d6ff68f5fc0dbc74770df92e
parent ea2d3d04d126af72cf52b77dfe0d48a78e791d88
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sat, 12 Sep 2026 02:57:39 -0400

common: the hub's member entry is one type, not two spellings of it

compose-hub.ts declared a local `HubSiteEntry` — siteId / siteTitle /
siteUrl / accent? / hubUrl? / pwa / contract — and then passed an array of
them straight into `buildHubCorpus`, whose parameter is `HubMemberInput`.
Two names, one shape, one direction: the same member as the hub is TOLD
about it, once by the pool file it writes and once by the corpus it maps.

S1 moved `HubMemberInput` into lib/archive/contract.ts and widened it with
the three fields only the pool entry carries, precisely so this copy could
go. It does, and nothing on the wire moves: the object literal built here is
unchanged field for field, and `buildHubCorpus` already read exactly these
names.

`HubCorpusSite` stays a separate type on purpose — it is the PUBLISHED
spelling (title/url plus two derived pointers) and corpus.json is frozen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Mcommon/bin/compose-hub.ts | 24+++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/common/bin/compose-hub.ts b/common/bin/compose-hub.ts @@ -21,6 +21,7 @@ import { buildHubCorpus, renderHubLlmsTxt, renderRobotsTxt, + type HubMemberInput, } from "../lib/corpus"; // CORS for the hub's own JSON (hub-sites.json). The hub is primarily a reader, @@ -47,19 +48,6 @@ const CORS_HEADERS = `# Generated by compose-hub.ts — do not edit by hand. Access-Control-Allow-Origin: * `; -// One entry the hub registry loads at boot to seed its trusted built-in pool. -// The origin is derived from siteUrl on the client (coerceBuiltin), so a pool -// site without a siteUrl can't be federated and is dropped. -type HubSiteEntry = { - siteId: string; - siteTitle: string; - siteUrl: string; - accent?: string; - hubUrl?: string; - pwa: boolean; - contract: number; -}; - async function exists(p: string): Promise<boolean> { try { await access(p); @@ -73,8 +61,14 @@ async function main(): Promise<void> { const paths = getPaths(); const publicDir = paths.exportPublicDir; - // Built-in pool: every configured site that publishes a public URL. - const builtins: HubSiteEntry[] = []; + // Built-in pool: every configured site that publishes a public URL. The entry + // the hub registry loads at boot to seed its trusted built-in pool, and the + // input buildHubCorpus maps — ONE type for both (lib/archive/contract.ts + // HubMemberInput), where this file used to restate it as a local + // `HubSiteEntry` with the same fields under a different name. The origin is + // derived from siteUrl on the client (coerceBuiltin), so a pool site without + // a siteUrl can't be federated and is dropped — by both consumers. + const builtins: HubMemberInput[] = []; for (const site of listSites(paths)) { if (!site.siteUrl) continue; builtins.push({