Static Application Foundation

The static application foundation defines how VyDex builds pages, separates domain code from Astro, and checks those boundaries. This page is for maintainers and coding agents changing application structure, root tooling, styling, or build behavior.

Purpose and Ownership

The foundation keeps public output static and prevents product rules from becoming coupled to Astro pages or components.

It owns:

  • The root Node and npm project.
  • Static Astro configuration and strict TypeScript checking.
  • The allowed dependency direction between Astro and src/domain.
  • The FoundationLayout.astro document boundary that renders the Stage 1 Site Shell around page content.
  • The global stylesheet entry point and locally bundled fonts used by the Frontier Atlas Design System.
  • Unit, responsive browser, and accessibility test harnesses, including an explicit hosted-origin mode.
  • The local application launcher, descriptor-gated production build, fixed-metadata test build, and root release-command entry point.
  • Static publication of the selected versioned Dataset Schema, release-specific Dataset artifact, and their Cloudflare response metadata. Dataset 2.0.0 is current for Entry v2 releases; the v1 contract remains available for legacy output.
  • Static generation of the Changelog, current public Entry routes, current and immutable Methodology routes, and the generic 404.html through thin Astro pages.
  • Production sitemap generation through Astro's official @astrojs/sitemap integration and static crawler discovery through public/robots.txt.
  • The root validation workflow and frozen dependency installation used by CI.

It does not own:

Normal Flow

  1. npm ci installs the exact root dependency tree from package-lock.json.
  2. Astro pages and layouts may import the public domain entry at src/domain/index.ts.
  3. Domain modules remain framework-independent and cannot import Astro or UI modules.
  4. Public HTML pages render their main content through FoundationLayout.astro, which supplies document metadata, the skip link, Header, single Main region, and Footer.
  5. npm run build:test type-checks the project, runs Vitest, generates deterministic static output with fixed non-production release metadata, and verifies the final sitemap files against that output. Ordinary Playwright validation uses this explicit test mode.
  6. npm run build performs the same checks and sitemap verification but loads the persisted production descriptor and requires a valid production origin.
  7. npm run release:check compares current committed public output with active release state without creating identity. npm run release:sync -- --confirm CREATE_NEXT_RELEASE creates a successor only when that comparison detects changed public output. npm run release:ci reproduces committed state, while direct release:next remains available for intentional successor creation. These commands build into isolated staging and none deploys by itself; the protected deployment workflow composes synchronization, a generated-state commit, reproduction, and upload after read-only validation succeeds.
  8. npm run build:pages-preview produces production-shaped Git preview output and adds validated redirects. It uses the production origin for canonical URLs rather than the temporary preview hostname.
  9. npm run test:browser rebuilds in test mode, writes the validated test-release redirects into disposable dist/, serves the output through a local Wrangler Pages server, and runs the Playwright and Axe checks. The public command supplies the reserved https://vydex.example origin so the Dataset Schema receives its absolute canonical $id.
  10. Hosted verification supplies VYDEX_BROWSER_BASE_URL and uses playwright.hosted.config.ts. That mode starts no local server and does not proxy production canonical URLs to local output.

The / route is the static Stage 1 Homepage, /about/ is the static Stage 1 About Page, /changelog/ is the static Stage 1 Changelog Page, and /export/ is the static Stage 1 Export JSON Page. Current public Entry routes are generated by the Stage 1 Entry Page, and current Topic Trail routes are generated by the Stage 1 Topic Trail Page. The Stage 1 Methodology Page generates /methodology/ for the highest validated version and one immutable route for every retained version, including /methodology/1.0.0/ and /methodology/2.0.0/ when both records are present. The project-level 404.astro produces the generic static 404.html. Their complete release-selected content is generated into HTML.

astro.config.ts takes the approved production origin from the Cloudflare Pages environment contract and passes it to Astro's sitemap integration. The integration discovers static routes, including generated Entry and Topic Trail paths, without maintaining a second slug list. It emits sitemap-index.xml and sitemap-0.xml; the error-page filter excludes 404 and 500 routes, while Astro excludes non-page endpoints. The production sitemap artifact adapter derives the expected URL set from the final generated HTML files, excludes error pages, rejects non-page URLs, requires the production origin, checks the index-to-child reference, and requires the production sitemap directive in robots.txt.

Interactions With Other Project Areas

The canonical-record domain module defines the data contracts consumed by loaders, publication revisions, release construction, pages, and exports. Publication revisions, material activity, routing, dataset generation, and release construction remain framework-independent; the foundation provides their dependency boundary and test environment but does not own their behavior.

The Dataset Schema route is a thin Astro endpoint over the shared Schema generator. Astro prerenders the JSON file, while public/_headers supplies its application/schema+json media type and immutable cache policy on Cloudflare Pages. The endpoint reads PUBLIC_SITE_ORIGIN; the domain Schema generator receives the origin explicitly and never reads the environment.

The release-specific Dataset route is a dynamic static endpoint over the application export boundary. It receives the generated path parameters and bytes as prerender props, verifies that the requested route reconstructs the prepared immutable path, and emits the JSON artifact with immutable response metadata. Fixed development/test metadata creates only disposable build output. Production route generation uses only the persisted genuine descriptor and fails while it is absent or invalid.

The application release adapter composes the read-only canonical loader with the framework-independent constructor. It reads PUBLIC_SITE_ORIGIN at the application boundary. Production loads the existing persisted descriptor, while development and explicit test mode use stable fixed non-production metadata. The application export adapter then composes that selected release with Dataset generation and derives the page model from the artifact. Astro pages and endpoints must use these named entry points rather than parse authoring files, choose metadata directly, or assemble a second export description.

The Stage 1 Homepage, Stage 1 About Page, Stage 1 Changelog Page, Stage 1 Entry Page, Stage 1 Export JSON Page, Stage 1 Methodology Page, and Stage 1 Topic Trail Page receive resolved release data through the Astro boundary. Their feature modules do not load files, access the environment, generate release metadata, or fetch canonical content in the browser.

Resolved release data keeps absolute canonical URLs for metadata and verification. Public-interface projection converts internal clickable links to same-site paths, so a local browser does not navigate to the reserved browser-test origin.

The repository also reserves separate locations for canonical records, publication snapshots, generated release data, and static output. Storage and generation behavior remain separate from the application foundation.

The browser harness keeps project definitions, viewports, expectations, and timeouts in one shared configuration. Ordinary npm run test:browser owns its build, test redirect preparation, and Wrangler server. The release-specific Playwright configuration starts no second server because Repeatable Release Publication owns Wrangler and passes the exact staged output directory to it. Hosted mode also starts no server; Hosted Release Verification supplies the live request origin while canonical expectations remain fixed to https://vydex.pages.dev.

The release gate invokes the foundation's type-check, Vitest, Astro build, and browser-test boundaries. It supplies the validated production origin, directs Astro into an isolated output directory, and verifies both generated files and hosted behavior before promotion. The foundation remains responsible for producing static pages and the reusable browser harness; the gate decides whether the complete result is promotable.

Cloudflare Pages Deployment is a protected workflow that runs after a successful main validation or an explicit manual dispatch. It synchronizes release selection, commits only verified generated release state when required, reproduces the selected release, and uploads dist/. Normal validation remains read-only, and neither workflow moves Cloudflare concerns into Astro pages or domain modules.

Hosted Release Verification reuses the same desktop and mobile projects, keyboard and focus checks, supported-width overflow assertions, downloads, no-JavaScript journeys, and Axe scans against the live origin. Hosting API access remains outside the browser harness.

Retype is an independent npm project under docs/documentation/. It publishes documentation to GitHub Pages; its base path, dependencies, and output do not apply to the Astro application.

Framework-independent domain modules import Zod from zod, never from astro/zod.

Frontier Atlas owns presentation tokens, typography roles, shared components, and responsive behavior. The foundation owns the Astro document boundary that loads those styles, the build process, and the test harness. The Stage 1 Site Shell owns the Header, Footer, navigation, skip-link behavior, and required page order rendered through that boundary. Page modules provide main content and must not move presentation rules into the framework-independent domain layer.

Internal Edge Cases

  • The domain entry exports versioned canonical records, cross-record validation, publication revisions, material activity, route generation, public source ordering, Dataset v1/v2 generation, and release construction. Page features obtain release data through the application adapter and consume public domain interfaces without reversing the allowed dependency direction.
  • TypeScript is pinned to 6.0.3 because the pinned Astro checker accepts TypeScript 5 or 6, not TypeScript 7.
  • The application base path is /, and .env.example documents PUBLIC_SITE_ORIGIN. Test-mode builds use reserved non-production origins. Production and Pages preview builds require the externally configured origin https://vydex.pages.dev; release validation rejects any value that disagrees with the committed manifest.
  • Reserved origins such as https://vydex.example remain valid canonical test identities but are never browser-navigation dependencies for internal public links.
  • The repository has a complete validated Stage 1 seed record set, an active committed successor release, and a retained immutable archive for the initial release. Development, unit tests, browser tests, and conformance builds use one fixed non-production descriptor value without writing it. Production builds never fall back to that adapter.
  • Sitemap URLs always use https://vydex.pages.dev, including in test and preview artifacts. Temporary hosts remain non-canonical and are controlled through response indexing policy rather than by rewriting sitemap URLs.
  • Test builds prerender a dated non-production Dataset artifact from the real seed records so the Export JSON link can be downloaded and Schema-validated. The generated file remains inside ignored dist/ output and is not a genuine release artifact.
  • Browser-test preparation derives _redirects from the validated fixed-metadata release instead of hand-writing test-only routing behavior. Production staging continues to use release-gate-generated redirects.
  • The Methodology version route derives static parameters from every resolved canonical public version. Unsupported versions remain absent from generated paths, while preserved v1 and current v2 routes remain distinct.
  • Topic Trail routes derive their static parameters only from resolved non-empty public trails. Invalid or empty trails block release construction before paths are generated.
  • Vitest runs both foundation architecture tests and domain validation tests in a Node environment.
  • Ajv validates generated datasets against the exact draft 2020-12 Schema. The pinned fast-uri override keeps Ajv's URI parser on its patched compatible release.

Cross-System Edge Cases

  • The Astro app and Retype docs use independent lockfiles and build commands. Installing or building one must not overwrite the other.
  • Canonical records and publication snapshots must not be placed in generated output folders.
  • A failed browser test can occur after dist/ has been generated. The presence of that directory does not mean a release is ready.
  • A successful build:test proves static rendering but does not create or validate genuine production release state.
  • A successful release-gate promotion updates local dist/ and the internal manifest, but it does not update the hosted site.
  • A Git-integrated Pages preview uses production release data and canonical origin even though Cloudflare assigns it a temporary preview URL. It must not be confused with the diagnostic private-preview model.
  • The deployment workflow synchronizes, rebuilds, and rechecks the validated main commit immediately before upload; it does not depend on an artifact from an earlier workflow run.
  • A code, metadata, content, dependency, or build change may alter public bytes while the active descriptor still points to an earlier source commit. The protected deployment workflow must create and push a verified successor before upload; unexpected generated paths or a non-fast-forward push fail the deployment safely.
  • A hosted browser run must not start Wrangler or proxy canonical URLs to local output; either behavior would test a local surface instead of production.
  • The Export JSON page and dated endpoint must fail together when application export preparation returns diagnostics; neither route renders a placeholder or independently repairs metadata.
  • Changelog content is generated from release.changelog_events; the browser does not load, sort, group, or filter material events.
  • Unknown Entry slugs remain absent from getStaticPaths(). The built host must serve the generated 404.html with an HTTP 404 rather than redirecting or asking client JavaScript to recover.
  • Unknown Topic Trail slugs follow the same static 404 contract.
  • Unknown Methodology versions also remain absent from static paths and use the same generic 404 behavior.
  • Domain code may use framework-independent packages such as Zod and Markdown parsers, but it must not depend on Astro pages, layouts, or components.
  • Environment access belongs to the application adapter. The release constructor accepts an explicit site origin and never reads process.env or import.meta.env.
  • Site-shell navigation may consume the public route contract from the domain entry, but route-generation code must not import presentation components or Astro modules.

Invariants

  • Public application output remains static HTML with no runtime backend.
  • Every generated public HTML page appears exactly once in the production sitemap, while error pages and non-page artifacts remain absent.
  • Core content must remain readable without browser JavaScript.
  • Public HTML pages use the layout-owned Header, Main, and Footer structure instead of composing their own shell.
  • Public Entry content is generated completely into HTML; unknown slugs use the project-level static not-found page.
  • Public Topic Trail content and Entry previews are generated completely into HTML; the browser does not load or reorder trail Entries.
  • Public Changelog content is generated completely into HTML; exact timestamps remain internal ordering data and are not displayed.
  • Export JSON metadata is generated completely into HTML, and its download points to the matching statically generated immutable artifact without runtime fetching.
  • Current and immutable Methodology content is generated by the version-appropriate v1 or v2 projection, with route-specific canonical metadata supplied through the layout.
  • Internal public anchors use route paths on the current origin; canonical metadata, sitemaps, exports, and release records retain absolute URLs.
  • UI code may depend on the domain entry; domain code must not depend on presentation modules.
  • Product contracts must come from approved tickets rather than permissive placeholders or inferred fields.
  • Inter Variable remains a pinned build-owned asset with system fallbacks and the role assignments defined by Frontier Atlas.
  • The application remains light-only until a separate ticket supplies a complete approved dark palette and component-state contract.
  • Project commands keep Astro CLI telemetry disabled; the browser has no telemetry, analytics, or persistent client logging.
  • Type-checking, tests, and builds preserve non-zero failure results.
  • Ordinary builds, development starts, page renders, and tests never generate release IDs or timestamps.
  • Clean-runner CI requires the committed descriptor and manifest and must not bootstrap release state.
  • Cloudflare hosting cannot become a dependency of page rendering or domain validation.
  • Retype deployment remains separate from the application hosting target.

Implementation Landmarks

  • playwright.hosted.config.ts - Hosted entry point over the shared browser projects without a local server.
  • astro.config.ts — Static application configuration.
  • src/domain/ — Framework-independent domain boundary.
  • src/adapters/ — Read-only filesystem loading and application configuration boundaries.
  • src/adapters/production-sitemap-artifact/ — Final-output sitemap, public-page, production-origin, and robots.txt verification boundary.
  • src/adapters/dataset-artifact-writer/ — Injected immutable dataset filesystem emission.
  • src/adapters/application-export/ — Dataset preparation, determinism checks, and Export Page presentation model.
  • src/release/stage-one-release/ — Atomic Stage 1 orchestration, staged verification, manifests, redirects, and promotion.
  • scripts/release/ — Thin release inspection, synchronization, reproduction, successor-creation, and process-exit entry points.
  • scripts/deployment/ — Pages preview preparation, production sitemap verification, and production artifact preflight.
  • .github/workflows/validate-application.yml — Read-only application and browser validation.
  • .github/workflows/deploy-application.yml — Manual production build and Pages publication.
  • wrangler.jsonc — Static Pages output configuration without Worker or Function bindings.
  • scripts/test/ — Disposable browser-output preparation and the release-owned Wrangler/Playwright runner.
  • playwright.config.ts, playwright.release.config.ts, and tests/browser/playwright-config.ts — Shared project settings with ordinary and release-specific server ownership.
  • src/shared/release-logger/ — Release-only colored terminal and rotating file logs.
  • src/pages/ and src/layouts/ — Astro-owned page and document rendering boundary.
  • src/components/site-shell/ — Shared Header, Footer, navigation model, and progressive enhancement.
  • src/components/entry-preview/ — Reusable static Entry projection and presentation boundary.
  • src/features/homepage/ — Stage 1 Homepage selection and rendering boundary.
  • src/features/about-page/ — Stage 1 About projection, preview fallback, rendering, and responsive composition boundary.
  • src/features/changelog-page/ — Material-event projection, date grouping, static rendering, and responsive composition boundary.
  • src/features/entry-page/ — Complete public Entry projection and rendering boundary.
  • src/features/methodology-page/ — Canonical Methodology projection and public rulebook rendering boundary.
  • src/features/topic-trail-page/ — Topic Trail projection, private-preview fallback, static list rendering, and responsive composition boundary.
  • src/features/export-page/ — Export JSON record sheet, field index, limits, and responsive composition boundary.
  • src/pages/entries/[slug].astro and src/pages/404.astro — Thin static Entry routing and generic not-found entry points.
  • src/pages/methodology/ — Thin current and immutable Methodology route entry points.
  • src/pages/changelog/ — Thin static Changelog route entry point.
  • src/pages/export/ and src/pages/datasets/releases/ — Thin Export JSON page and immutable artifact entry points.
  • src/pages/topic-trails/ — Thin generated Topic Trail route entry point.
  • src/shared/canonical-markdown/ and src/shared/entry-markdown/ — Shared safe rendering core and Entry-specific Markdown APIs.
  • src/shared/public-navigation/ — Same-site internal link projection from validated canonical URLs.
  • src/pages/schemas/, public/_headers, and public/robots.txt — Static Dataset Schema publication, hosting metadata, and sitemap discovery.
  • src/styles/ — Frontier Atlas tokens, base styles, type roles, layouts, components, and the global stylesheet entry point.
  • tests/foundation/ — Architecture checks.
  • tests/domain/ — Canonical record and validation checks.
  • tests/browser/ — Cross-page journeys, routes, responsive behavior, accessibility, keyboard, no-JavaScript, reduced-motion, and download checks.
  • scripts/dev/setup-and-run.ps1 — Windows setup and launch workflow.

Before Changing the Foundation

Check:

  • Whether a dependency would introduce a UI framework, runtime service, or external content dependency.
  • Whether a presentation change preserves the Frontier Atlas ownership boundary and accessibility invariants.
  • Whether a page or layout change preserves the Stage 1 Site Shell order, navigation, and no-JavaScript behavior.
  • Whether an Entry list integration preserves the Entry Preview projection and sequence while using only its approved host options.
  • Whether Entry route changes preserve the Stage 1 Entry Page release boundary, static generation, and genuine not-found response.
  • Whether Methodology route changes preserve version-aware v1/v2 projection, every retained immutable version, correct canonical metadata, and generic 404 behavior for unknown versions.
  • Whether Changelog route changes preserve release-owned material-event ordering, derived date grouping, canonical metadata, and complete static output.
  • Whether Topic Trail route changes preserve release-owned path generation, non-empty production data, canonical metadata, and generic 404 behavior for unknown slugs.
  • Whether a domain import points toward Astro or another presentation module.
  • Whether new browser JavaScript is genuine progressive enhancement.
  • Whether a data location mixes canonical, immutable, generated-release, or static-build concerns.
  • Whether Schema publication still uses the shared generator and a validated configured origin.
  • Whether Export JSON page metadata and endpoint bytes still come from one prepared application export and one selected release.
  • Whether root tooling changes also require launcher, lockfile, Vitest, or Playwright updates.
  • Whether build or route changes preserve exact sitemap coverage, the production origin, error-page exclusion, and the robots.txt sitemap directive.
  • Whether a production-release change belongs to Repeatable Release Publication rather than the ordinary Astro foundation.
  • Whether a hosting or artifact-transfer change belongs to Cloudflare Pages Deployment.
  • Whether hosted browser behavior belongs to Hosted Release Verification rather than the ordinary local test command.
  • Whether the Retype project is being changed intentionally rather than as a side effect of application work.

See the Quickstart for the commands used to run and validate the project.