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
ADR-000
Astro Performance Starter Template Architecture Decisions
Architectural Decision Record for initial Astro performance starter template architecture choices
ADR-001
Preact Island Usage Policy
Guidelines for when and how Preact components and ecosystem libraries can be incorporated within Astro Islands, prioritizing zero-JS by default
ADR-002
Future CSS Tooling Considerations (UnoCSS/Plugins)
A note on potential future exploration of UnoCSS or advanced Tailwind plugins for specific CSS needs
ADR-003
Unified Component Structure and Atomic Design Adherence
Enforces strict Atomic Design hierarchy for all UI components, preventing ad-hoc directory proliferation and maintaining a single organizational system
ADR-004
Optional Design System Tooling for MVP Track
Makes design token build and contrast validation steps optional via environment variable to improve CI/CD performance and developer experience for MVP users
ADR-005
Link Validation Strategy
Build-time link validation using a custom remark plugin to catch broken internal links before deployment with zero runtime overhead
ADR-006
Documentation Review Cadence
Architectural Decision Record for automated documentation review cadence using frontmatter-based review dates and CI enforcement
ADR-007
Reserved
Placeholder preserving ADR numbering sequence. This number was skipped during initial ADR creation and is reserved for future use.
ADR-008
Documentation Sync Strategy
Automated documentation sync from the template repository to a Starlight-based documentation site using GitHub Actions with PR-based review workflow
ADR-009
ClientRouter and View Transitions API Usage
Decision to use Astro's ClientRouter for View Transitions API in BaseLayout, justifying the ~5KB gzipped JavaScript addition against zero-JS philosophy
ADR-010
Social Share URL Generation Utility
Extract social share URL generation into a dedicated utility module for type safety, reusability, and consistent encoding across pages
ADR-011
Dynamic Route Error Handling
Defensive error handling in all dynamic route files with 404 redirects for undefined props and slug mismatches
ADR-012
Blog Performance Optimizations
Build-time performance optimizations for blog pages including single-pass sorting, single-render markdown, and async image decoding
ADR-013
BaseLayout Slot Strategy for Hero and CTA Sections
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.
ADR-014
Index Page Performance Strategy
Performance analysis and optimization decisions for the homepage, including JS hydration strategy, lazy loading, and metric generation.
ADR-015
Projects Page Pagination Strategy
Hybrid pagination approach combining SSR initial load with client-side Load More for optimal UX, SEO, and progressive enhancement
ADR-016
Reserved
Placeholder preserving ADR numbering sequence. This number was skipped during initial ADR creation and is reserved for future use.
ADR-017
Experience Content Collection
Create an experience content collection to manage work history data with type-safe Zod schemas and MDX support for rich descriptions
ADR-018
Contact Page Accessibility Enhancements
Accessibility enhancements for the contact page including decorative emoji hiding, Badge ARIA role corrections, and focus order documentation
ADR-019
Accessibility Patterns and Standards
Consolidated reference for WCAG 2.1 Level AA accessibility patterns including decorative content, focus management, ARIA usage, and color contrast
ADR-020
Page Performance Patterns
Consolidated page performance patterns targeting 95+ Lighthouse scores with minimal JavaScript, covering static pages, blog, and interactive features
ADR-021
Contact Form Progressive Enhancement
Progressive enhancement strategy for the contact form, deferring validation JavaScript from inline script to module for build-time optimization
ADR-022
Error Handling and Logging Strategy
Defines error handling patterns, structured logging, and observability practices
ADR-023
Testing Strategy and Coverage Targets
Defines testing philosophy, coverage targets, and test data management
ADR-024
Live Quality Badges for Performance Transparency
Implementation of live Lighthouse score badges to surface CI results and prove performance claims with zero JavaScript overhead
ADR-025
Tailwind CSS v4 Migration
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.
ADR-026
Font Strategy — Self-Hosted Variable Fonts via @fontsource
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.
ADR-027
Content Collections Schema Design
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.
ADR-028
Prefetch Strategy — @astrojs/prefetch
Documents the decision to include @astrojs/prefetch in the base template, its performance trade-offs, and configuration defaults.
ADR-029
SEO and Metadata Architecture
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.
ADR-030
Image Optimisation Defaults
Documents the non-obvious image optimisation configuration choices in astro.config.mjs — Sharp service, constrained layout, AVIF/WebP output, and the pixel limit rationale.
ADR-031
Preact Over React for Islands
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.
ADR-032
Dark Mode Strategy — Class-Based Toggle, Dark-First Default
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.
ADR-033
Track Consolidation — Progressive Tier Model
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.
ADR-034
Documentation Architecture — Dual-Purpose Docs Strategy
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.
ADR-035
Template Scope Boundary — Code vs Reference Documentation
Establish a clear inclusion policy defining what ships as modifiable template code versus reference documentation, providing a decision framework for evaluating new features.
ADR-036
Layered Constitution for Agent Context
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.
ADR-037
Testing Philosophy and House Rules
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.
ADR-038
Agent Roles and Handoff Patterns
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.
ADR-039
Halt-on-Violation Enforcement
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.
ADR-040
Container API for Component Microtests
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.
ADR-041
Reserved
Placeholder preserving ADR numbering sequence. This number was skipped during ADR creation and is reserved for future use.
ADR-042
Mutation Testing with Stryker
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.
ADR-043
CRAP Score Budgets
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.
ADR-044
Coupling Map
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.
ADR-045
Cross-Tool AGENTS.md as Generated Spine
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.
ADR-046
Security Scanning Pipeline (SAST + Secret Scanning)
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.
ADR-047
Design Tokens v2 — Role-Based Semantic Naming
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.
ADR-048
CSS-Native Motion System
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).
ADR-049
The Showcase Is the Living Style Guide
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.
ADR-050
Type-Safe Environment via astro:env
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.
ADR-051
Content Security Policy Strategy
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.
ADR-052
Script Taxonomy — Cloner-Facing vs Maintainer
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.
ADR-053
Fonts via the Astro 6 Fonts API
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.
ADR-054
Demo persona & brand mascot (Pulci Nella)
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.
ADR-055
Icon System — Lucide-aligned line family, one gradient per view
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.
ADR-056
Projects as replaceable demo portfolio
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.
ADR-057
Per-Image Size Budget Gate
Enforce a per-asset size ceiling on raster images in CI, turning the previously advisory 200KB image budget into a halt-on-violation gate.
ADR-058
Font Preload Budget Gate
Cap the number of preloaded font files per page and enforce it in CI, so over-preloading fonts can't silently regress LCP.
ADR-059
Docs Drift Gate Replaces Push-Sync
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
ADR-060
Showcase Interactive Demo Islands
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.
ADR-061
Dependabot Version-Pin Auto-Sync
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
ADR-062
Pezza Design System Adoption
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.