Building Multi-Site Automated Technical Blog Infrastructure with Session-Based Generation
This session implemented a comprehensive system to automatically generate granular technical blog posts across four domain properties: queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com. The system captures development work in real-time and publishes detailed technical documentation without manual intervention.
Problem Statement
Previously, there was no centralized way to document technical work across multiple properties. The goal was to create a system that:
- Automatically captures session work from Claude development sessions
- Generates detailed, granular blog posts (not high-level summaries)
- Posts to separate tech subdomains for each property
- Integrates with existing site navigation ("Ship's Papers" menu)
- Strips all credentials and sensitive data automatically
- Requires zero manual intervention after session completion
Architecture Overview
The implementation uses three core components:
- tech_blog_generator.py — Parses Claude session transcripts and generates HTML posts
- tech_blog_init.py — Sets up S3 buckets, CloudFront distributions, and DNS for each tech blog
- tech_blog_stop.sh — Claude Code Stop hook that triggers post generation at session end
The system integrates with Claude Code's hook system. When a development session ends, the Stop hook automatically invokes the generator, which reads the session transcript, extracts technical work, and publishes to the appropriate blog.
Infrastructure Setup
Each tech blog required provisioning four AWS resources:
S3 Buckets
Four buckets were created to serve as CloudFront origins:
qos-tech-blog— origin for tech.queenofsandiego.comjada-tech-blog— origin for tech.sailjada.combats-tech-blog— origin for tech.burialsatseasandiego.comdc-sites— existing wildcard bucket, reconfigured for tech.dangerouscentaur.com
Each bucket was configured with:
- Static website hosting enabled
- Block public access disabled (required for CloudFront access)
- Bucket policy allowing CloudFront origin access identity (OAI) to read objects
CloudFront Distributions
Three new CloudFront distributions were created (dangerouscentaur reused existing E2Q4UU71SRNTMB):
- Distribution for tech.queenofsandiego.com with origin
qos-tech-blog - Distribution for tech.sailjada.com with origin
jada-tech-blog - Distribution for tech.burialsatseasandiego.com with origin
bats-tech-blog
Each distribution was configured with:
- Default root object:
index.html - Viewer protocol policy: redirect HTTP to HTTPS
- Origin access identity for bucket authentication
- Custom SSL certificate (wildcard for queenofsandiego.com and sailjada.com; GoDaddy managed for burialsatseasandiego.com)
DNS Configuration
DNS entries varied by registrar:
- queenofsandiego.com and sailjada.com — Route53 hosted zones. CNAME entries created pointing to CloudFront distribution domain names.
- dangerouscentaur.com — Namecheap DNS. Existing CNAME wildcard configuration reused.
- burialsatseasandiego.com — GoDaddy DNS. ACM certificate validation required CNAME record addition to GoDaddy DNS console before CloudFront could be activated.
Session Transcript Parsing
The tech_blog_generator.py script extracts technical details from Claude session transcripts (stored as JSONL in ~/.claude/projects). The parsing logic:
- Reads tool_use entries from the session transcript (e.g., file reads, command executions)
- Filters for technical operations: file modifications, infrastructure commands, deployments
- Removes sensitive data patterns: AWS credentials, API keys, passwords, tokens
- Extracts command examples and shows exact file paths, bucket names, distribution IDs
- Determines target blog based on which domains/files were modified
- Generates HTML with proper structure: title, sections, code blocks
The generator creates multiple posts if the session touched multiple properties (e.g., work on both queenofsandiego.com and sailjada.com generates two separate posts).
Integration with Ship's Papers Menu
The queenofsandiego.com navigation was updated to include a "Tech Blog" link in the Ship's Papers dropdown menu. The entry points to tech.queenofsandiego.com. Similar navigation updates will be made to other properties' Ship's Papers menus.
The tech blog index page (index.html) on each S3 bucket lists all published posts in reverse chronological order with publication timestamps and brief descriptions.
Credential Scrubbing Strategy
The system implements multiple layers of scrubbing:
- Pattern matching — Regex patterns detect AWS key formats, GoDaddy credentials, API tokens
- Environment variable filtering — Any value from repos.env or AWS_* environment variables is redacted
- Manual memory files — Sensitive reference files (e.g., reference_godaddy_credentials.md) are excluded from transcript parsing
- Output validation — Generated HTML is scanned for password-like strings before uploading to S3
If a credential is accidentally captured, the HTML is not published and a warning is logged to ~/.claude/hooks/tech_blog_stop.log.
Stop Hook Integration
The tech_blog_stop.sh hook is registered in Claude Code settings at ~/.claude/settings.json. When a session ends:
- Claude Code invokes the hook script
- Hook reads the session ID and session directory
- Invokes
tech_blog_generator.pywith the session transcript path - Generator outputs HTML to appropriate S3 buckets
- CloudFront distributions are invalidated to ensure fresh content
- Log entries are written to
~/.claude/hooks/tech_blog_stop.log
The hook logs all actions including which blog received posts, post titles, and any scrubbing warnings.
Key Technical Decisions
- Session-based generation vs. real-time — Posts are