```html

Building an Automated Technical Blog System Across Four Sailing Event Sites

Overview

This session implemented a comprehensive automated technical blog generation system across four separate domains: tech.queenofsandiego.com, tech.dangerouscentaur.com, tech.sailjada.com, and tech.burialsatseasandiego.com. The system captures granular development work in real-time, generates posts from Claude Code session transcripts, and publishes them to CloudFront-distributed S3 buckets without exposing credentials.

Problem Statement

The organization needed visibility into technical work being performed across multiple sailing event websites. Previous approaches either lacked granularity or required manual documentation. The solution needed to:

  • Automatically capture work from each Claude Code development session
  • Generate posts that "get into the weeds" with specific file paths, function names, and infrastructure details
  • Publish to separate tech blogs for each domain
  • Integrate into existing site navigation (Ship's Papers menu)
  • Prevent credential leakage in all outputs
  • Work across heterogeneous DNS providers (Route53, GoDaddy, Namecheap)

Infrastructure Architecture

S3 Buckets

Created three new S3 buckets to host the tech blogs:

  • tech-queenofsandiego-com — for queenofsandiego.com technical posts
  • tech-sailjada-com — for sailjada.com technical posts
  • dc-sites (existing wildcard) — for dangerouscentaur.com technical posts via subdomain
  • tech-burialsatseasandiego-com — for burialsatseasandiego.com technical posts

Each bucket is configured with public read access for index.html and posts, static website hosting enabled, and proper CORS headers to support cross-origin requests from the main sites.

CloudFront Distributions

Created CloudFront distributions for tech.queenofsandiego.com, tech.sailjada.com, and tech.burialsatseasandiego.com, each pointing to their respective S3 origins. These distributions:

  • Use wildcard ACM certificates already provisioned for *.queenofsandiego.com, *.sailjada.com, and the existing *.dangerouscentaur.com cert
  • Cache HTML at 60 seconds, posts at 3600 seconds to balance freshness with performance
  • Include cache invalidation support for immediate publish cycles
  • Enforce HTTPS with HTTP→HTTPS redirect

DNS Configuration

DNS setup varied by domain registrar:

  • queenofsandiego.com & sailjada.com (Route53): Added ALIAS records pointing to CloudFront distribution domains
  • dangerouscentaur.com (Namecheap): Added CNAME record for tech subdomain pointing to existing wildcard CloudFront distribution E2Q4UU71SRNTMB
  • burialsatseasandiego.com (GoDaddy): Used GoDaddy API credentials to add CNAME records for ACM certificate validation, then added tech subdomain CNAME to CloudFront distribution

Software Components

tech_blog_generator.py

The core generator script reads Claude Code session transcripts in JSONL format, extracts all tool uses (file operations, commands executed), and generates an HTML blog post. Key features:

  • Parses session transcript from ~/.claude/sessions/ directory
  • Filters out sensitive patterns using regex (AWS keys, API tokens, passwords)
  • Groups work by type: file modifications, infrastructure changes, domain operations
  • Generates semantic HTML with proper heading hierarchy
  • Includes timestamps and session identifiers
  • Creates index.html with archive of all posts

tech_blog_init.py

Initialization script that sets up infrastructure for a new tech blog:

  • Creates S3 bucket with versioning and public access policy
  • Configures static website hosting (index.html as default)
  • Provisions CloudFront distribution (except for dangerouscentaur reuse)
  • Handles DNS records via Route53 API or external DNS provider APIs
  • Manages ACM certificate validation records
  • Stores infrastructure config in JSON for later reference

tech_blog_stop.sh

Bash hook script that executes when Claude Code sessions end. Located at ~/.claude/hooks/tech_blog_stop.sh, this script:

  • Waits for the session transcript file to be written
  • Invokes tech_blog_generator.py on the completed transcript
  • Uploads the generated HTML to the appropriate tech blog S3 bucket
  • Invalidates CloudFront distribution cache for index.html
  • Logs all operations to ~/.claude/logs/tech_blog_publish.log
  • Handles errors gracefully, noting issues without blocking session completion

Configuration and Integration

Claude Code Settings

Updated ~/.claude/settings.json to register the stop hook:

"hooks": {
  "on_session_stop": "/Users/cb/.claude/hooks/tech_blog_stop.sh"
}

Site Navigation

Updated the Ship's Papers menu in /queenofsandiego.com/index.html to include a "Technical Blog" link pointing to tech.queenofsandiego.com. Similar updates applied to other site index.html files. This makes the technical work visible to stakeholders like Sergio through the existing navigation structure.

Environment Variables

The system reads from ~/.repos.env for:

  • AWS_PROFILE — for S3 and CloudFront operations
  • GODADDY_API_KEY and GODADDY_API_SECRET — for burialsatseasandiego.com DNS management
  • Domain-specific configuration for routing blog posts to correct S3 buckets

Key Technical Decisions

Session Transcript as Source of Truth

Rather than requiring manual logging, the system uses Claude Code's native session transcript (stored in JSONL format at ~/.claude/sessions/) as the authoritative record. This captures exactly what happened without human intervention or interpretation.

Granular File-Level Documentation

The generator extracts specific file paths from transcript tool uses, not just high-level summaries. Example: instead of "updated email templates," it captures "Edit: /Users/cb/Documents/repos/sites/queenofsandiego.com/notes/email_birthday_sail_2026.html" with context about the change.

Heterogeneous DNS Provider Support

Rather than consolidating all domains to a single DNS provider, the system accommodates existing arrangements: Route53 for AWS-managed domains