Architecture Decision Records

Every architectural decision governing this site — what the rule is, the alternatives considered, and why this one won. Halt-on-violation means an agent reads these before proposing a change. Records marked inherited are the founding decisions of the Astro Performance Starter this site is built on; the rest are this site's own.

63 records · numbered ADR-000 onward

  1. ADR-000

    Architectural Decision Record for initial Astro performance starter template architecture choices

  2. ADR-001

    Guidelines for when and how Preact components and ecosystem libraries can be incorporated within Astro Islands, prioritizing zero-JS by default

  3. ADR-002

    A note on potential future exploration of UnoCSS or advanced Tailwind plugins for specific CSS needs

  4. ADR-003

    Enforces strict Atomic Design hierarchy for all UI components, preventing ad-hoc directory proliferation and maintaining a single organizational system

  5. ADR-004

    Makes design token build and contrast validation steps optional via environment variable to improve CI/CD performance and developer experience for MVP users

  6. ADR-005

    Build-time link validation using a custom remark plugin to catch broken internal links before deployment with zero runtime overhead

  7. ADR-006

    Architectural Decision Record for automated documentation review cadence using frontmatter-based review dates and CI enforcement

  8. ADR-007

    Placeholder preserving ADR numbering sequence. This number was skipped during initial ADR creation and is reserved for future use.

  9. ADR-008

    Automated documentation sync from the template repository to a Starlight-based documentation site using GitHub Actions with PR-based review workflow

  10. ADR-009

    Decision to use Astro's ClientRouter for View Transitions API in BaseLayout, justifying the ~5KB gzipped JavaScript addition against zero-JS philosophy

  11. ADR-010

    Extract social share URL generation into a dedicated utility module for type safety, reusability, and consistent encoding across pages

  12. ADR-011

    Defensive error handling in all dynamic route files with 404 redirects for undefined props and slug mismatches

  13. ADR-012

    Build-time performance optimizations for blog pages including single-pass sorting, single-render markdown, and async image decoding

  14. ADR-013

    Defines the approach for handling hero and CTA sections in BaseLayout, choosing single default slot over named slots for maximum flexibility and minimal layout coupling.

  15. ADR-014

    Performance analysis and optimization decisions for the homepage, including JS hydration strategy, lazy loading, and metric generation.

  16. ADR-015

    Hybrid pagination approach combining SSR initial load with client-side Load More for optimal UX, SEO, and progressive enhancement

  17. ADR-016

    Placeholder preserving ADR numbering sequence. This number was skipped during initial ADR creation and is reserved for future use.

  18. ADR-017

    Create an experience content collection to manage work history data with type-safe Zod schemas and MDX support for rich descriptions

  19. ADR-018

    Accessibility enhancements for the contact page including decorative emoji hiding, Badge ARIA role corrections, and focus order documentation

  20. ADR-019

    Consolidated reference for WCAG 2.1 Level AA accessibility patterns including decorative content, focus management, ARIA usage, and color contrast

  21. ADR-020

    Consolidated page performance patterns targeting 95+ Lighthouse scores with minimal JavaScript, covering static pages, blog, and interactive features

  22. ADR-021

    Progressive enhancement strategy for the contact form, deferring validation JavaScript from inline script to module for build-time optimization

  23. ADR-022

    Defines error handling patterns, structured logging, and observability practices

  24. ADR-023

    Defines testing philosophy, coverage targets, and test data management

  25. ADR-024

    Implementation of live Lighthouse score badges to surface CI results and prove performance claims with zero JavaScript overhead

  26. ADR-025

    Documents the completed migration from Tailwind CSS v3 to v4, replacing the tailwind.config.ts + @astrojs/tailwind setup with a CSS-native @theme inline configuration via the @tailwindcss/vite plugin.

  27. ADR-026

    Documents the decision to self-host variable fonts via @fontsource, covering the rationale over Google Fonts, subsetting, and loading strategy. Amended for the v2 design language: Geist as the display face alongside Inter for body text.

  28. ADR-027

    Documents the design decisions behind the five content collections (blog, projects, bio, experience, navigation), their schema fields, storage formats, and the rationale for each choice.

  29. ADR-028

    Documents the decision to include @astrojs/prefetch in the base template, its performance trade-offs, and configuration defaults.

  30. ADR-029

    Documents the decision to extract all <head> metadata into a dedicated Head molecule, the structured data strategy, canonical URL generation, and OG/Twitter card implementation.

  31. ADR-030

    Documents the non-obvious image optimisation configuration choices in astro.config.mjs — Sharp service, constrained layout, AVIF/WebP output, and the pixel limit rationale.

  32. ADR-031

    Documents the decision to use Preact rather than React as the islands framework, covering bundle size rationale, React compat layer, and when users should consider switching.

  33. ADR-032

    Documents the decision to use Tailwind's darkMode: "class" strategy with a small inline script, rather than the CSS-only "media" strategy. Amended for the v2 design language: dark is the default when no preference is stored.

  34. ADR-033

    Replace the dual-track model (MVP vs Showcase) with a single progressive tier system (Foundation, Build, Polish) that simplifies navigation, reduces documentation overhead, and better maps to how users actually consume the template.

  35. ADR-034

    Formalize the dual-purpose documentation strategy where docs serve both as a rendered Starlight site and as in-repo AI assistant context, with explicit partitioning and an AI context contract.

  36. ADR-035

    Establish a clear inclusion policy defining what ships as modifiable template code versus reference documentation, providing a decision framework for evaluating new features.

  37. ADR-036

    Split the monolithic CLAUDE.md into a layered constitution (CLAUDE.md + .claude/engineering.md + .claude/workflow.md + .claude/stack.md) so that halt-on-violation rules, engineering defaults, process guidance, and stack facts each have a single tone and a single update cadence.

  38. ADR-037

    Adopts Uncle Bob's testing principles (TDD discipline, F.I.R.S.T., AAA with single assertion, no conditional assertions) as house rules in the layered constitution. Extends ADR-023 without superseding it.

  39. ADR-038

    Defines a three-pass sequential workflow (Architect → Coder → Reviewer) for non-trivial features in a single Claude session, with explicit role prompts that keep the passes distinct rather than blurring into a single plan-and-build-and-review smear.

  40. ADR-039

    Brings local `pnpm quality:ci` to parity with the CI gate so that a broken test fails the same command locally that it fails in CI, and hardens the language across `CLAUDE.md` and `.claude/*.md` from "verify with" softness to explicit halt-on-violation enforcement.

  41. ADR-040

    Ratifies the choice of Astro's experimental_AstroContainer for unit-testing .astro components, extracts a shared helper at src/components/__tests__/_helpers/container.ts to confine the experimental API surface to one file, and defines the contract for extending to molecules.

  42. ADR-041

    Placeholder preserving ADR numbering sequence. This number was skipped during ADR creation and is reserved for future use.

  43. ADR-042

    Adopts Stryker Mutator (@stryker-mutator/core + vitest-runner) as the test-quality verification layer on top of Vitest coverage. Establishes thresholds at the measured baseline of 81% (well above the 50% break), runs nightly in CI as a tracked metric, and does NOT gate PRs.

  44. ADR-043

    Reserves an ADR slot for CRAP score (Change Risk Anti-Patterns) budgets. Deferred indefinitely — TypeScript tooling for CRAP is immature compared to Clojure/Java. Revisit every six months.

  45. ADR-044

    Reserves an ADR slot for a static "framework coupling map" enumerating which files import from astro:* virtual modules (load-bearing on the framework) versus which are framework-free (utilities, schemas, types). Deferred until the next major Astro upgrade.

  46. ADR-045

    Generate AGENTS.md at the repo root from the layered constitution (CLAUDE.md, .claude/engineering.md, .claude/workflow.md, .claude/stack.md) so every AGENTS.md-aware tool reads the same canonical content as Claude Code, with CI-enforced drift detection.

  47. ADR-046

    Add Semgrep static analysis and gitleaks secret scanning as halt-on-violation CI gates, alongside the existing pnpm audit and Trivy SBOM steps, with a committed gitleaks allowlist for documented false positives.

  48. ADR-047

    Adopts the cold-minimal v2 design language: role-based semantic token names, renamed base palettes, status colours as single light/dark role tokens, and a swappable fontFamily group. Records the rename map and the scale-retention rationale.

  49. ADR-048

    Adopts a seven-technique motion system that is CSS-native, compositor-cheap, and gated behind prefers-reduced-motion. The entire JavaScript surface is one optional client:idle island (the cursor spotlight).

  50. ADR-049

    Evolves the /showcase page into the canonical design-system style guide (System / Color / Type / Motion / Components), built from token-driven specimens so it cannot drift, zero-JS, with how-it-works delegating to it.

  51. ADR-050

    Adopts astro:env (env.schema in astro.config) for the PUBLIC_* surface and reduces the hand-rolled validate-env.ts to the one check astro:env can't make.

  52. ADR-051

    Rejects Astro 6's built-in security.csp for this stack and records the header-based CSP in public/_headers as the deliberate production default.

  53. ADR-052

    Organises package.json scripts into a cloner-facing core and a maintainer group as a documentation convention — grouping and ordering only, never renaming — so the everyday surface is obvious without breaking CI/hooks.

  54. ADR-053

    Supersedes ADR-026. Delivers self-hosted Geist (display) + Inter (body) via Astro 6's native Fonts API with local providers and vendored woff2, adding metric-adjusted fallback faces to cut CLS.

  55. ADR-054

    Adopt Pulci Nella — a reusable Clownware ghost-dev mascot derived from Pulcinella — as the swappable demo identity. Source bio, experience, and blog byline from the existing content collections; forbid fabricated metrics; ship clear "replace me" markers throughout the author surface.

  56. ADR-055

    Adopt a single Lucide-aligned line-icon family rendered through the existing Icon.astro path registry; forbid emoji as UI iconography; preserve the one-gradient-per-view restraint established on /showcase.

  57. ADR-056

    Convert the projects content collection from meta case studies about the template itself to clearly-demo, replaceable case studies in Pulci Nella's voice. Consolidate template marketing into the blog, told once. Forbid fabricated client KPIs in projects content.

  58. ADR-057

    Enforce a per-asset size ceiling on raster images in CI, turning the previously advisory 200KB image budget into a halt-on-violation gate.

  59. ADR-058

    Cap the number of preloaded font files per page and enforce it in CI, so over-preloading fonts can't silently regress LCP.

  60. ADR-059

    Retire the automated docs push-sync to the Starlight documentation repository in favour of independent authoring plus a CI drift gate that fails the docs build when its stack claims diverge from this repository's versions.json

  61. ADR-060

    Sanctions the two Preact islands hydrated on the showcase page (MotionLab and SignalsCounter) as labelled, demo-scoped exceptions to the zero-JS showcase rule, and reconciles ADR-048's description of the cursor spotlight with its actual implementation as a deferred module script rather than an island.

  62. ADR-061

    Give Dependabot PRs a pre-synced version:check and auto-heal the versions.json/versions.yml pins on main after manifest-changing merges, so dependency bots stop failing a gate they can never satisfy

  63. ADR-062

    Records the Pezza rebrand as the binding design language for this site, supersedes the cold-minimal sections of the inherited token, motion, font, and icon ADRs, dims the focus ring on light for 3:1 contrast, and takes ownership of the published ADR route.