Skip to content

[RFC] Upgrade to Astro 7 and formalize production/non-production builds #185

Description

@jubalm

Summary

Evaluate and sequence an upgrade from Astro 5 to Astro 7, refresh coupled dependencies, and formalize the site's existing production/non-production distinction.

The production artifact remains a static GitHub Pages site served at augur.net. Local development uses the non-production view. The existing Cloudflare runtime remains an optional non-production capability for cases where request-time behavior or dynamic data cannot be represented adequately by the static build.

This issue is an RFC and proposed roadmap. It does not authorize implementation by itself. After review, approved milestones and implementation issues will be created from it.

Current state

The site currently uses:

  • Astro 5.18.2
  • React 19
  • Tailwind 4
  • Vite 7 through a package override
  • Legacy Blog, Learn, and whitepaper-v2 content collections
  • MDX and Markdown processing with custom remark/rehype plugins
  • Published whitepaper HTML, raw Markdown, figure, and machine-discovery routes
  • Generated fork-risk and REP supply data
  • Static GitHub Pages production output
  • An optional Cloudflare server-mode configuration for local/preview use

The current baseline passes:

  • dependency installation
  • Astro checking
  • linting
  • script typechecking
  • existing test suites
  • GitHub Pages static build
  • current Cloudflare server-mode build

The production workflow now also generates REP supply endpoints alongside fork-risk data before assembling the site artifact. These generated outputs and their artifact handoffs must be included in the migration safety rails.

The static build currently generates 41 pages.

A dependency audit reported 21 findings: 12 high, 7 moderate, and 2 low. Many originate in Astro, Vite, and Cloudflare dependency chains. Some findings may remain after the framework upgrade and will require separate review.

Why consider Astro 7

The primary motivations are maintenance, security, and toolchain currency. This is not expected to produce a major visitor-facing feature or performance change.

An initial disposable Astro 7 migration probe against the pre-whitepaper tree confirmed that the earlier site could build successfully on Astro 7 after coordinated application changes. Current main has since added the whitepaper publication and REP supply systems. A current-tree probe identified additional migration work in those surfaces, so the complete current site should not yet be considered proven on Astro 7.

  • All three legacy content collections must move to Content Layer loaders.
  • Collection consumers must migrate from entry.slug to entry.id.
  • Entry rendering must migrate from entry.render() to render(entry).
  • Whitepaper sorting, navigation, raw-source routes, and machine discovery also encode legacy collection identifiers.
  • Whitepaper title extraction currently reads entry.body, which becomes optional in the newer Content Layer entry type and requires explicit handling.
  • The historical Vite 7 override conflicts with Astro 7's Vite 8 requirement.
  • Tailwind's Vite integration must be upgraded with Vite.
  • The latest Cloudflare adapter removes the existing platformProxy configuration.
  • Wrangler's server entrypoint configuration has changed.
  • The expanded optional server build externalizes node:fs and node:path imports used by whitepaper-source and fork-data helpers; compatibility should be checked without elevating Cloudflare into a production requirement.
  • Astro 7's default Markdown processor requires an explicit unified configuration that preserves remark-math, rehype-katex, rehype-whitepaper-links, rehype-heading-icons, and rehype-callouts across the intended Markdown and MDX surfaces.
  • Astro 7 requires Node >=22.12.0.
  • The newer compiler exposed malformed markup in src/features/home/featured-posts.astro.

No migration probe changed the real repository.

Proposed deployment and view contract

The site has two views:

View Primary context Characteristics
Production GitHub Pages / augur.net Static output; no non-production tooling
Non-production Local development Controls, watermark, and future development/review utilities

Cloudflare may also host or run the non-production view when runtime behavior is useful, but it is not part of the required production path or routine release process.

Source of truth

Use a dedicated site-view signal rather than treating the generic GitHub CI signal as a deployment identity:

const isProductionSite = process.env.SITE_VIEW === "production";
const isNonProductionSite = !isProductionSite;

Accepted build contexts are:

Context SITE_VIEW Result
Local development unset or non-production Non-production view
GitHub Pages build production Static production view
Optional Cloudflare runtime non-production Non-production view

Production must be explicit so an unknown build cannot silently present itself as the public site. The GitHub Pages build script and workflow set SITE_VIEW=production; an optional Cloudflare build sets SITE_VIEW=non-production even if invoked from GitHub Actions.

GITHUB_ACTIONS remains available only for CI-specific behavior such as native lint annotations. It must not determine the site view. Issue #136 concerns immutable Actions cache keys rather than view derivation and remains an independent workflow concern.

Non-production tooling

Non-production tools should be layered around the canonical production components rather than changing their layout or structure.

The initial shell should:

  • render only in the non-production view
  • contain the existing fork scenario controls
  • support a visible non-production watermark
  • render outside normal document flow
  • cause no layout shift
  • avoid intercepting pointer events while closed
  • collapse completely
  • provide an obvious return-to-live-data action
  • leave room for future controls without coupling them to production components

More advanced behavior such as dragging, repositioning, or additional stakeholder utilities is follow-up work rather than part of the Astro migration. M1 should implement only the minimum shell needed to host the existing controls and identify the non-production view.

Content processor contract

The migration must preserve the current separation between fidelity-sensitive whitepaper Markdown and editorial Blog/Learn MDX:

Surface Intended processor behavior
whitepaper-v2 Markdown remark-math, rehype-katex, and rehype-whitepaper-links; no heading-icon or callout transformation
Blog and Learn MDX inherited remark-math parsing plus rehype-heading-icons and rehype-callouts; do not broaden KaTeX or whitepaper-link rehype behavior during this migration

M1/M2 tests must include both positive and negative assertions for this matrix. Astro 7 processor configuration must not broaden a plugin to another content surface as an incidental migration effect. Any desired expansion of MDX math or link behavior belongs in a separate post-migration issue.

Cloudflare's role

Cloudflare is retained lightly as an optional non-production runtime.

It may be useful for selectively demonstrating features that rely on request-time behavior or data unavailable to the static production build. It is not being introduced as a mandatory stakeholder-review system.

This RFC does not require:

  • an always-available stakeholder preview
  • automatic pull-request deployments
  • a dedicated preview hostname
  • a Cloudflare Access policy
  • a Cloudflare production deployment
  • a successful remote Cloudflare deployment as a production release gate

The migration should preserve a working local Cloudflare/server-mode build if the adapter remains configured. Whether and when to deploy it can be decided separately based on an actual feature need.

Delivery principles

  1. Verification is introduced before or alongside the behavior it protects.
  2. Every implementation issue leaves the repository in a working state.
  3. The production static path remains authoritative.
  4. Framework-coupled updates are separated from unrelated dependency updates.
  5. Cloudflare compatibility does not drive production architecture.
  6. Documentation and non-runtime tooling follow after application behavior stabilizes.
  7. No blanket dependency update is performed.
  8. Route inventories and generated outputs are produced and compared automatically rather than verified by hand.

Migration coordination window

A repository-wide content freeze is unnecessary, but structural work must not move the same APIs during M2–M3.

Proposed delivery plan

# Proposed milestone Outcome Depends on Exit gate
1 Safety rails and site views Current behavior is protected and the two-view contract is explicit — Astro 5 production and non-production paths pass
2 Astro 7 preparation Content and markup no longer depend on known legacy behavior 1 Existing routes and rendering remain stable on Astro 5
3 Astro 7 toolchain migration Astro and coupled integrations are upgraded together 2 Complete verification passes on Astro 7
4 Dependency hygiene Remaining updates and audit findings are handled independently 3 Each dependency group passes independently
5 Documentation and tooling follow-through Project guidance and developer tooling reflect the accepted architecture 3–4 Documentation and commands match verified behavior

These are proposed planning boundaries. Actual GitHub milestones and child issues will be created only after this RFC is approved.

Milestone 1: Safety rails and site views

Outcome

Consolidate the test structure, pin migration prerequisites, establish deterministic build fixtures, and formalize the production/non-production distinction on Astro 5.

Candidate work

  • Complete Organize shell and footer test coverage #183 first so shell/footer assertions and package test scripts have one durable home.
  • Add an aggregate npm test command for the existing suites.
  • Add a unified local verification command.
  • Pin the future Astro 7 runtime requirement before migration work starts:
    • declare Node >=22.12.0 in package.json;
    • add .nvmrc or the repository's chosen equivalent;
    • make CI select an explicitly compatible Node release rather than an unconstrained 22;
    • fail early for unsupported local versions.
  • Generate the production route inventory from build output and compare it automatically with a reviewed baseline.
  • Add focused built-output smoke checks for:
    • expected production routes
    • RSS output
    • representative Blog and Learn pages
    • whitepaper HTML and raw Markdown representations
    • whitepaper figure routes, /llms.txt, and sitemap filtering
    • custom heading icons and callouts
    • math and whitepaper-link transformations, including negative cross-surface assertions
    • critical generated assets
    • fork-risk and REP supply endpoints
  • Provide deterministic fork-risk and REP supply fixtures for local and CI assembly tests. Local verification must not require live RPC access or secrets.
  • Keep live generation as a separate CI integration concern. Fixture-backed build checks neither depend on nor resolve Fix fork-monitor event cache persistence in GitHub Actions #136's cache-persistence behavior.
  • Derive the view from explicit SITE_VIEW values and test the environment truth table.
  • Expose the derived non-production value to client code.
  • Add explicit production and non-production build commands.
  • Introduce only the minimal non-production shell required for the existing scenario controls and watermark.
  • Add tests for:
    • production exclusion of non-production tooling
    • non-production availability of the tooling
    • scenario reset-to-live behavior
    • closed controls not affecting layout or pointer interaction

Exit criteria

  • Organize shell and footer test coverage #183 is complete and new tests use its consolidated structure.
  • The declared and CI Node versions satisfy >=22.12.0.
  • Existing and aggregate tests pass.
  • Script and application typechecking pass.
  • Lint passes.
  • Production static build passes with SITE_VIEW=production.
  • Non-production development/server build passes with the non-production view.
  • Route inventory comparison is automated and green.
  • Fixture-backed artifact assembly succeeds without network access or secrets.
  • Production output does not expose non-production UI.
  • Non-production controls remain usable without displacing or blocking production elements.
  • Whitepaper and machine-readable representations remain discoverable.
  • Generated fork-risk and REP supply artifacts remain present in the assembled production output.

Milestone 2: Astro 7 preparation

Outcome

Remove application-level migration blockers while the framework remains on Astro 5, limiting the eventual major-version change.

Candidate work

  • Begin only after the migration coordination baseline is regenerated from current main.
  • Fix malformed markup exposed by the newer compiler.
  • Move all three content collections to src/content.config.ts.
  • Add Content Layer glob() loaders for the MDX and Markdown source trees.
  • Migrate collection identifiers from slug to id without changing domain-level edition slugs.
  • Migrate entry rendering to render(entry).
  • Update Learn and whitepaper helpers and their associated tests.
  • Handle the newer optional entry.body type explicitly in whitepaper title extraction.
  • Preserve Blog, Learn, whitepaper, raw Markdown, figure, RSS, homepage, and machine-discovery routes.
  • Add positive and negative assertions for the documented Markdown/MDX processor matrix before changing processor configuration.
  • Regenerate and compare the route/output inventory for every structural PR.

The unified processor configuration changes in M3 rather than being forced onto Astro 5. M2 establishes tests protecting the rendered behavior first.

Exit criteria

  • All Milestone 1 verification remains green on Astro 5.
  • Production route inventory is unchanged unless a separately approved concurrent issue intentionally updates the reviewed baseline.
  • Representative Blog, Learn, and whitepaper output is unchanged.
  • Content ordering and navigation tests pass.
  • Raw Markdown and machine-discovery representations remain stable.
  • Processor matrix tests prove expected transforms are present and excluded transforms remain absent.
  • No known malformed Astro markup remains.

Milestone 3: Astro 7 toolchain migration

Outcome

Upgrade the framework and only the dependencies tightly coupled to it.

Candidate work

  • Re-run a disposable Astro 7 probe against current main at milestone kickoff and update issue scope for any drift.
  • Upgrade Astro to version 7.
  • Upgrade official Astro integrations.
  • Upgrade to Vite 8.
  • Remove or replace the historical Vite 7 override.
  • Upgrade Tailwind and @tailwindcss/vite together.
  • Use the Node >=22.12.0 requirement established in M1.
  • Keep TypeScript 5.9 initially.
  • Configure the unified Markdown processor explicitly while preserving the documented processor matrix.
  • Update the Cloudflare adapter and Wrangler entrypoint configuration if the optional runtime remains enabled.
  • Remove the obsolete platformProxy configuration.
  • Review the optional server bundle's node:fs and node:path usage introduced by source-backed whitepaper and fork-data routes.
  • Preserve the dual TypeScript configuration:
    • application/compiler changes belong in tsconfig.app.json;
    • script/tooling changes belong in tsconfig.scripts.json;
    • the two configurations must not be merged.
  • Resolve compiler and type changes without broad application refactoring.

Exit criteria

  • Clean dependency installation succeeds.
  • All tests pass.
  • tsconfig.app.json application typechecking and tsconfig.scripts.json script typechecking pass independently.
  • Lint passes.
  • Production static build passes.
  • Non-production build passes.
  • Custom Markdown and MDX transformations satisfy the processor matrix.
  • Whitepaper HTML, raw Markdown, figures, and machine-readable discovery remain valid.
  • Production route inventory remains unchanged unless explicitly re-baselined for approved work.
  • If the optional Cloudflare runtime is retained, start the built server locally through Wrangler and successfully request representative production-independent routes, including site HTML, whitepaper HTML, raw Markdown, a figure, and fixture-backed data.
  • No actual Cloudflare deployment is required for milestone completion.

Milestone 4: Dependency hygiene

Outcome

Refresh dependencies unrelated to the Astro major upgrade without obscuring framework migration failures.

Candidate dependency groups

  1. React and React types
  2. Biome and TypeScript-facing tooling
  3. Nanostores, Radix, and UI utilities
  4. Wrangler and optional Cloudflare tooling
  5. Security-specific remediation

Each group should be independently reviewable and run the complete verification gate.

image-size requires separate investigation because the current advisory does not have a newer patched upstream release. Any temporary acceptance must record an owner, rationale, review date, and replacement or mitigation trigger.

TypeScript 7 should remain out of scope until Astro's checking toolchain explicitly supports it.

Exit criteria

  • Every update group passes independently.
  • The dependency audit is rerun after each relevant group.
  • Remaining findings are fixed, replaced, mitigated, or documented.
  • No unrelated application refactor is bundled into dependency changes.

Milestone 5: Documentation and tooling follow-through

Outcome

Update project guidance and developer ergonomics after runtime behavior is stable.

Candidate work

  • Update README.md.
  • Update docs/technical-architecture.md.
  • Document the production/non-production view contract.
  • Describe Cloudflare as an optional non-production runtime.
  • Document production and non-production build commands.
  • Improve local development and troubleshooting instructions.
  • Normalize script names where doing so does not change generated output.
  • Remove stale configuration and comments.
  • Document the accepted dependency/audit policy.
  • Consider dependency automation as separate follow-up work.
  • Record the accepted architecture in project/Folio knowledge.

Any tooling change found to affect application output should move back into the appropriate core milestone.

Exit criteria

  • Documentation matches the verified implementation.
  • Developer commands are exercised successfully.
  • Optional Cloudflare instructions do not imply it is a production requirement.
  • Lasting project knowledge records the accepted decisions.

Risks and mitigations

Regressions discovered too late

Mitigation: Add focused tests and build checks before each migration layer. Run the complete gate after every issue rather than reserving validation for the final milestone.

Content URLs change during Content Layer migration

Mitigation: Maintain an explicit route inventory and update identifier-dependent helper tests before changing collection consumers.

Custom MDX rendering changes under Astro 7

Mitigation: Assert representative callout and heading-icon output before changing processors, then retain the unified processor initially.

Whitepaper publication representations regress

Mitigation: Protect the HTML routes, raw Markdown responses, figure routes, source ordering, navigation, math rendering, link rewriting, and machine-discovery output before migrating collections or processors.

Framework failures are obscured by unrelated updates

Mitigation: Upgrade only Astro-coupled packages in the framework milestone. Handle all other dependencies afterward in small groups.

Cloudflare expands into an unintended production requirement

Mitigation: Keep GitHub Pages as the sole production deployment and treat Cloudflare as an optional non-production runtime with no mandatory deployment workflow.

Non-production tooling interferes with canonical UI

Mitigation: Isolate it in a portal-based shell with no layout participation and controlled pointer interaction.

Out of scope

  • Changing the production host
  • Making Cloudflare a production deployment target
  • Establishing a mandatory stakeholder-preview process
  • New application features
  • A broad visual redesign
  • Porting custom rehype plugins to a new processor without a demonstrated need
  • TypeScript 7 adoption
  • Blanket dependency upgrades
  • Automatic Cloudflare preview infrastructure
  • Advanced positioning or dragging for non-production controls

Review requested

Please review the following decisions:

  • GitHub Pages remains the sole production path.
  • The site has one production and one non-production view.
  • A dedicated SITE_VIEW signal distinguishes deployment view from generic GitHub CI context.
  • Non-production tools are isolated from canonical production components and M1 keeps the shell minimal.
  • Cloudflare remains optional and non-production only.
  • Organize shell and footer test coverage #183 precedes the rest of M1 and feat(rep): source total supply from the live REP contract #168 lands before the baseline or waits until after M3.
  • Structural content work follows the M2–M3 coordination window rather than a repository-wide content freeze.
  • Tests, deterministic fixtures, automatic route inventories, and verification gates are introduced throughout the sequence.
  • The Markdown/MDX processor matrix is preserved without broadening plugin scope.
  • Node >=22.12.0 is pinned in M1 rather than deferred to the framework upgrade.
  • Content migration occurs before the Astro major upgrade.
  • Framework-coupled and unrelated dependency updates remain separate.
  • The optional server runtime receives a local request smoke test if retained.
  • Dual application/script TypeScript configurations remain separate.
  • Documentation and non-runtime tooling follow in a separate milestone.
  • Approved milestones and child issues will be created only after RFC review.

After approval

  1. Incorporate agreed revisions into this issue.
  2. Record an approval/decision comment.
  3. Create the approved GitHub milestones.
  4. Create narrowly scoped implementation issues with explicit verification gates.
  5. Link every derived milestone and issue back to this RFC.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions