Building an Automated Technical Blog System Across Four Multi-Domain Properties
Today's session focused on architecting and implementing an automated technical documentation system that captures development work across four separate website properties in real-time, generating granular technical blog posts automatically as work completes. This required coordination of infrastructure, CI/CD hooks, cloud resources, and DNS configuration across multiple cloud providers.
The Problem: Knowledge Silos and Manual Documentation
Previously, technical work on queenofsandiego.com, dangerouscentaur.com, sailjada.com, and burialsatseasandiego.com existed without a systematic way to document what was being built. This creates challenges for stakeholders (like Sergio) who need visibility into implementation details, architecture decisions, and technical progress. The goal was to build a system that automatically generates detailed, granular technical blog posts immediately when work completes—without manual intervention.
Architecture Overview
The solution involves four main components:
- Session Capture: Claude Code hook intercepts development session transcripts
- Content Generation: Python script analyzes session JSONL data and generates technical blog posts
- Static Hosting: Four separate S3 buckets + CloudFront distributions serve tech blogs
- DNS & Navigation: Wildcard subdomains configured; Ship's Papers menus updated to link tech blogs
Infrastructure Setup
S3 & CloudFront Resources Created
Four new S3 buckets were created to host the technical blogs:
qos-tech-blog→ serves tech.queenofsandiego.comjada-tech-blog→ serves tech.sailjada.comdc-tech-blog→ serves tech.dangerouscentaur.combats-tech-blog→ serves tech.burialsatseasandiego.com
CloudFront distributions were provisioned with appropriate origins, caching behaviors, and compression settings. Three distributions leverage existing wildcard ACM certificates:
*.queenofsandiego.comwildcard cert (existing)*.sailjada.comwildcard cert (existing)dangerouscentaur.comwildcard distribution (E2Q4UU71SRNTMB) reused for tech subdomain via CNAME
For burialsatseasandiego.com, which uses GoDaddy nameservers (not Route53), a new ACM certificate request was initiated and DNS validation records were added to GoDaddy's control panel.
DNS Configuration
Route53 hosted zones for queenofsandiego.com and sailjada.com received new A records (alias records pointing to CloudFront distributions). For dangerouscentaur.com, a CNAME record was created in the existing Namecheap configuration. GoDaddy DNS for burialsatseasandiego.com received ACM validation records and will receive a CNAME for the CloudFront distribution once certificate validation completes.
Session Capture & Blog Generation Pipeline
The Stop Hook: tech_blog_stop.sh
A new Claude Code hook was registered at /Users/cb/.claude/hooks/tech_blog_stop.sh that executes when a development session ends. This shell script:
- Reads the session transcript in JSONL format from Claude Code's session directory
- Invokes the Python blog generator with the transcript path
- Captures stdout (generated HTML) and uploads to the appropriate S3 bucket
- Logs all activity to
/Users/cb/.logs/tech_blog_generation.log
The hook was registered in Claude Code settings at /Users/cb/.claude/settings.json under the onSessionStop configuration.
The Blog Generator: tech_blog_generator.py
This Python script performs the heavy lifting:
- Input: Session transcript (JSONL file containing tool use, code writes, command outputs)
- Parsing: Extracts all tool_use blocks (file modifications, AWS CLI operations, etc.)
- Filtering: Removes sensitive data (credentials, API keys, passwords) using regex patterns
- Categorization: Groups changes by domain (QOS, Jada, DC, BATS) using file path patterns
- HTML Generation: Constructs a detailed, granular technical blog post with sections for each major change
- Output: Returns sanitized HTML suitable for static hosting
The script implements a content filtering layer that redacts common credential patterns while preserving technical details like S3 bucket names, CloudFront distribution IDs, Route53 hosted zone operations, and code logic.
Infrastructure Initialization: tech_blog_init.py
A companion script handles initial setup and teardown of the blog infrastructure. It:
- Creates S3 buckets with versioning and public-read policies
- Provisions CloudFront distributions with appropriate origins and behaviors
- Creates Route53 or third-party DNS records
- Validates ACM certificates via DNS CNAME records
- Saves infrastructure configuration to a JSON state file for future reference
Navigation Integration
The Ship's Papers menu structure across all four main websites was updated to include links to the technical blogs. These appear as a new section, allowing visitors (particularly stakeholders like Sergio) to drill into the detailed technical work being performed.
Key Design Decisions
Why Automated Generation?
Manual blog posts create friction and get deprioritized. By hooking into the development workflow itself (session stop), documentation happens automatically and immediately. The granularity emerges naturally from the session transcript—every file write, AWS operation, and command is captured.
Why Separate S3/CloudFront per Domain?
Keeping infrastructure segregated by domain maintains clean separation of concerns, enables per-domain access controls, and allows independent scaling or migration of each tech blog if needed.
Why Route53 + Third-Party DNS Mix?
Three domains (QOS, Jada, BATS via Jada account) live in Route53 for centralized management. Dangerouscentaur and burialsatseasandiego required working within existing third-party DNS providers, necessitating CNAME configuration in Namecheap and GoDaddy respectively.
Credential Filtering Strategy
Rather than trying to prevent credentials from being captured (impossible—they might appear in command output), the blog generator actively filters them out using regex patterns for common credential formats. This allows technical details to flow while protecting secrets.
Testing & Validation
The system was validated with a dry-run on this actual session transcript, generating a technical blog post about itself—a self-referential validation that the infrastructure setup, blog generation, and content filtering all work correctly. HTTP access to all three live tech blogs (QOS, Jada, DC) was confirmed, and CloudFront cache invalidations were performed to ensure fresh content.