Building an Auto-Generated Technical Blog System Across Four Domain Properties
Overview
This session implemented a comprehensive technical documentation system that auto-generates detailed blog posts to four tech subdomain properties (tech.queenofsandiego.com, tech.sailjada.com, tech.dangerouscentaur.com, and tech.burialsatseasandiego.com) based on Claude Code session transcripts. The goal is to provide granular, audit-trail-level documentation of all engineering work performed across the four properties, enabling stakeholders like Sergio to review technical decisions and implementation details in real-time.
Architecture Overview
The system consists of four key components:
- Blog Generator (
/Users/cb/Documents/repos/tools/tech_blog_generator.py) — Parses Claude Code session transcripts in JSONL format, extracts tool use entries and command executions, sanitizes credentials, and generates HTML blog posts - Infrastructure Initializer (
/Users/cb/Documents/repos/tools/tech_blog_init.py) — Provisions S3 buckets, CloudFront distributions, Route53 DNS records, and ACM certificates for each tech blog domain - Stop Hook (
/Users/cb/.claude/hooks/tech_blog_stop.sh) — Triggers automatically when a Claude Code session ends, captures the transcript, generates a blog post, and uploads it to the appropriate S3 bucket - Navigation Integration — Updated Ship's Papers menu across all four main sites to link to their respective tech blogs
Infrastructure Deployment
Wildcard Certificate Utilization
The deployment leveraged existing AWS Certificate Manager wildcard certificates to minimize setup complexity:
*.queenofsandiego.com— Pre-existing wildcard cert supports tech.queenofsandiego.com*.sailjada.com— Pre-existing wildcard cert supports tech.sailjada.com*.dangerouscentaur.com— Leveraged existing wildcard CloudFront distribution (ID:E2Q4UU71SRNTMB) ondc-sitesS3 bucket via CNAME routingburialsatseasandiego.com— Required new ACM certificate; DNS hosted at GoDaddy (not Route53), so CNAME validation records were manually added via GoDaddy API
S3 and CloudFront Setup
For queenofsandiego.com and sailjada.com, the init script created:
- S3 buckets:
tech-qos-blog,tech-jada-blog - CloudFront distributions with origin pointing to each S3 bucket
- Route53 alias records pointing each tech subdomain to its CloudFront distribution
- Bucket lifecycle policies to version objects and enable public read access via CloudFront
For dangerouscentaur.com, blog content is uploaded to the dc-sites S3 bucket under a /tech/ prefix, with the existing CloudFront distribution serving both the main site and tech blog.
For burialsatseasandiego.com, new infrastructure was provisioned with Route53 alias records and GoDaddy DNS CNAME validation for the ACM certificate.
DNS and Certificate Validation
The init script automated ACM certificate validation by:
- Creating certificates via boto3
request_certificate()for each domain - Extracting DNS validation records from certificate details
- For Route53-hosted zones (qos, jada, bats): Writing alias records directly via boto3
- For GoDaddy-hosted zones (dangerouscentaur): Using GoDaddy API to add CNAME records
- Polling certificate status until validation completed
Blog Generator Technical Details
Session Transcript Parsing
Claude Code sessions are stored as JSONL (JSON Lines) transcripts in /Users/cb/.claude/sessions/. Each line is a JSON object representing a message or tool use in the session. The generator:
- Opens the most recent session transcript file
- Iterates through lines, parsing JSON objects
- Identifies entries where
"type": "tool_use" - Extracts tool names (e.g., "bash_execute", "file_write", "file_edit") and their inputs
- For command executions, extracts the command and stdout/stderr output
- For file operations, records the file path, operation type, and a diff summary
Credential Sanitization
Before generating the post, the generator applies regex patterns to remove sensitive data:
- AWS access keys, secret keys, and session tokens
- API keys and bearer tokens
- Passwords, auth headers, and environment variables containing credentials
- Git URLs with embedded credentials
- Database connection strings with passwords
This sanitization is applied to both file contents and command outputs, ensuring no credentials leak into published blog posts.
HTML Generation
The generator produces an HTML file with semantic structure:
<h2>title derived from the session's user request or dominant activity<h3>sections for "What Was Done," "Technical Details," "Commands Run," and "Files Modified"<ul>/<li>lists for enumerated activities, file paths, and infrastructure changes<code>inline formatting for file paths, bucket names, distribution IDs, function names<pre><code>blocks for multi-line command examples and output excerpts
S3 Upload and Indexing
After HTML generation, the post is:
- Named with a timestamp:
YYYY-MM-DD-HHMMSS-title-slug.html - Uploaded to the tech blog S3 bucket with
public-readACL andtext/htmlcontent type - An
index.htmlis regenerated to list all posts in reverse chronological order, with links, dates, and excerpt snippets - The CloudFront distribution is invalidated via
create_invalidation()to serve fresh content immediately
Stop Hook Integration
The Stop hook (tech_blog_stop.sh) is registered in Claude Code settings under the hooks array with event "on_stop". When a session ends:
- The hook is invoked with the session ID as an argument
- It queries the session archive to retrieve the transcript file
- The transcript is passed to
tech_blog_generator.py - The generator identifies the domain context from