A public GitHub repo opts in with spfn.site.yaml, keeps its markdown
under site/, and @spfn/pages turns it into a validated, sanitized,
render-ready site model. No build pipeline on the author's side — push is deploy.
The presence of spfn.site.yaml at the repo root is the
owner's consent to publish — registration rejects repos without it. From there the package
reads AI-authored markdown from the content root and produces the whole site model: pages,
posts, nav trees, theme CSS. Per-file failures never take the site down; they land in
problems and the file is skipped. This is the first source driver of SPFN's
frontend serving primitive — the tenant edge is shared infrastructure, and content sources
plug in via the ContentSource interface.
A mount in spfn.site.yaml serves documentation that lives
next to the code — a README, a whole guide tree — as site routes, so docs are consumed
on-site instead of on GitHub. A source page is the curated version: a page whose frontmatter
says source: packages/core/src/db/README.md serves that doc at the page's own
clean URL, with no src/ leaking in. Every relative link in rendered markdown
resolves in order — a served markdown file becomes its route, a public/ asset
becomes its served URL, any other repo file links back to the repo — so authors link files
the way the repo is laid out and the site just works. The reference this page points to is
itself a package README served this way.
spfn.site.yaml at the repo root — opt-in proof, site meta, content root.
READMEs and guide trees from the repo, served as site routes.
A repo doc served at a curated URL via frontmatter source:.
GFM, sanitized; repo-aware links, GitHub-style anchors, shiki dual-theme code.
tokens.json becomes --sf-* CSS variables; custom.css layers on top.
pages/*.html served verbatim as full standalone documents.
validateSite at registration — [] means publishable, entries are actionable feedback.
GithubContentSource with ETag conditional requests; MemoryContentSource for tests.