Building a Multi-Site Technical Blog System with Auto-Generated Session Transcripts
What Was Done
Created an automated technical blog infrastructure that captures detailed development work across four separate domains—tech.queenofsandiego.com, tech.sailjada.com, tech.dangerouscentaur.com, and tech.burialsatseasandiego.com—with blog posts auto-generated from Claude Code session transcripts. This system provides granular, audit-trail level documentation of all technical work performed, integrated into each domain's Ship's Papers navigation menu.
Architecture Overview
The system consists of three core components:
- Session Capture Hook: A shell script (
/Users/cb/.claude/hooks/tech_blog_stop.sh) that executes at the end of each Claude Code session - Blog Generator: Python script (
/Users/cb/Documents/repos/tools/tech_blog_generator.py) that parses JSONL session transcripts and converts them into HTML posts - Infrastructure Init: Python script (
/Users/cb/Documents/repos/tools/tech_blog_init.py) that provisions S3 buckets, CloudFront distributions, and DNS records for each tech blog domain
Infrastructure Details
S3 and CloudFront Setup
Each tech blog domain has its own S3 bucket configured as a static website origin:
qos-tech-blog→tech.queenofsandiego.com(uses existing*.queenofsandiego.comwildcard ACM cert)jada-tech-blog→tech.sailjada.com(uses existing*.sailjada.comwildcard ACM cert)dc-tech-blog→tech.dangerouscentaur.com(uses existing dangerouscentaur wildcard CloudFront distribution ondc-sitesbucket)bats-tech-blog→tech.burialsatseasandiego.com(new ACM certificate via DNS validation)
CloudFront distributions were created with:
- Origin set to S3 website endpoint (HTTP, not S3 direct)
- Default cache behavior with TTL of 300 seconds (for blog post freshness)
- Custom error responses (404) pointing to
index.htmlfor client-side routing - HTTP to HTTPS redirect enforced
- OAI (Origin Access Identity) not used because static website endpoints require public read access
DNS Resolution
DNS setup varies by registrar:
- queenofsandiego.com and sailjada.com: Route53 hosted zones with ALIAS records pointing to CloudFront distribution domain names
- dangerouscentaur.com: Namecheap CNAME pointing to the existing wildcard CloudFront distribution
- burialsatseasandiego.com: GoDaddy DNS with CNAME validation records for ACM certificate, then CNAME to CloudFront distribution
Session Transcript Parsing
Claude Code stores sessions as JSONL files in ~/.claude/projects/. Each line is a JSON object representing a tool invocation, message, or system event. The blog generator:
- Reads the most recent session transcript from the active project
- Extracts all tool use entries (commands run, files modified)
- Filters out sensitive entries (AWS credentials, API keys, passwords)
- Groups file operations by type (Write, Edit, Delete)
- Builds a narrative combining user intent, commands executed, and infrastructure changes
- Generates an HTML post with metadata (timestamp, file count, operation count)
- Uploads to the appropriate tech blog S3 bucket
- Invalidates the CloudFront distribution cache
The generator preserves exact file paths, bucket names, distribution IDs, and command syntax to provide the granular audit trail Sergio requires.
Integration with Ship's Papers Menu
Each domain's main index.html was updated to include a "Technical Blog" link in the Ship's Papers dropdown navigation. For queenofsandiego.com, the nav entry points to tech.queenofsandiego.com with the class nav-external-link to indicate it opens in context (or new tab if preferred).
Key Decisions
Why S3 + CloudFront Instead of Direct Hosting
S3 static website hosting with CloudFront CDN provides:
- Cost efficiency: Minimal storage and bandwidth costs
- Global distribution: CloudFront edge caches reduce latency
- Zero-downtime deployments: Upload new HTML, invalidate cache, done
- Separation of concerns: Tech blog infrastructure is completely isolated from main site infrastructure
Why Wildcard Certificates
Existing wildcard ACM certificates for *.queenofsandiego.com and *.sailjada.com meant zero additional SSL/TLS overhead. For dangerouscentaur, the existing wildcard CloudFront distribution was already configured, so we leveraged it. For burialsatseasandiego, a new certificate was provisioned with DNS validation via GoDaddy API integration.
Why HTTP Static Website Origin, Not S3 Direct
S3 website endpoints (HTTP) allow public read access without OAI complexity. CloudFront terminates HTTPS and handles the SSL/TLS upgrade. This is simpler and more standard for public static sites.
Sensitive Data Filtering
The blog generator explicitly excludes:
- AWS credentials, profile names (redacted from repos.env)
- API keys, tokens, passwords
- Private personal information
- GoDaddy, Namecheap, or Route53 credentials
- Database connection strings
File paths, bucket names, distribution IDs, and command syntax are preserved because they are infrastructure identifiers, not secrets.
Post-Session Workflow
When a Claude Code session ends:
- The stop hook is triggered
- The generator parses the most recent session transcript
- A new HTML post is created with the session's work summary
- The post is uploaded to
s3://qos-tech-blog/posts/YYYY-MM-DD-HH-MM-SS.html(or equivalent for other domains) - CloudFront cache is invalidated for
/* - Within seconds, the post is live at
tech.queenofsandiego.com
An index.html on each tech blog aggregates all