Building Multi-Site Tech Blog Infrastructure with Auto-Generated Session Capture
What Was Done
Created an automated technical blog generation system that captures detailed session work across four websites (queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com) and publishes granular technical posts to corresponding tech subdomains. This system parses Claude session transcripts, extracts file modifications and commands executed, and generates detailed engineering documentation without exposing credentials.
Architecture Overview
The system consists of three primary components:
- Session Capture Hook — A Claude Code Stop hook that runs at session end, capturing the transcript
- Blog Generator — Python script that parses session JSONL transcripts and generates HTML blog posts
- Infrastructure Layer — S3 buckets, CloudFront distributions, and DNS configuration for each tech blog subdomain
Infrastructure Setup
S3 & CloudFront Distribution
Four S3 buckets were created to host the generated blog content:
tech-qos-blog— Static site for tech.queenofsandiego.comtech-jada-blog— Static site for tech.sailjada.comdc-tech-blog— Static site for tech.dangerouscentaur.combats-tech-blog— Static site for tech.burialsatseasandiego.com
CloudFront distributions were provisioned for each, leveraging existing wildcard ACM certificates:
*.queenofsandiego.com— Certificate ARN used for QOS tech blog distribution*.sailjada.com— Certificate ARN used for JADA tech blog distribution*.dangerouscentaur.com— Routed through existing wildcard distribution E2Q4UU71SRNTMB on dc-sites bucket- burialsatseasandiego.com — New certificate created via ACM with DNS validation
DNS Configuration
Domain DNS was configured based on existing registrar setup:
- Route53 Hosted Zones: queenofsandiego.com and sailjada.com — CNAME records created pointing to respective CloudFront distribution domain names
- Namecheap (dangerouscentaur.com): CNAME record added:
tech.dangerouscentaur.com CNAME → d111111abcdef8.cloudfront.net - GoDaddy (burialsatseasandiego.com): ACM certificate DNS validation CNAME added, then A record created pointing to CloudFront distribution
Blog Generator Implementation
Session Transcript Parsing
The generator reads Claude session transcripts stored as JSONL files. Each session file contains an array of interaction objects with the following structure:
{
"type": "tool_use" | "text" | "command",
"path": "/Users/cb/Documents/repos/...",
"action": "Write" | "Edit" | "Read",
"timestamp": "ISO-8601"
}
The parser extracts three categories of session data:
- File Modifications — Paths, actions (Write/Edit), and counts per session
- Commands Executed — User commands run during the session (without sensitive output)
- Infrastructure Changes — AWS resource creation/modification detected from logs
Site Detection Logic
The generator automatically routes posts to the correct tech blog by analyzing file paths:
if "/queenofsandiego.com" in path:
target_site = "queenofsandiego"
elif "/sailjada.com" in path or "jada" in path.lower():
target_site = "sailjada"
elif "/dangerouscentaur" in path or "dc" in path.lower():
target_site = "dangerouscentaur"
elif "/burialsatseasandiego" in path or "bats" in path.lower():
target_site = "burialsatseasandiego"
Sessions touching multiple sites generate multiple posts, each published to its corresponding tech blog.
HTML Generation
Posts are generated with detailed file modification tables, command execution lists, and infrastructure change documentation. The HTML template includes:
- Session metadata (timestamp, duration, number of files changed)
- File modification summary table (path, action, type)
- Command execution log (with credential redaction)
- AWS/Infrastructure changes detected and applied
- Technical decision rationale
Credential & Security Handling
The system implements multiple layers of credential protection:
- Redaction Filters: Regex patterns strip API keys, tokens, passwords, and AWS credentials from command output before HTML generation
- Path Filtering: Sensitive file paths (like
.claude/hooks/containing credentials) are excluded from file modification lists - Template Truncation: Email addresses and personal data are summarized rather than fully displayed
- Source Code Redaction: Environment variables, hardcoded secrets in code, and credential references are replaced with placeholders
Claude Code Settings Integration
The Stop hook was registered in Claude Code settings at ~/.claude/settings.json:
"hooks": {
"stop": "/Users/cb/.claude/hooks/tech_blog_stop.sh"
}
The hook script runs at session end, executing the blog generator and uploading posts to the appropriate S3 bucket before invalidating CloudFront caches.
Navigation Integration
The tech blog link was added to the Ship's Papers menu on queenofsandiego.com's index.html. This dropdown now includes a link to tech.queenofsandiego.com, making session documentation discoverable by stakeholders like Sergio.
Key Technical Decisions
JSONL Transcript Format
Claude sessions are stored as JSONL (JSON Lines) for efficient streaming. This format allows the generator to process sessions incrementally without loading entire transcripts into memory, critical for long sessions with hundreds of interactions.
Multi-Site Routing
Rather than a single centralized blog, each organization has its own tech blog. This allows filtering by site and maintains organizational boundaries while sharing infrastructure patterns across all four properties.
CloudFront Distribution Reuse
The dangerouscentaur.com tech blog was routed through the existing wildcard distribution (E2Q4UU71SRNTMB) on the dc-sites bucket to avoid unnecessary certificate and distribution overhead, reducing operational complexity.
GoDaddy ACM Certificate Integration
burialsatseasandiego.com was the only domain without a pre-existing wildcard certificate. Rather than requesting a wild