Skip to content
GRPNR.

00 — SYNTHESIS: Showcase Website Stack + Repo Setup

2026-07-19. oh-architecture run (ultra mode: 8-agent research fan-out + 4-candidate adversarial court, 24 agents total). Decision doc — readable standalone; doubles as the ADR.

Decision: Candidate B — Astro 7 + Tailwind v4, bespoke curated product pages over a content-layer view of plans/ + research/. Matrix score 4.10, winner robust under sensitivity shifts. Runner-up: VitePress 1.6.4 (3.40). Quartz v5 (2.90) and Next 16 export (2.75) rejected.

1. Question + scope

Which stack and markdown→site pipeline should the internal showcase website use, optimized for the speed at which Claude Code agents author new, distinctive product pages — and how is this repo set up around it? In scope: stack, content pipeline, curation/confidentiality mechanism, serving, repo conventions. Out of scope: the factory products themselves, auth, cloud hosting (one-paragraph forward path only).

2. The evidence that shaped the decision

  1. The corpus is not Obsidian-shaped. 86 md files, ~13.9k lines: zero real wikilinks, zero callouts, 43 mermaid fences, heavy GFM tables (01-deep-dive §2). This deleted Quartz’s and VitePress’s headline advantages before the court convened — the fidelity requirement is GFM + mermaid, which everything can meet.
  2. The best agent-authoring evidence points at exactly one lane. The only detailed field report of the target workload (agent-built showcase site, 85 pages, ~80% agent-carried) is Astro + Tailwind + locked design tokens; Astro 7.0 shipped astro dev --background + JSON logs explicitly for AI agents (02-case-studies; first-party).
  3. Slop is a prompting problem, not a stack problem (convergent, 02-case-studies §1) — so the design-ceiling criterion rewards the stack with no theme to fight (Astro bespoke) and penalizes wiki/docs chrome (Quartz, VitePress default).
  4. Silent failure classes disqualify, loud ones don’t. Next 16: getServerSideProps silently ignored + stale caching priors (documented). VitePress: md compiled as Vue templates — a fence-aware scan found 14 bare pseudo-tags in 3 existing corpus files that throw day-one compile errors pointing at generated SFC output, not the source line (04-steelman D-prosecution — empirical, this repo). Astro’s enumerated drift zones all fail at build time; its one silent mode (Sätteri pipeline regression → mermaid renders as code blocks) is closed structurally (§5 risk 1).

3. Decision matrix

Weights per the stated optimization target. Scores 1–5, grounded in 01–04 (citations there).

Criterion Wt A Quartz v5 B Astro 7 C Next 16 D VitePress
Agent-authoring throughput (new pages) 20% 2 4 3 3
Agentic familiarity + failure legibility 20% 2 4 2 3
Design ceiling (anti-template rule) 15% 2 5 5 3
Simplicity / ops surface 15% 2 3 1 4
Time-to-first-value 15% 5 4 2 4
Corpus fidelity (GFM + 43 mermaid) 10% 5 5 3 4
Evolution path / exit cost 5% 5 4 5 3
Weighted 2.90 4.10 2.75 3.40

Score rationales (compressed): A pays the zero-training-data v5 tax exactly on the graded deliverable (bespoke pages) and carries a fork-as-app upstream with no tags; C is maximum ops for a brochure with priors that actively fight export mode; D loses the graded loop to off-stack Vue in the zero-evidence quadrant plus the template-compile hazard; B’s drift zones are enumerated, pinnable, and loud.

Sensitivity. Winner survives: doubling TTFV at throughput’s expense (A→~3.35, B→~4.0); zeroing design ceiling entirely (B still leads on throughput+familiarity); pricing familiarity as raw training mass (C rises but its silent-failure class caps legibility). The only flip is a scope change, not a weight shift: if the site were pure vault-publish with no bespoke product pages, A/D win — Robert already rejected that scope (“awesome webpages for the products”).

4. The winning architecture

flowchart LR
  subgraph CONTENT["content plane (untouched masters)"]
    P["plans/NNN-*/**.md"]
    R["research/*.md"]
    X["analysis/legacy/SYNTHESIS.md, docs/llm-runs.md"]
  end

  subgraph SITE["site/ (Astro 7, presentation plane)"]
    CL["Content Layer glob() base ../plans, ../research<br/>ALLOWLIST curation config (fail-closed)"]
    MD["@astrojs/markdown-remark pipeline (pinned)<br/>+ remark-gfm + astro-mermaid"]
    TW["Tailwind v4 (@tailwindcss/vite)<br/>DESIGN.md-locked tokens"]
    PAGES["index (program) · /products/x bespoke .astro<br/>/library/* auto-rendered corpus"]
  end

  CONTENT --> CL --> MD --> PAGES
  TW --> PAGES
  PAGES --> DIST["static dist/"]
  DIST --> SERVE["python3 -m http.server / systemd --user<br/>later: CF Access or Tailscale for Tomas"]

Boundaries: content plane = existing markdown, never moved, never converted (exit cost = delete site/). Curation layer = explicit allowlist in the collection config — confidential paths (analysis/monorepo-development/, research/11-*, research/14-*, repos/) are simply never included; fail-closed by construction, not by exclude-glob discipline (adopted from A/D prosecutions). Presentation plane = site/, the only throwaway.

Version pins (all VERIFIED active 2026-07-19): astro@7.1, @astrojs/markdown-remark, astro-mermaid@2.1, tailwindcss@4 via npx astro add tailwind. Exact versions in lockfile; upgrades are deliberate events, never side effects.

5. Risk register (winner’s prosecution, absorbed)

# Risk Containment
1 Sätteri silent regression — mermaid fences render as inert code blocks, no error Structural, not prompt discipline: canary page with a mermaid fence + table; build script = astro build && grep -q '<svg' dist/canary/index.html — pipeline regression becomes a hard build failure. Wired before the first real page.
2 Astro-7 newness — glob base:'../' dev-watch unverified on v7 Verify in hour one; fallback = dev-server restart on md edits (acceptable) or a 5-line copy-sync script. Build path is verified regardless.
3 Tailwind v4 setup drift (loudest documented 2025 agent failure) Setup happens once via official astro add tailwind, then frozen in repo + lockfile; executors author pages, never re-scaffold; rules pin in CLAUDE.md.
4 Agents emit Astro-4/5 idioms (deprecated @astrojs/tailwind, legacy collections) All fail loud at build; enumerated as CLAUDE.md pins; main-branch-only means drift can’t hide on a branch.
5 Annual major churn (documented Astro pattern) Pin exact versions; upgrade = deliberate maintenance event with the canary build as the gate.
6 Slop despite stack DESIGN.md tokens locked BEFORE first page (the field report’s named success factor); every page passes the impeccable/frontend-design gate; anti-template rule ported into rules/.

6. First implementation steps (test-first)

  1. Canary first: site/ scaffold (pnpm create astro minimal) + pipeline pins; add src/content/canary.md (mermaid fence + GFM table + frontmatter) and the grep-canary build script. Red until the pipeline is right, green forever after — this is the site’s regression test.
  2. Content config: allowlist collections over ../plans + ../research; /library/[...slug] renders the corpus. Acceptance: all 86 files render, 43 mermaid fences emit <svg>, zero dead links (link-check script).
  3. DESIGN.md: locked tokens (palette, type pairing, spacing, radius, motion) chosen per the anti-template rule — before any product page exists.
  4. First product page: /products/fleet-monitor composed from plans/004-fleet-monitor entries, through the impeccable gate. This page sets the pattern the other four copy.
  5. Serving: python3 -m http.server -d site/dist 4173 now; systemd --user unit when it becomes daily-driver; CF Access/Tailscale decision deferred until Tomas needs it.

7. Repo setup (executed with this decision)

git repo on main (init 2026-07-19; remote eletrixa/groupon-refactor private, added by a parallel session — push on request only), .gitignore excludes repos/ (confidential clones) + build artifacts; rules/ ported from the vault per the Astro column of 01-deep-dive §5 (~25 files incl. web/design-quality.md anti-template policy, astro/framework-conventions.md, file-headers + security pinned); CLAUDE.md pins required rules via @rules/..., states main-branch-only, the allowlist-curation rule, and the Astro-drift pin list. Plans numbering note: 002- is duplicated by two parallel-session folders — renumbering deferred until those sessions are idle (one-sweep rule, tools/plans.md).

8. Files

Doc Content
01-deep-dive.md Corpus ground truth, candidate tech facts, serving/repo facts, rules-port table
02-case-studies.md Agentic-era experience + classic case studies + evidence gaps
03-options.md The 4 candidates with diagrams, boundaries, test seams, costs
04-steelman.md Full court record: advocate/prosecution/cross-exam per candidate

Flip status: draftactive in README.md when the decision is accepted.