updated readme with more relevant details, gemini wrote

This commit is contained in:
venus
2026-09-13 22:13:53 -05:00
parent bd6358cf1c
commit 73603bc61b
+198 -91
View File
@@ -1,116 +1,223 @@
# River Rooks | Technical Publication & Systems Architecture Blog # River Rooks | Technical Publication & Systems Architecture Blog
> Developer-centric, high-signal, low-noise personal technical blog and homelab documentation site. > Developer-centric, high-signal, low-noise personal technical publication and systems architecture blog.
Inspired by native terminal environments, modal text editors (Zed, Ghostty), and tiling window managers, this site prioritizes raw performance, keyboard navigability, information density, and structured craftsmanship over generic marketing aesthetics. Inspired by native terminal environments, modal text editors (Zed, Ghostty), and tiling window managers, this site prioritizes raw performance, keyboard navigability, information density, and structured craftsmanship over generic marketing aesthetics.
--- ---
## 1. Architectural Vision & Pillars ## 1. Quickstart: Production Server Deployment
### 1.1 Static Generation via Eleventy (11ty) The production deployment uses a **decoupled container architecture**. The server does not need Node.js, git, or build dependencies—it only pulls the prebuilt engine from the registry and mounts a local folder containing your Markdown posts.
- **Engine:** Fast, pre-rendered static HTML and minimal client-side runtime using **Eleventy** and **Nunjucks (`.njk`)** templates.
- **Performance:** Instant time-to-first-byte (TTFB), zero client-side framework bloat, and pure static asset delivery via high-performance native Node runtime.
- **Syntax Highlighting & Code Blocks:** Terminal-styled code blocks with title bars displaying filenames, language tags, and high-contrast monospace code.
### 1.2 Dynamic Obsidian Publishing Pipeline
- **Seamless Authoring:** Author and edit technical dispatches, CTF write-ups, and homelab notes directly inside an **Obsidian** vault.
- **Custom Ingestion API:** A dedicated server-side endpoint (`POST /api/posts`) accepting markdown payloads and assets, paired with a custom Obsidian plugin for one-click publishing.
- **LiveSync Integration:** Architectural support for syncing notes from a self-hosted Obsidian LiveSync (CouchDB) instance.
- **Content Normalization:** Translates Obsidian wikilinks (`[[slug|Title]]`), callouts (`> [!NOTE]`), and asset references into standard web formats during ingestion and build time.
### 1.3 Strict CSS Isolation & Reusable Templating
- **No Monolithic Inlines:** Replaces repetitive inline `<style>` tags with a modular CSS token and component architecture.
- **Design Tokens:** Centralized CSS custom properties (`--bg-canvas`, `--bg-surface`, `--border-color`, `--accent-cyan`, etc.) for consistent dark-mode native styling.
- **DRY Layouts & Partials:** Reusable Nunjucks components for global navigation (`global-bar`), hero tiles (`hero-tile`), split cards, and article workspace layouts (`article-workspace-grid`).
### 1.4 AI Pair Architect & Pedagogical Explainer
- **Interactive Learning:** The workspace includes customized Antigravity agent configurations (`.agents/` and `AGENTS.md`) that pair-program with the author, architecting solutions while clearly explaining *how* and *why* code is built.
---
## 2. Strict Design Specification
Adhering to the principles in [`sample-designs/design-specification.md`](./sample-designs/design-specification.md):
| Rule | Constraint |
| :--- | :--- |
| **Color Scheme** | Dark-mode native only. Canvas: `#0d0f12`, Surface: `#121417`, Elevated: `#1c1f26`, Borders: `#2b303b`. |
| **Accents** | High-signal terminal accents used sparingly: Cyan (`#00f0ff`), Green (`#00e676`), Amber (`#ffb700`). |
| **Borders & Radius** | Crisp 1px solid borders. Zero to 4px maximum border-radius (sharp corners preferred). |
| **Strict Anti-Patterns** | **NO** glassmorphism (`backdrop-filter`), **NO** drop shadows or glows, **NO** gradients, **NO** spring animations. |
| **Typography** | Monospace for UI & code (`IBM Plex Mono`, `JetBrains Mono`); clean sans-serif for body prose (`Inter`). |
| **Interactivity** | Instant binary hover snaps (no slow fade transitions); high-contrast focus outlines for keyboard navigation. |
---
## 3. Project Directory Map
### 1.1 Server Directory Structure (`~/docker/blog`)
```text ```text
. ~/docker/blog/
├── .agents/ # Antigravity agent configurations & customizations ├── .env # Environment variables (SITE_DOMAIN, etc.)
│ ├── rules/ ├── docker-compose.yml # Production container definition
│ │ └── blog-system.md # Architectural constraints, CSS/template isolation & explainer mode └── posts/ # Your live Markdown articles (.md)
│ └── skills/ ```
│ ├── eleventy-tiling-blog/ # Runbook & recipes for Eleventy builds and component extraction
│ └── obsidian-sync/ # Runbook & API contracts for Obsidian publishing & plugin sync ### 1.2 Production `docker-compose.yml`
├── sample-designs/ # Canonical HTML/CSS prototypes & design specification ```yaml
│ ├── article-tiling-firmware.html services:
│ ├── blog-tiling-lead.html web:
│ ├── design-specification.md image: git.riverrooks.dev/venus/river-rooks-blog:latest
│ └── service-gateway-tiling.html container_name: river_rooks_web
├── src/ # Eleventy source directory (scaffolded in Phase 2) restart: unless-stopped
│ ├── _data/ # Global site metadata, navigation, telemetry data volumes:
│ ├── _includes/ - "./posts:/app/src/posts:ro"
│ │ ├── layouts/ # Base, post, and page templates environment:
│ │ └── partials/ # Global bar, hero tile, card, code box, sidebar - "SITE_DOMAIN=${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env}"
│ ├── assets/ - "SITE_URL=${SITE_URL:-https://${SITE_DOMAIN}}"
│ │ ├── css/ # Modular CSS (tokens, reset, layout, components) - "PORT=${PORT:-8080}"
│ │ └── fonts/ # Self-hosted monospace & prose webfonts - "WATCH=${WATCH:-false}"
│ └── posts/ # Markdown content ingested from Obsidian ports:
├── .eleventy.js # Eleventy configuration, markdown-it plugins, and shortcodes - "${HOST_PORT:-${PORT:-8080}}:${PORT:-8080}"
├── package.json # Project dependencies & build scripts networks:
├── server.js # Native Node static web server & clean-URL router - backend
├── Dockerfile # Node container definition (built & served via npm) labels:
├── docker-compose.yml # Container orchestration (web gateway) - "traefik.enable=true"
└── AGENTS.md # Project-level agent instructions & pair programming guide - "traefik.http.routers.blog.rule=Host(`riverrooks.dev`) || Host(`www.riverrooks.dev`)"
- "traefik.http.routers.blog.entrypoints=websecure"
- "traefik.http.routers.blog.tls.certresolver=basic"
- "traefik.http.services.blog.loadbalancer.server.port=8080"
- "traefik.docker.network=backend"
networks:
backend:
external: true
```
### 1.3 Deployment Commands
```bash
# 1. Pull the prebuilt engine from Gitea registry
docker compose pull
# 2. Launch the container
docker compose up -d
# 3. Verify healthcheck status (transitions to healthy in 3-5 seconds)
docker compose ps
``` ```
--- ---
## 4. Development & Build Roadmap ## 2. Local Development & Verification
- [x] **Phase 1: Foundation & Agent Customizations** All templates, styles, and engine code are developed in this repository (`~/code/blog`).
- Establish `README.md` architectural blueprint.
- Setup `.agents/` workspace rules, skills, and root `AGENTS.md`.
- [ ] **Phase 2: Eleventy Scaffolding & Modularization**
- Initialize Node/npm environment and configure `.eleventy.js`.
- Extract design tokens, layout styles, and components into `src/assets/css/`.
- Build reusable Nunjucks layouts and partials modeled on `sample-designs/`.
- [ ] **Phase 3: Dynamic Obsidian Ingestion & Plugin**
- Implement the server-side note ingestion endpoint (`POST /api/posts`).
- Develop the custom Obsidian plugin for publishing notes and frontmatter.
- Integrate wikilink and callout transformation filters.
- [ ] **Phase 4: Containerization & Deployment**
- Verify static build outputs in `_site/`.
- Update Dockerfile and `docker-compose.yml` for unified production serving.
---
## 5. Development Setup
*(To be initialized during Phase 2)*
### 2.1 Native Node.js Workflow
```bash ```bash
# Install dependencies # Install dependencies
npm install npm install
# Start Eleventy local development server with hot-reload # Run automated test suite (unit tests, filters, server, and docker assertions)
npm test
# Launch Eleventy dev server with hot-reload (binds to http://localhost:8080)
npm run dev npm run dev
# Compile static assets for production # Compile static assets to _site/
npm run build npm run build
# Run via Docker Compose # Start the native static server locally
docker compose up --build npm start
``` ```
### 2.2 Local Docker Compose Workflow
The local `docker-compose.yml` provides sensible defaults (`localhost`, port 8080, and mounts `./src/posts`):
```bash
# Build and run the local container stack
docker compose up -d --build
# View container logs (Eleventy compilation + server output)
docker compose logs -f
# Stop and clean up
docker compose down
```
---
## 3. Push & Update Cycles
Because the system separates the **Engine** (templates/code) from the **Content** (markdown notes), updates follow two distinct paths:
### 3.1 Publishing or Editing Articles (Content Workflow)
When you write a new note or edit an existing article:
1. **Add or update the Markdown file** in `posts/` (e.g. `posts/my-new-post.md`):
```yaml
---
title: "My Article Title"
date: 2026-09-14
tags: ["#systems", "#architecture"]
excerpt: "A short synopsis of the article."
---
# Article Content...
```
2. **Recompile the site:**
```bash
docker compose restart web
```
*Eleventy compiles the mounted markdown in ~150ms and starts serving immediately.*
> [!TIP]
> **Zero-Restart Live Reload:** Set `WATCH=true` in your server's `docker-compose.yml` environment. Eleventy will watch the `posts/` directory in the background. Whenever a note is saved or synced (e.g., from Obsidian), the site automatically updates in memory without running any commands.
### 3.2 Updating Blog Templates, CSS, or Features (Engine Workflow)
When you modify design tokens, Nunjucks templates, server routes, or dependencies:
1. **Develop and verify locally:**
```bash
npm test
```
2. **Build and push the new engine image to the Gitea container registry:**
```bash
# Build the engine image
docker build -t git.riverrooks.dev/venus/river-rooks-blog:latest .
# Push to Gitea
docker push git.riverrooks.dev/venus/river-rooks-blog:latest
```
3. **Update the production server:**
```bash
docker compose pull
docker compose up -d
```
---
## 4. System Architecture & Structure
### 4.1 High-Level Architecture
```text
┌─────────────────────────────────────────────────────────────┐
│ Dev Machine / Workstation │
│ src/ (templates, CSS, config) + Dockerfile + entrypoint.sh │
└──────────────────────────────┬──────────────────────────────┘
│ docker push
▼
┌─────────────────────────────────────────────────────────────┐
│ Gitea Container Registry (git.riverrooks.dev) │
│ image: venus/river-rooks-blog:latest │
└──────────────────────────────┬──────────────────────────────┘
│ docker pull
▼
┌─────────────────────────────────────────────────────────────┐
│ Production Server │
│ │
│ ~/docker/blog/posts/ ──(volume)──> [ river_rooks_web ] │
│ (Live Markdown Notes) ├── entrypoint.sh │
│ ├── 11ty compiles │
│ Traefik (SSL / Proxy) <──────────── └── server.js (:8080) │
└─────────────────────────────────────────────────────────────┘
```
### 4.2 Key Engine Components
- **`entrypoint.sh`**: Dynamic container entrypoint. Compiles mounted markdown notes with Eleventy on boot, starts optional background file watcher, and spawns `server.js` as PID 1 for clean signal handling.
- **`Dockerfile`**: Minimal `node:22-alpine` container with pre-installed dependencies, baseline static pre-compilation, and baked-in `HEALTHCHECK` querying `http://127.0.0.1:8080/healthz`.
- **`server.js`**: Zero-dependency native Node static web server supporting clean directory URLs, MIME caching, security headers, and the `/healthz` telemetry endpoint.
- **`eleventy.config.js`**: Eleventy 3.x configuration, custom collections (`posts`, `tagList`), markdown-it anchor plugins, and custom date/reading-time filters.
### 4.3 Directory Map
```text
.
├── .agents/ # Antigravity agent configurations & rules
├── sample-designs/ # Design specifications & HTML/CSS prototypes
├── src/ # Blog engine source
│ ├── _data/ # Site metadata & navigation
│ ├── _filters/ # Modular Eleventy filters (date, readingTime, headings)
│ ├── _includes/
│ │ ├── layouts/ # Base & post Nunjucks templates
│ │ └── partials/ # Global bar, hero tile, post cards, code box
│ ├── assets/
│ │ └── css/ # Modular CSS (tokens, reset, layout, components)
│ └── posts/ # Default/fallback markdown posts
├── test/ # Automated test suite (node:test)
├── docker-compose.yml # Local development compose file
├── sample-docker-compose.yml # Production-ready compose template
├── Dockerfile # Production container image definition
├── entrypoint.sh # Container startup & compilation entrypoint
├── server.js # Native Node static HTTP server
├── eleventy.config.js # Eleventy configuration
├── package.json # Project scripts & dependencies
└── README.md # Documentation & runbook
```
---
## 5. Strict Design Specification
All UI components and stylesheets strictly follow [`sample-designs/design-specification.md`](./sample-designs/design-specification.md):
| Rule | Constraint |
| :--- | :--- |
| **Color Scheme** | Dark-mode native only. Canvas: `#0d0f12`, Surface: `#121417`, Elevated: `#1c1f26`, Borders: `#2b303b`. |
| **Accents** | Terminal accents: Cyan (`#00f0ff`), Green (`#00e676`), Amber (`#ffb700`), Red (`#ff5252`). |
| **Borders & Radius** | Crisp 1px solid borders. Zero to 4px maximum border-radius (sharp corners). |
| **Strict Anti-Patterns** | **NO** glassmorphism (`backdrop-filter`), **NO** drop shadows or glows, **NO** gradients, **NO** spring animations. |
| **Typography** | Monospace for UI & code (`IBM Plex Mono`, `JetBrains Mono`); clean sans-serif for body prose (`Inter`). |
| **Interactivity** | Instant binary hover snaps (no slow fade transitions); high-contrast focus outlines for keyboard navigation. |