ai-labs splash goes live — Pages workflow wired, base path corrected before first deploy
Yesterday the splash was scaffolded assuming everything lived under `/ai-labs/`. But the GitHub repo is `lossless-ai-labs`. Without correcting the base path, Pages would have 404'd every internal link, image, sitemap entry, and OG URL on first deploy. This entry fixes that mismatch and adds the `.github/workflows/pages.yml` that bootstraps Pages on push to `master`.
Why Care?
The splash that landed yesterday looked great locally and built cleanly — pnpm build produced a dist/ ready to ship. The instinct was to enable GitHub Pages and watch it go live. The right move was to slow down for ninety seconds and check what Pages would actually serve, because the repo name and the splash's configured base path didn't match. A blind deploy would have published a site where every internal link, every preloaded stylesheet, every image, every sitemap entry, and every OpenGraph URL pointed at a path that didn't exist.
This entry fixes the mismatch, adds the deploy workflow, and runs a clean build to verify every absolute URL now resolves to the right place. Pages is now safe to enable.
What's New?
.github/workflows/pages.yml— runs on push tomaster,main, ordevelopment(andworkflow_dispatch). Checks out without submodules (the splash uses pre-syncedsrc/rollup/, not live submodule reads), installs withpnpm install --ignore-workspace, builds, and deploys viaactions/deploy-pages@v4.actions/configure-pages@v5runs withenablement: trueso the workflow bootstraps Pages itself on first run — no manual UI step required.Base path corrected from
/ai-labs/→/lossless-ai-labs/insplash/astro.config.mjs,splash/src/lib/seo.ts(SITE_URLandSITE_REPO), andsplash/public/robots.txt(sitemap pointer). All four were silently wrong before tonight.README updated — removed the "workflow will follow in the next iteration" note; documented the deploy trigger and the two acknowledged gaps versus the
maintain-splash-pagesskill's full convention (Pagefind search and/llms.txtendpoints — deferred, not deploy blockers).Clean build verified. After the path edits,
pnpm buildfrom a wipeddist/produced 40 pages, all OG image URLs absolute and pointing athttps://lossless-group.github.io/lossless-ai-labs/..., sitemap index and child sitemap both correctly rooted atlossless-ai-labs, canonical link correct, robots.txt sitemap pointer correct.
The bug that was about to ship
Pages serves at https://lossless-group.github.io/<repo>/. The repo is lossless-ai-labs, so Pages would serve at https://lossless-group.github.io/lossless-ai-labs/. But splash/astro.config.mjs had:
site: 'https://lossless-group.github.io',
base: '/ai-labs/',…and Astro builds every internal <a>, <link>, <script>, <img>, sitemap entry, and OG image URL by prepending BASE_URL to the path. So the rendered HTML would have shipped with hundreds of /ai-labs/... references, every one of them 404 on a host serving at /lossless-ai-labs/. The favicon, the CSS bundle, the OG image, the in-page nav — all broken.
The local directory is ai-labs/ (legacy from before the repo was created with the lossless- prefix), so when scaffolding the splash yesterday the obvious-looking value for base was the directory name. Worked on localhost, would have failed on Pages. The asymmetry was invisible because nothing in the splash test loop touched the deployed URL.
The same mismatch lived in two other places:
// splash/src/lib/seo.ts — before
export const SITE_URL = 'https://lossless-group.github.io/ai-labs/';
export const SITE_REPO = 'https://github.com/lossless-group/ai-labs';SITE_URL feeds canonical links and the OG sextet's absolute URLs. Unfurlers read those values verbatim — a wrong og:image URL means iMessage / WhatsApp / Slack all show the favicon fallback (or nothing) instead of the 1,312×736 instrument-bench banner that just got generated. SITE_REPO was wrong in a quieter way — the "github" link in the footer would have 404'd.
# splash/public/robots.txt — before
Sitemap: https://lossless-group.github.io/ai-labs/sitemap-index.xmlSitemap discovery convention says crawlers look at robots.txt for the Sitemap: line. A wrong absolute URL there is the kind of issue you only catch by submitting the sitemap manually to Google Search Console and watching it report 404 — by which point you've already wasted indexing budget.
Fix in all four places is one search-and-replace: /ai-labs/ → /lossless-ai-labs/, lossless-group/ai-labs → lossless-group/lossless-ai-labs.
Verification
After the edits, a clean build produced output where every absolute URL is correct:
$ rm -rf dist && pnpm build
... 40 page(s) built in 1.18s
[@astrojs/sitemap] `sitemap-index.xml` created at `dist`
$ grep -oE '<meta[^>]*property="og:image[^>]*>' dist/index.html
<meta property="og:image" content="https://lossless-group.github.io/lossless-ai-labs/ogimage__AI-Labs--Banner.jpg">
<meta property="og:image:secure_url" content="…lossless-ai-labs/ogimage__AI-Labs--Banner.jpg">
<meta property="og:image:type" content="image/jpeg">
<meta property="og:image:width" content="1312">
<meta property="og:image:height" content="736">
<meta property="og:image:alt" content="Three small isometric instrument modules…">
$ head dist/sitemap-0.xml
<loc>https://lossless-group.github.io/lossless-ai-labs/</loc>
<loc>https://lossless-group.github.io/lossless-ai-labs/changelog/</loc>
…
$ cat dist/robots.txt
Sitemap: https://lossless-group.github.io/lossless-ai-labs/sitemap-index.xmlEvery absolute URL the deployed site emits is correctly rooted at lossless-ai-labs. The bytes/MIME/URL agreement for the OG image holds: bytes start FF D8 FF, og:image:type says image/jpeg, URL ends .jpg, file is hosted from splash/public/ so no CDN gets between the unfurl bot and the file.
What's not yet wired (intentional follow-ups)
These were the splash's three gaps versus the maintain-splash-pages skill's full convention before this entry, and they remain gaps after:
No Pagefind search. The skill's convention is "every splash ships search-by-default" — confirmed twice across the family (memopop-site, lfm/splash). The ai-labs splash will need
astro-pagefind+ thedata-pagefind-bodymarkers on detail pages, aSearchBoxcomponent, a/searchroute, and CSS-variable overrides on the Pagefind UI. This was deferred from yesterday's scaffold; it's still deferred.No
/llms.txt+/llms-full.txtendpoints. Context-vigilance-kit (2026-05-09) and memopop-ai (2026-05-11) both now serve these for LLM-facing discovery. Theastro.config.mjshere already excludes them from the sitemap filter (forward-looking), but the actual endpoints don't exist yet.No sort controls on
/changelog/and/context-v/list pages. The skill specifies aSortControlscomponent, server-pre-sorted default, per-pagelocalStoragepersistence. Not present here yet.
All three are content-quality additions, not deploy blockers. Pages goes live cleanly without them; they get added in subsequent passes when the splash is ready for that level of polish.
What's next
Push
master(this commit + the two earlier ones that have been sitting unpushed) — that triggers the workflow,configure-pages@v5bootstraps Pages, the artifact gets uploaded and deployed. First successful deploy lands athttps://lossless-group.github.io/lossless-ai-labs/.Manual verification post-deploy: confirm the mode toggle (dark/light/vibrant) works without FOUC, confirm the OG card unfurls correctly in iMessage / WhatsApp / Slack / Discord / X by pasting the live URL.
Then circle back to the three follow-ups above in order — Pagefind first (high signal, well-documented pattern in the skill), then llms.txt (mechanical port from the children), then sort controls.
Related
The reference implementations cited by the skill:
lfm/splash/(most recent, asymmetric hero),content-farm/splash/(canonical pseudomonorepo variant),ai-labs/memopop-ai/apps/memopop-site/(first instance).The
maintain-splash-pagesskill inlossless-skills/— codifies the workflow shape, the package-isolation discipline (N/A here since ai-labs doesn't publish), the Pagefind wire-up, and the acceptance checklist.The
open-graph-share-seo-geoskill — the JPEG-over-WebP rule, the bytes/MIME/URL agreement invariant, and the cache-bust recipe used to force a re-unfurl after fixing a stale preview.Yesterday's entry:
2026-05-11_01.md— the broader splash scaffold and the DidiDecks repo promotion that this Pages-deploy work caps off.
