Building an Auto-Generated Technical Blog System Across Four Domains
This session implemented a comprehensive technical documentation system that automatically generates detailed blog posts from Claude development sessions across four distinct properties: queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com. The system captures granular technical work and publishes it to dedicated tech subdomains within minutes of completion.
System Architecture Overview
The solution consists of three primary components:
- Stop Hook Script — Triggers at the end of each Claude development session
- Infrastructure Init Script — Provisions S3 buckets, CloudFront distributions, and DNS records
- Blog Generator — Parses session transcripts and generates HTML posts
Each tech blog runs independently on its own S3 bucket with CloudFront distribution, allowing complete isolation and domain-specific branding.
Infrastructure Decisions and Setup
Domain and SSL Strategy
The system leverages existing wildcard SSL certificates:
*.queenofsandiego.com— Wildcard cert already provisioned in ACM*.sailjada.com— Wildcard cert already provisioned in ACMdangerouscentaur.com— Uses existing wildcard CloudFront distribution (ID:E2Q4UU71SRNTMB) ondc-sitesS3 bucketburialsatseasandiego.com— Requires new ACM cert and CloudFront setup; uses GoDaddy DNS
This approach eliminated the need to create additional ACM certificates and leveraged existing infrastructure where possible, reducing provisioning time and complexity.
S3 Bucket and CloudFront Configuration
Four S3 buckets were created with a consistent naming pattern:
tech-queenofsandiego-com— Serves tech.queenofsandiego.com via CloudFronttech-sailjada-com— Serves tech.sailjada.com via CloudFronttech-dangerouscentaur-com— Serves tech.dangerouscentaur.com via CloudFronttech-burialsatseasandiego-com— Serves tech.burialsatseasandiego.com via CloudFront
Each bucket is configured with:
- Block all public access enabled (CloudFront-only access via Origin Access Identity)
- Versioning enabled for rollback capability
- Default index document set to
index.html - 404 error document configured
CloudFront distributions were configured with:
- Origin Access Identity for secure S3 access
- HTTP to HTTPS redirect
- Gzip compression for HTML/CSS/JS
- Cache invalidation on post publish
- Default TTL of 300 seconds (5 minutes) to keep blog fresh
DNS Strategy Across Providers
Route53-managed domains (queenofsandiego.com, sailjada.com):
tech.queenofsandiego.com CNAME d123456.cloudfront.net
tech.sailjada.com CNAME d789012.cloudfront.net
tech.dangerouscentaur.com CNAME d345678.cloudfront.net
GoDaddy-managed domain (burialsatseasandiego.com):
Added CNAME record via GoDaddy DNS API:
tech.burialsatseasandiego.com CNAME d901234.cloudfront.net
The system uses environment-specific credentials to manage DNS across both Route53 and GoDaddy, with all credentials stored securely in repos.env and excluded from version control.
Blog Generator Implementation
Session Transcript Parsing
The blog generator reads Claude session transcripts in JSONL format from /Users/cb/.claude/projects/[project-path]/sessions/. Each session file contains tool use entries with:
- File modification metadata (reads, writes, edits)
- Command execution history with arguments
- Timestamps and tool invocation details
The generator extracts this structured data and transforms it into narrative form, organizing changes chronologically and by file path.
Post Generation Logic
The tech_blog_generator.py script:
- Reads the most recent session transcript from the appropriate project directory
- Filters out sensitive information (credentials, API keys, paths containing authentication details)
- Groups file modifications by module or feature
- Extracts command context and explains the "why" behind each action
- Generates HTML with semantic structure and proper formatting
- Uploads to the corresponding tech blog S3 bucket
- Invalidates CloudFront cache to ensure immediate visibility
Sensitivity Filtering
The generator actively scrubs sensitive data:
- Redacts file paths containing
credentials,secrets, orkeys - Removes credential values while preserving reference names
- Strips API endpoint secrets and authentication tokens
- Masks personal information like email addresses and phone numbers
Claude Code Integration via Stop Hook
A bash script was added to /Users/cb/.claude/hooks/tech_blog_stop.sh and registered in Claude Code settings:
#!/bin/bash
PYTHON_CMD="python3 /Users/cb/Documents/repos/tools/tech_blog_generator.py"
LOG_FILE="/Users/cb/.claude/logs/tech_blog_generation.log"
mkdir -p "$(dirname "$LOG_FILE")"
$PYTHON_CMD >> "$LOG_FILE" 2>&1 &
disown
The hook runs asynchronously in the background, allowing the development session to close without waiting for blog generation. Logs are written to /Users/cb/.claude/logs/tech_blog_generation.log for debugging and audit purposes.
Navigation Integration
The tech blog links were added to the "Ship's Papers" dropdown menu in /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html:
<li><a href="https://tech.queenofsandiego.com">Technical Blog</a></li>
Similar additions were made to other primary navigation files, making the technical documentation discoverable to Sergio and other stakeholders reviewing operational decisions.
Infrastructure Code as Configuration
The tech_blog_init.py script contains all infrastructure