Repository navigation
🏛️ Archie: establish ADR governance baseline and tech radar #1164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| 2026-03-30 - Architecture Governance Baseline & Edge-First Directives | ||
| Learning: Standardizing ADR formats with explicit 'Directives for AI Agents' and establishing a Repository Tech Radar prevents AI agent drift across edge runtime constraints (Cloudflare Workers vs Render Node test env) and eliminates redundant dependencies. | ||
| Action: Require all future ADRs to define actionable 'Do' and 'Don't' directives for AI agents and maintain the master index in docs/adr/README.md. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,26 @@ | ||
| # ADR 0001: Cloudflare as production, Render as Jules test env | ||
| # 0001. Cloudflare Workers as Production, Render as Jules Test Environment | ||
|
|
||
| - Status: Accepted | ||
| - Date: 2026-08-24 | ||
| - **Status:** Accepted | ||
| - **Date:** 2026-08-24 | ||
| - **Deciders:** Autonomous Architect (Archie) / Repository Analysis | ||
|
|
||
| ## Context | ||
|
|
||
| The site can build two ways: Cloudflare Workers (static + `@astrojs/cloudflare`) or a Node standalone server when `RENDER=true` (`@astrojs/node`). Prod already runs at https://me.alehar.workers.dev/. We need a clear split so Google Jules can debug against a Node environment without treating that path as a second production or failover. | ||
| The personal portfolio site supports two build paths: Cloudflare Workers (static SSG/SSR via `@astrojs/cloudflare`) and a standalone Node.js server (`@astrojs/node`) triggered when `RENDER=true`. Production runs on Cloudflare Workers (https://me.alehar.workers.dev/). A clear operational separation is required so AI agents (such as Google Jules) can run integration and health checks against a Node environment without treating Render as a production failover or active secondary deployment. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Align both documents with the configured production output.
📍 Affects 2 files
🤖 Prompt for AI Agents |
||
|
|
||
| ## Decision | ||
|
|
||
| Production is Cloudflare Workers only. Render is a test environment for Google Jules (Node server via `render.yaml`). It is not a second prod and not a failover. | ||
| Cloudflare Workers is strictly designated as the sole Production target. Render is strictly an isolated testing and preview environment for AI agent verification (`render.yaml`). Render is neither a production failover nor a secondary hosting target. | ||
|
|
||
| ## Consequences | ||
| ## Consequences & Tradeoffs | ||
|
|
||
| - Ship and operate prod on the Cloudflare Worker (`wrangler.jsonc`, `src/cloudflare-worker.ts`). | ||
| - Keep the Render Node path for Jules debugging only; expect AI/KV and other Workers bindings to be absent or stubbed there (`src/env/cloudflare-workers.node.ts`). | ||
| - Docs and ops language should call Cloudflare production and Render the Jules test env. | ||
| - **Positive:** Eliminates operational confusion regarding dual deployment targets; guarantees Cloudflare Edge environment bindings (`wrangler.jsonc`, KV, AI) remain production authoritative. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Use an unambiguous compound adjective. Write “authoritative for production” or “production-authoritative”, not “production authoritative”. 🧰 Tools🪛 LanguageTool[grammar] ~17-~17: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| - **Negative / Risks:** Node standalone compatibility stubs (`src/env/cloudflare-workers.node.ts`) must be maintained to ensure agent verification passes on Render without Workers native bindings. | ||
| - **Adoption Readiness:** Already implemented across `astro.config.mjs`, `render.yaml`, and `wrangler.jsonc`. | ||
|
|
||
| ## Directives for AI Agents | ||
|
|
||
| - **Do:** Ensure production deployment features and Worker bindings target `@astrojs/cloudflare` and `wrangler.jsonc`. | ||
| - **Do:** Keep Render node mocks/stubs in `src/env/cloudflare-workers.node.ts` updated if Worker binding contracts change. | ||
| - **Don't:** Modify production routing or architectural assumptions to treat Render as a secondary production environment. | ||
| - **Don't:** Remove the `isRender` branching in `astro.config.mjs`. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # 0002. Edge-First Zero-Dependency Architecture & Single-Pass Data Transforms | ||
|
|
||
| - **Status:** Accepted | ||
| - **Date:** 2026-03-30 | ||
| - **Deciders:** Autonomous Architect (Archie) / Repository Analysis | ||
|
|
||
| ## Context | ||
|
|
||
| The personal portfolio operates on Cloudflare Workers edge runtime isolates where memory overhead, GC pauses, subrequest latency, and bundle sizes are critical performance factors. Relying on heavy external runtime utility libraries or executing multi-pass array operations (`.map()`, `.filter()`, `.slice()`, `.flatMap()`) in Edge SSR handlers creates unnecessary dynamic intermediate allocations and increases cold start latency. | ||
|
|
||
| ## Decision | ||
|
|
||
| 1. **Zero-Dependency Utilities:** All backend, math, data transformation, and UI helper functions must be implemented natively in pure TypeScript without adding third-party runtime dependencies. | ||
| 2. **Single-Pass Edge Transforms:** Array processing in Edge SSR helpers (such as visitor changelogs, release summaries, and chat utilities) must utilize single-pass `for...of` loops or reverse-indexed `for` loops rather than chaining dynamic intermediate array allocations. | ||
| 3. **Strict Schema Boundaries:** All untrusted external inputs (Markdown frontmatter, API endpoints, feature flag JSON, user payloads) must be validated using Zod schemas at system boundaries. | ||
|
|
||
| ## Consequences & Tradeoffs | ||
|
|
||
| - **Positive:** Drastically minimizes Cloudflare Worker bundle size, eliminates memory allocation spikes during Edge requests, ensures sub-millisecond SSR execution, and maintains total type safety. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win Use qualified performance language in both governance documents. Single-pass transforms can reduce intermediate array allocations. They do not prove zero allocation or sub-millisecond SSR execution.
📍 Affects 2 files
🤖 Prompt for AI Agents |
||
| - **Negative / Risks:** Developers and AI agents must author bespoke native TypeScript helpers instead of pulling in utility packages (e.g., Lodash, Ramda). | ||
| - **Adoption Readiness:** Fully active across all utilities in `src/utils/` and content loaders in `src/content.config.ts`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🤖 get_repo_knowledge executed:
Length of output: 2900 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- changed ADR context ---'
sed -n '1,80p' docs/adr/0002-edge-first-zero-dependency-architecture.md
printf '%s\n' '--- tracked utility and content files ---'
git ls-files 'src/utils/**' 'src/content.config.ts'
printf '%s\n' '--- utility imports and package references ---'
rg -n --glob 'src/utils/**' --glob 'src/content.config.ts' '^(import|export).*from|require\(|node:|`@astrojs`|zod|npm:|package' src/utils src/content.config.ts || true
printf '%s\n' '--- utility source sizes ---'
wc -l $(git ls-files 'src/utils/**' 'src/content.config.ts')Repository: alehar9320/astro-cloudflare-personal-website Length of output: 5404 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- changed ADR context ---'
sed -n '1,80p' docs/adr/0002-edge-first-zero-dependency-architecture.md
printf '%s\n' '--- tracked utility and content files ---'
git ls-files 'src/utils/**' 'src/content.config.ts'
printf '%s\n' '--- utility imports and package references ---'
rg -n --glob 'src/utils/**' --glob 'src/content.config.ts' '^(import|export).*from|require\(|node:|`@astrojs`|zod|npm:|package' src/utils src/content.config.ts || true
printf '%s\n' '--- utility source sizes ---'
git ls-files 'src/utils/**' 'src/content.config.ts' | xargs wc -lRepository: alehar9320/astro-cloudflare-personal-website Length of output: 5404 🤖 get_repo_knowledge executed:
Length of output: 2963 🏁 Script executed: #!/bin/bash
set -eu
sed -n '1,80p' docs/adr/0002-edge-first-zero-dependency-architecture.md
git ls-files 'src/utils/**' 'src/content.config.ts'Repository: alehar9320/astro-cloudflare-personal-website Length of output: 3011 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- ADR ---'
sed -n '1,100p' docs/adr/0002-edge-first-zero-dependency-architecture.md
printf '%s\n' '--- tracked files ---'
git ls-files 'src/utils/**' 'src/content.config.ts'
printf '%s\n' '--- utility and content source ---'
while IFS= read -r f; do
printf '\n### %s\n' "$f"
sed -n '1,240p' "$f"
done < <(git ls-files 'src/utils/**' 'src/content.config.ts')Repository: alehar9320/astro-cloudflare-personal-website Length of output: 3133 🌐 Web query:
💡 Result: The repository alehar9320/astro-cloudflare-personal-website is a personal project created by Alexander Härenstam [1][2], a Product Manager at IFS [1][3]. The project is built using the Astro framework and is designed for deployment on Cloudflare [1]. Regarding your query about specific file paths, standard Astro projects utilizing Content Collections follow a common directory structure [4]: - src/content.config.ts: This is the standard location for defining content collection schemas using Zod [5][6][4]. It serves as the configuration file where you define the frontmatter structure for your Markdown or MDX files [7][4]. - src/utils/: While not a mandatory folder, this directory is commonly used in Astro projects to house shared helper functions, utility modules, or custom logic that can be imported across components and pages [4]. In the specific repository alehar9320/astro-cloudflare-personal-website, while specific file contents may evolve, the project adheres to typical Astro conventions [1]. If you are exploring the codebase for development purposes, you will generally find the collection definitions in src/content.config.ts and various helper scripts or utilities within src/utils/ [4]. You can explore the repository structure directly at https://github.com/alehar9320/astro-cloudflare-personal-website [1]. Citations:
🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- package dependencies ---'
sed -n '1,180p' package.json
printf '%s\n' '--- content schema ---'
cat -n src/content.config.ts
printf '%s\n' '--- runtime utility imports and array operations ---'
for f in src/utils/*.ts; do
case "$f" in *.test.ts) continue;; esac
printf '\n### %s\n' "$f"
rg -n '^(import|export).*from|require\(|\.(map|filter|slice|flatMap|reduce|sort)\s*\(' "$f" || true
done
printf '%s\n' '--- Zod usage in utilities ---'
rg -n -C 3 '\b(z|zod)\b' src/utils/chat-logic.ts src/utils/github-releases.tsRepository: alehar9320/astro-cloudflare-personal-website Length of output: 10713 Qualify the adoption status.
🤖 Prompt for AI Agents |
||
|
|
||
| ## Directives for AI Agents | ||
|
|
||
| - **Do:** Write math, string parsing, and array utilities natively in pure TypeScript. | ||
| - **Do:** Refactor multi-step array chains (`.map().filter().slice()`) in Edge SSR routines into single-pass `for...of` or indexed loops. | ||
| - **Do:** Strictly validate all external inputs with Zod schemas using `z.infer` for derived types. | ||
| - **Don't:** Introduce third-party npm runtime dependencies for utility or data processing needs. | ||
| - **Don't:** Use `@ts-ignore`, `any`, or unvalidated type assertions on external boundaries. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Architecture Decision Records (ADRs) | ||
|
|
||
| This directory contains the sequential Architecture Decision Records for Alexander Härenstam's personal portfolio repository. These records govern the strategic architecture, framework choices, edge runtime constraints, and AI agent boundaries. | ||
|
|
||
| ## ADR Index | ||
|
|
||
| | ID | Title | Status | Date | | ||
| | :-------------------------------------------------------- | :-------------------------------------------------------------------- | :------- | :--------- | | ||
| | [0001](./0001-cloudflare-production-render-jules.md) | Cloudflare Workers as Production, Render as Jules Test Environment | Accepted | 2026-08-24 | | ||
| | [0002](./0002-edge-first-zero-dependency-architecture.md) | Edge-First Zero-Dependency Architecture & Single-Pass Data Transforms | Accepted | 2026-03-30 | | ||
|
|
||
| ## Structure & Directives | ||
|
|
||
| Each ADR defines explicit **Directives for AI Agents** to ensure human developers and autonomous AI agents maintain repository architectural standards without agent drift or regression. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Repository Tech Radar | ||
|
|
||
| This document maintains ground-truth technology status across four standard rings and four operational quadrants for Alexander Härenstam's personal portfolio repository. | ||
|
|
||
| ## Quadrants & Technology Status | ||
|
|
||
| ### 1. Frameworks & Runtimes | ||
|
|
||
| - **Adopt:** | ||
| - **Astro (v7):** Core web framework using static SSG & Edge SSR adapters (`@astrojs/cloudflare`). | ||
| - **Cloudflare Workers:** Production Edge SSR runtime for zero-cold-start delivery. | ||
| - **TypeScript:** Strict type checking across the entire codebase. | ||
| - **Trial:** | ||
| - **Node.js (v22+):** Used exclusively for Jules test runner / standalone Render preview environment via `@astrojs/node`. | ||
| - **Assess:** | ||
| - **Workers AI:** Cloudflare edge LLM inference for release summarization (`@cf/meta/llama-3.1-8b-instruct-fast`). | ||
| - **Hold:** | ||
| - **React / Vue / Svelte Heavy Hydration:** Avoid introducing framework islands when vanilla JS or Astro components suffice. | ||
|
|
||
| ### 2. Infrastructure & Cloud | ||
|
|
||
| - **Adopt:** | ||
| - **Cloudflare Workers Builds:** Production deployment pipeline (`wrangler.jsonc`). | ||
| - **Cloudflare KV:** Edge key-value caching for release summaries and visit stats. | ||
| - **Trial:** | ||
| - **Render:** Isolated test environment for automated AI agent preview verification (`render.yaml`). | ||
| - **Assess:** | ||
| - **Cloudflare Vectorize:** High-dimensional vector storage for semantic portfolio search. | ||
| - **Hold:** | ||
| - **Traditional VPS / Dedicated Servers:** Production MUST run on Cloudflare Workers edge runtime. | ||
|
|
||
| ### 3. Tooling & AI Workflows | ||
|
|
||
| - **Adopt:** | ||
| - **Vitest:** Native TypeScript test runner for zero-dependency utility and API unit tests. | ||
| - **Prettier & ESLint:** Enforced code formatting and linting pipelines. | ||
| - **Husky & lint-staged:** Git pre-commit hooks for format check enforcement. | ||
| - **PostHog:** Deferred dynamic-import analytics integration (`posthog-js`). | ||
| - **Trial:** | ||
| - **Sentry (@sentry/astro & @sentry/cloudflare):** Application monitoring and error boundary tracing. | ||
| - **Assess:** | ||
| - **Codecov Vite Plugin:** Automated bundle size and test coverage analysis in CI. | ||
| - **Hold:** | ||
| - **Jest / Mocha:** Legacy test runners. Use Vitest exclusively. | ||
|
|
||
| ### 4. Patterns & Architecture | ||
|
|
||
| - **Adopt:** | ||
| - **Vanilla CSS Glassmorphism:** Lightweight, hardware-accelerated 'Northern Lights' aesthetic using Vanilla CSS variables. | ||
| - **Zod Schema Boundaries:** Strict runtime validation for API payloads, frontmatter, and feature flags (`src/content.config.ts`). | ||
| - **Single-Pass Array Traversals:** Zero-allocation `for...of` loops and reverse-indexed loops in Edge SSR functions. | ||
| - **Feature Flags via Content Collections:** Isolated feature toggles (`src/content/flags/config.json`). | ||
| - **Trial:** | ||
| - **DOM MutationObserver State Guarding:** Synchronizing state with `localStorage` while preventing redundant disk write I/O. | ||
| - **Assess:** | ||
| - **Canvas DPR Capping:** Hardware-accelerated canvas micro-interactions capped at DPR <= 2. | ||
| - **Hold:** | ||
| - **Tailwind CSS & Utility Frameworks:** Strictly forbidden. All layout and interactive styling uses Vanilla CSS. | ||
| - **Unvalidated Inputs & `@ts-ignore`:** Banned across all files. | ||
|
|
||
| ## Ring Definitions | ||
|
|
||
| - **Adopt:** High confidence, production-proven in this repo. Default choice for new work. | ||
| - **Trial:** High potential with low risk. Ready for isolated usage in minor features or test environments. | ||
| - **Assess:** Worth tracking and evaluating trade-offs; not yet recommended for active production standard. | ||
| - **Hold:** Phasing out, banned, or proven problematic in our setup. Do not use for new work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Add Tech Radar synchronization to the AI-agent action.
The PR objective requires the ADR index and Tech Radar to stay synchronized. This action names only
docs/adr/README.md. Adddocs/tech-radar.mdand define when technology-ring changes require an update.🤖 Prompt for AI Agents