ADR-0003 — Artifacts as an MDX content collection
Status: Accepted (documents the existing decision)
2026-10 (DS-5): The collection is now
stations, one folder per station withpt.mdx/en.mdx(write-up only) and_stage.astro(the island). Entry ids are paths (weaver/pt); theslugfrontmatter field is gone. Seeapps/site/src/content.config.ts.
Context
Artifacts are the site’s content type: each needs a URL, typed metadata (status, category, presentation mode…), an interactive implementation, and — per the roadmap — prose. New artifacts should be addable without touching routing or index code.
Decision
One Astro content collection (src/content.config.ts) globbing
src/artifacts/**/*.mdx, with a Zod schema over frontmatter. Implementation code lives
beside the MDX in _-prefixed folders (excluded from the glob), imported and mounted
by the MDX body as a Vue island. Routes (/artifact/[...slug]) and the index derive
entirely from the collection.
The collection is the registry; the filesystem is the database; git is the CMS.
Alternatives considered
- Hardcoded pages per artifact: no schema, no index generation, metadata drifts — rejected.
- Separate data file (JSON/TS array) + component map: typed and explicit, but splits one artifact across two locations and needs a manual registry — the glob does this work for free.
- Colocate prose elsewhere (per-artifact
about.md): MDX already merges prose and mount point in one file; splitting would be structure for its own sake. - A real CMS: absurd at this scale; noted only to mark the boundary.
Tradeoffs
- (+) Adding an artifact = adding a folder. Zod validates at build.
render(post)gives prose for free when write-ups land. - (+)
_privacy convention keeps implementation out of the collection cleanly. - (−) The id/slug trap: routes use loader
idwhile links usedata.slug; they agree only because both artifacts set explicitslugfrontmatter (the loader adopts it). The schema’sslugify(title)fallback produces a value routing ignores — a 404 factory for any future artifact that omitsslug. Fix per architecture.md R1 (makeslugrequired, delete the fallback). - (−) MDX compile is part of the build; heavy artifact counts could slow builds (not a concern below ~100 entries).
Consequences
- The frontmatter schema is the artifact API: index UI, artifact shell, OG images, and
the future scaffold all read from it. Schema changes are project-wide changes —
version them consciously (roadmap adds:
hint,codefor HTTP numbering, OG copy). - Artifact implementations must stay self-contained (no cross-artifact imports); shared
needs graduate into
utils//composables/by the rule of three.
Future evolution
- Scaffold (
pnpm new:artifact) stamps the contract (artifacts.md R2). - Possible second collection for lab notes (content.md R7) — same pattern, separate concerns.
featured/categorybecome curation inputs for the index redesign.