The Astro and TypeScript implementation as it stands — components, dependency seams, entry points, and deliberate absences.

Code Architecture

This record answers what implementation exists today, what each part owns, and which direction its dependencies flow. Note semantics belong to content-model, physical placement to repository-layout, and what runs to build-and-validation.

Current stack

Solid lines follow runtime dependencies; the dashed line is the verification path. Arrows point toward the code or contract depended upon, and every box opens its source or design note.

Dependencies run one way. Shared packages take explicit inputs; they never discover this repository’s paths, vocabulary, or acceptance rules. The instance never reimplements a mechanism a package owns.

There is one application, site/, and no local package workspace or standalone build CLI. The casting commands also live under site/ because they consume the same TypeScript kinds and content binding; their generated artifacts live at the repository root under casts/.

Kind definitions

site/src/types/ owns the note kinds. Each kind is a directory holding three files: schema.ts (the strict Zod contract, shape, and companion declarations), kind.md (why each required field is required), and example.md (a minimal note parsed against its own schema by the tests, so the documentation stays executable).

types/context.ts builds the KindContext a kind receives: the base envelope, the license-id primitive, the typed-reference entry, and — for the kinds that need to interrogate rather than merely validate — the tag registry and license policy themselves. Method and Application notes have to ask which facet declared a proposed anchor; a Paper note has to ask what a license row permits. types/index.ts is the single enumeration of concrete kinds, exported both as a keyed DEFINITIONS map and an ordered KINDS array.

@galaxy-foundry/kind-schema supplies the definition, assembly, and companion mechanics. It ships no domain kinds. The directory-per-kind layout is a cross-instance contract implemented independently in all three Foundries, not a local preference. The library’s package-boundary rationale explains why the reusable mechanism stops short of owning those kinds.

The Paper kind is the one exception to a kind being wholly local, and it is a deliberate one. Its source-facing frontmatter — bibliographic identity, license posture, and read coverage — is the shared contract from @galaxy-foundry/source-note, spread into the kind and refined by that package’s coherence rules. Describing someone else’s work is the same problem in every Foundry; what stays local is which kinds are source notes, and everything that describes the note rather than its source.

Contract composition

site/src/lib/frontmatter-schema.ts is the composition point. It assembles each kind against the live registries, exposes them as NOTE_KINDS, states the content root once as CONTENT_DIR with a contentPath helper, and declares COLLECTIONS — the one mapping from content location to kind, glob, and schema.

COLLECTIONS is also the route table and the wiki-link precedence order, and both facts are content decisions rather than formatting ones; content-model owns why the rows sit in the order they do. No page, test, or resolver may carry a second collection list.

site/src/content.config.ts is a thin Astro adapter over that table. Its collections are spelled out one at a time rather than mapped, because a .map collapses every row to the widest common type and Astro stops discriminating the frontmatter shapes.

Registries and shared substrate

site/src/lib/registries.ts joins the instance-owned halves of the shared contracts into the one object every kind context is built from:

Both loaders resolve their file relative to the site working directory and cache it. The adapters supply paths and concrete vocabularies; they do not re-export or reimplement a package API.

site/src/lib/content-reader.ts binds @galaxy-foundry/content-reader to the collection table, a route mapping, and this corpus’s alias rule. Its exported factory accepts a content-path resolver: Astro supplies its content-relative frame, while casting supplies a repository-root frame. Both therefore get filesystem enumeration, note ids, frontmatter, aliases, and link targets from the same reader rather than maintaining parallel corpus walks. Its boundary design shows why Astro types stay on the application side of that seam.

remark-wiki-links.ts adapts that resolver with @galaxy-foundry/wiki-links for astro.config.mjs. This is the one module reachable from the Astro config, and the constraint it carries is easy to trip: config loads outside Astro’s module graph, so nothing reachable from it may import astro:content. Here the content reader is filesystem-based and imports no Astro runtime, which is what keeps the constraint satisfied without a second module split.

remark-citation-links.ts is the second module the config reaches, and carries the same constraint plus one of its own. It links a note’s numbered citation markers — [3], [1, 2], [7–9] — to the entries of that note’s own bibliography, giving each entry an id and each written number a link, and failing the build when a marker names an entry the list does not hold. Which heading opens a bibliography is not its decision: it reads referenceHeadingTerms from audit-citations.config.json as raw JSON, because the package that owns that vocabulary is a development dependency the site build may not import. The config is found by walking up from the working directory, since a module-relative import.meta.url is a /@fs/… URL under Vite rather than a path on disk.

render-vault-doc.ts is the corresponding path for a loose document — currently only the glossary. It resolves links through the same reader, renders with marked, and adds the bold-term anchors the glossary’s own page links into.

companions.ts measures a directory-shaped note’s siblings against its kind’s declarations rather than trusting frontmatter, which is why environment has no locked field.

Presentation registries

tags.ts, design-records.ts, and detail-routes.ts are presentation registries over already validated content: they decide which notes appear on a surface and what to label them. tags.ts also projects an optional facet_tag into the guide that leads a tag page; the page takes its guide label from the declaring kind, so Method and Application anchors share one mechanism. They do not define note membership, and each is held to the collection table by a test — DETAIL_ROUTES in both directions, the tag surface by the registry-drift check.

motifs.ts is domain furniture with no content dependency at all: a stable hash from a note’s metadata to repeatable point-cloud and barcode geometry, so a note’s marginalia is derived rather than authored and never changes between builds.

Reading application

site/src/pages/ owns routes. Every collection detail page runs through one route, [collection]/[...slug].astro, with collection-specific metadata in explicit branches; the common frame, breadcrumb, and tag links live once. Per-collection index pages, the glossary, the tag surface, the design index, and the home page are the remaining routes.

The reading shell — document skeleton, header, navigation, theme toggle, search, footer — is not here. It comes from @galaxy-foundry/site-kit, and site/src/layouts/Base.astro is only the composition point: it hands the package a SiteIdentity and the base URL and receives the markup. The site-kit runtime note documents the server-rendered shell and its small progressive-enhancement boundary. What stays local is that identity, the palette and type system in src/styles/global.css (custom properties the kit names but does not ship), and the domain components in src/components/. That stylesheet also has to point Tailwind at the package, because source detection does not look inside node_modules, and the built-output test is what checks it did.

Shipping no stylesheet has two further consequences, and both fail without an error. Element defaults here belong in @layer base, because unlayered CSS outranks every layer whatever its specificity: a bare a { color } outside one repaints the header and footer the kit colours with utilities, and the style-contract check still passes, since the utility is emitted and merely outranked. The shell’s behaviour at narrow widths is local for the same reason — navVisible is one number measured against a wide bar, and no count fits a phone, so the wrapping rule is this stylesheet’s to write. Built-output tests hold both.

site/src/pages/gallery/ is the visual acceptance surface for that boundary. It imports every case from @galaxy-foundry/site-kit/specimens and renders the shared components through this instance’s theme; package-declared isolated and document surfaces receive generated standalone routes. Local specimen groups place the filtration hero, persistence divider, point-cloud fingerprint, topology breadcrumb, and every declared reference kind beside the shared cases without moving their domain vocabulary into the package. Built-output tests require complete shared and local coverage, every standalone route, the gallery’s design-index link, and the intended search policy.

src/pages/usage/ is the publication surface for committed casts. lib/casts.ts discovers targets from their _target.yml declarations, resolves bundle placement through @galaxy-foundry/cast, and exposes the same inventory to the usage index, per-skill static routes, and the source Mold’s cast panel. lib/repo-root.ts anchors that filesystem read on Astro’s configured project root, so prerender bundling cannot silently turn a populated cast tree into an empty page.

The Astro application is a pure reader. It validates and renders source but does not mutate notes or cast artifacts. The only client-side code is progressive enhancement — the homepage filtration control — and there is no UI framework. Mutation is confined to explicit build-time commands.

Generation, citation audit, and casting

site/scripts/generate-kind-manifest.ts derives src/types/kinds.generated.json from the live kind definitions, their kind.md and example.md, and the collection table, through @galaxy-foundry/kind-manifest. It imports the same contracts validation does rather than building a parallel model, and it has a --check mode. build-and-validation owns when it runs; the library’s manifest-provenance note describes the trust boundary.

The citation audit is a second build-time path, not part of the reader stack above. @galaxy-foundry/audit-citations owns extraction, provider normalization, comparison, adjudication, and report rendering. audit-citations.config.json supplies this instance’s corpus and provider policy; site/src/lib/citation-audit.ts binds the package to committed evidence and exposes the offline replay used by site/tests/citation-audit.test.ts. Live provider access stays in the scheduled workflow. repository-layout owns the committed files and build-and-validation the commands and gates. See the shared citation-audit architecture for the separation between evidence acquisition, replay, and adjudication.

The tool-alignment audit is a second checker on that same path, and it is local. Its evidence is already in the repository — each fixture’s prose is checked against the pixi.toml and pixi.lock committed beside it — so there is no provider layer, no refresh, and nothing to acquire. site/src/lib/audit/tool-alignment/ holds the parts that know about pixi: manifest and lock parsing, the claim grammar, comparison, and report rendering. The parts that know about neither pixi nor citations are no longer here at all — they are @galaxy-foundry/audit-base, which audit-citations also consumes.

Two artifacts feed that grammar: the Environment note, and the manifest’s own header comment. They differ only in how a file becomes prose, so extract.ts exposes an entry point per artifact over one shared scan rather than a grammar per file — two grammars would drift apart exactly as the two files do. The artifact a claim came from travels with it in span.artifactKind, which is also the first exercise that field has had: a discriminator with one value is a field nothing has tested.

The local half is tool-alignment/lifecycle.ts, and what it holds is exactly what the package refuses to own. The verdicts and the evidence states, because the two checkers share one value of each and a common union would be a lowest common denominator or an untagged mixture. The claim id, because a citation candidate has no kind and a claim does, so one sentence can produce a channel claim and a version claim over one span. The corpus digest, because this one hashes ordered ids and the citation one hashes full records, which answer different questions about what counts as the same corpus. Each is a divergence that was found rather than assumed.

That boundary was laid out to make the extraction question answerable rather than to presume the answer, and the answer came out cleanly: the shapes are one contract with the vocabulary taken out. The two byte-identical files moved unchanged, the re-typed shapes moved as parameterized schemas, and the local file is what is left. audit/tool-alignment-README.md keeps the comparison and the remaining known limits.

Casting is the other build-time path. cast-corpus.ts projects the shared content index into the two maps the cast engine consumes. cast-spec.ts composes that corpus with the Kind definitions, reference contract, target-independent hooks, and supported modes. The local scripts are thin terminal adapters over @galaxy-foundry/cast: one casts a named Mold, and one checks or rewrites the committed set. The target file under casts/claude/ owns bundle placement and runtime-path constraints; the Environment Kind owns which companions are bundled. TDA code contributes the domain prose around those shared mechanics, not a second caster.

Publication adds no second cast. The claude target is a portable Agent Skills tree, with one thin plugin manifest for Claude Code and one for Codex inside the target directory, plus each runtime’s repository marketplace manifest at the repository root. Both runtime adapters point at casts/claude/skills/; tests/cast-publishing.test.ts checks their identity, placement, and portable name/description frontmatter.

Deliberate absences

  • No package workspace. One application, so contracts live beside it. Extracting them becomes worthwhile when a second consumer needs them without depending on the Astro project.
  • No server or database. The output is a static site with a static search index.

A record must not describe machinery as running before it runs. A reader who finds a present-tense sentence about a command and then cannot find the command has no way to tell whether the record is aspirational or the checkout is broken.

Code orientation

ConcernPrimary location
note kinds, context, enumerationsite/src/types/
schema and collection compositionsite/src/lib/frontmatter-schema.ts
Astro collection wiringsite/src/content.config.ts
instance registriessite/src/lib/registries.ts and its loaders
file discovery, ids, link mapsite/src/lib/content-reader.ts
Markdown link adapterssite/src/lib/remark-wiki-links.ts, render-vault-doc.ts
companion measurementsite/src/lib/companions.ts
presentation registriessite/src/lib/tags.ts, design-records.ts, detail-routes.ts
shell composition and identitysite/src/layouts/Base.astro, site/src/lib/site-identity.ts
shared and local visual acceptancesite/src/pages/gallery/, site/src/lib/gallery.ts
domain furnituresite/src/components/, site/src/lib/motifs.ts
routessite/src/pages/
committed-cast discovery and usage UIsite/src/lib/casts.ts, site/src/pages/usage/, site/src/components/CastArtifacts.astro
corpus and contract testssite/tests/
kind-manifest generatorsite/scripts/
cast composition and commandssite/src/lib/cast-*.ts, site/scripts/cast.ts, site/scripts/check-casts.ts
cast target and committed bundlescasts/
runtime plugin and marketplace adapterscasts/claude/.{claude,codex}-plugin/, .claude-plugin/, .agents/plugins/
citation-audit binding and testsite/src/lib/citation-audit.ts, site/tests/citation-audit.test.ts
citation policy and committed evidenceaudit-citations.config.json, audit/
audit lifecycle shared by both@galaxy-foundry/audit-base
verdicts, evidence states, claim idssite/src/lib/audit/tool-alignment/lifecycle.ts
pixi claim grammar and comparisonsite/src/lib/audit/tool-alignment/
tool-alignment binding and testsite/src/lib/tool-alignment-audit.ts, site/tests/tool-alignment.test.ts

Update this record when a component, dependency seam, entry point, or deliberate absence changes.