Building Multi-Site Technical Blog Infrastructure with Auto-Generated Session Transcripts
This session implemented a comprehensive technical blogging system across four independent sailing and event sites, with automatic post generation from Claude development session transcripts. The goal was to create granular, detailed technical documentation of ongoing work—visible to stakeholders like Sergio—without manual blog writing overhead.
What Was Done
- Created automated blog generation pipeline that converts Claude session transcripts into technical posts
- Provisioned S3 buckets and CloudFront distributions for four tech blogs:
tech.queenofsandiego.com,tech.sailjada.com,tech.dangerouscentaur.com,tech.burialsatseasandiego.com - Integrated tech blog navigation links into Ship's Papers menu on queenofsandiego.com
- Implemented Claude Code hook system to capture and publish posts automatically after each development session
- Created email template validation and unsubscribe monitoring tooling
- Fixed image references on burialsatseasandiego.sailjada.com and created progress tracking cards
Technical Architecture
Blog Generation Pipeline
Two Python scripts handle the core functionality:
/Users/cb/Documents/repos/tools/tech_blog_generator.py— Parses JSONL transcript files from Claude sessions, extracts work items (files modified, commands executed), and generates semantic HTML blog posts with exact file paths, function names, and infrastructure changes/Users/cb/Documents/repos/tools/tech_blog_init.py— Provisions cloud infrastructure for each tech blog domain, including S3 bucket creation, CloudFront distribution setup with proper origin and caching behavior, and DNS record creation
The generator reads session transcripts in JSONL format (one JSON object per line), extracting tool use entries that contain file operations and shell commands. It groups related changes by theme and generates narrative HTML describing what was changed, why the decisions were made, and how the infrastructure supports it.
Claude Code Integration
A Stop hook script at /Users/cb/.claude/hooks/tech_blog_stop.sh executes when a Claude development session ends. This script:
- Locates the current session's transcript in
/Users/cb/.claude/projects/ - Identifies which site(s) were worked on by checking modified file paths
- Invokes the blog generator to create an HTML post
- Uploads the post to the appropriate S3 bucket (
qos-tech-blog,jada-tech-blog,dc-tech-blog, orbats-tech-blog) - Invalidates the CloudFront distribution cache to ensure immediate visibility
The hook is registered in Claude Code settings at /Users/cb/.claude/settings.json under the hooks configuration, ensuring it runs automatically without user intervention.
Infrastructure Details
S3 & CloudFront Setup
Each tech blog uses the same pattern:
- queenofsandiego.com: S3 bucket
qos-tech-blog, CloudFront distribution with origin pointing to bucket, wildcard ACM certificate*.queenofsandiego.com(already existed), Route53 alias record fortech.queenofsandiego.comin the queenofsandiego.com hosted zone - sailjada.com: S3 bucket
jada-tech-blog, CloudFront distribution, wildcard ACM certificate*.sailjada.com(already existed), Route53 alias record in the sailjada.com hosted zone - dangerouscentaur.com: S3 bucket
dc-tech-blog, CloudFront distribution, used existing wildcard Namecheap CNAME setup (since dangerouscentaur does not use Route53), certificate provisioned via ACM - burialsatseasandiego.com: S3 bucket
bats-tech-blog, CloudFront distribution, certificate provisioned via ACM and validated through GoDaddy DNS API (burialsatseasandiego.com is hosted at GoDaddy), CNAME record added to GoDaddy DNS
CloudFront distributions are configured with:
- S3 bucket as origin with origin access identity (OAI) for security
- Default behavior caching HTML with 1-hour TTL to balance freshness with performance
- Index document set to
index.html - Minimum TTL of 0 seconds to allow immediate cache invalidation
DNS & Certificate Strategy
Four hosted zones were involved:
queenofsandiego.comandsailjada.com— Both managed in Route53 under the same AWS account; wildcard certificates already existed in ACM, so DNS validation was straightforwarddangerouscentaur.com— Uses Namecheap for DNS; wildcard CF distribution existed, so we created a new CNAME record pointing to the new tech blog CloudFront domainburialsatseasandiego.com— Hosted at GoDaddy; ACM certificate creation required DNS validation via GoDaddy API, using credentials stored in environment variables
Key Decisions & Rationale
Why Auto-Generation Instead of Manual Posts?
Sergio needs visibility into detailed technical work. Manual blog writing creates a bottleneck and encourages high-level summaries over granular details. By parsing session transcripts automatically, we capture exact file paths, function names, infrastructure IDs, and command sequences—the "in the weeds" details that matter for technical accountability.
Why a Stop Hook Instead of Event-Based Publishing?
Claude Code sessions have clear start and end points. Using the Stop hook ensures we capture a coherent unit of work (one session) and publish it as a single post. This avoids partial posts or duplicate entries.
Why Four Separate Tech Blogs?
Each domain (queenofsandiego.com, sailjada.com, dangerouscentaur.com, burialsatseasandiego.com) serves different purposes and audiences. Separate tech blogs allow domain-specific documentation without cluttering the main sites.
Why S3 + CloudFront + Route53/Namecheap/GoDaddy?
Static HTML hosting via S3 + CloudFront provides high availability, low cost, and fast global delivery. Using existing DNS providers (Route53 for AWS-hosted domains, Namecheap for dangerouscentaur, GoDaddy for burialsatseasandiego) avoids unnecessary DNS migration.
Code & Credential Security
The blog generator and initialization scripts explicitly filter out credentials, API keys, tokens, and secrets before publishing. Environment variables like GoDaddy API credentials are used during infrastructure provisioning but never appear in generated posts.
Session transcripts are parsed to extract high-level summaries of what was done