```html

Building Multi-Site Auto-Generated Technical Blog Infrastructure

This session involved architecting and deploying an automated technical documentation system that captures development work across four distinct maritime and sailing websites. The goal was to create real-time, granular technical blogs that provide complete visibility into infrastructure changes, code modifications, and deployment activities—with no sensitive credentials exposed.

What Was Done

  • Created automated blog generation system triggered on Claude Code session stops
  • Deployed four independent tech blogs: tech.queenofsandiego.com, tech.sailjada.com, tech.dangerouscentaur.com, tech.burialsatseasandiego.com
  • Integrated CloudFront CDN distributions with wildcard ACM certificates for three domains
  • Configured DNS records across Route53 (queenofsandiego.com, sailjada.com) and external providers (Namecheap for dangerouscentaur.com, GoDaddy for burialsatseasandiego.com)
  • Added navigation links to Ship's Papers menus across all sites
  • Established secure credential handling without exposing sensitive data in generated content

Technical Architecture

Core Components:

  • /Users/cb/Documents/repos/tools/tech_blog_generator.py — Main generation engine that parses Claude Code session transcripts (JSONL format) and converts tool usage and file modifications into structured blog posts
  • /Users/cb/Documents/repos/tools/tech_blog_init.py — Infrastructure provisioning script that creates S3 buckets, CloudFront distributions, and DNS records
  • /Users/cb/.claude/hooks/tech_blog_stop.sh — Stop hook that triggers blog generation and upload immediately after each Claude Code session ends

Session Data Processing:

The system ingests Claude Code session transcripts in JSONL format (one JSON object per line). Each line contains tool usage events, including:

  • File write/edit operations with full paths
  • Command executions with arguments and results
  • Lambda invocations with payloads
  • API calls and HTTP requests

The generator parses these events and filters them by domain relevance (e.g., only queenofsandiego.com file paths and commands go into the QOS tech blog). It sanitizes all credentials by detecting and stripping common patterns: AWS keys, tokens, passwords, API keys, and GoDaddy/Namecheap credentials.

Infrastructure Deployment

Storage Layer:

S3 Buckets created:
- qos-tech-blog (queenofsandiego.com tech blog)
- jada-tech-blog (sailjada.com tech blog)
- dc-sites (dangerouscentaur.com, reused existing wildcard CF dist)
- bats-tech-blog (burialsatseasandiego.com tech blog)

Each bucket is configured with:

  • Block all public access ACLs
  • Website hosting disabled (access only via CloudFront)
  • Versioning enabled for audit trail
  • Standard storage class for cost efficiency

CDN Layer:

CloudFront distributions were created for each site with the following configuration:

  • queenofsandiego.com: Distribution ID automatically generated, uses existing wildcard certificate *.queenofsandiego.com
  • sailjada.com: Distribution ID automatically generated, uses existing wildcard certificate *.sailjada.com
  • dangerouscentaur.com: Reused existing wildcard distribution (ID: E2Q4UU71SRNTMB) on dc-sites bucket with existing wildcard cert
  • burialsatseasandiego.com: New distribution with certificate provisioning via AWS Certificate Manager

All distributions use:

  • HTTP/2 enabled for performance
  • IPv6 disabled (legacy compatibility)
  • Default root object: index.html
  • Origin Access Control (OAC) for secure S3 bucket access
  • Gzip compression enabled

DNS Configuration:

  • queenofsandiego.com & sailjada.com: Route53 CNAME records created pointing tech subdomains to CloudFront distribution domain names
  • dangerouscentaur.com: Namecheap DNS updated with CNAME pointing to existing CloudFront distribution
  • burialsatseasandiego.com: GoDaddy DNS updated with CNAME and ACM DNS validation record for certificate provisioning

Session Data Capture & Processing

The stop hook executes the following workflow:

# Pseudo-code flow
1. Claude Code session ends (stop hook triggered)
2. Hook reads most recent session transcript from ~/.claude/sessions/
3. Invokes tech_blog_generator.py with transcript path and domain filter
4. Generator sanitizes content (removes credentials, API keys)
5. Generator creates timestamped HTML article
6. Article is uploaded to appropriate S3 bucket
7. CloudFront cache is invalidated (all paths /*) for immediate visibility
8. Status logged to ~/.claude/hooks/logs/tech_blog_generation.log

Granularity Strategy:

Rather than high-level summaries, the system captures exact details:

  • Specific file paths modified (e.g., /Users/cb/Documents/repos/sites/queenofsandiego.com/events.html)
  • Command invocations with arguments (e.g., aws s3 cp index.html s3://qos-tech-blog/)
  • Lambda function names and triggers
  • CloudFront distribution IDs affected
  • DNS changes and CNAME values
  • S3 bucket operations and invalidation patterns

Navigation Integration

The Ship's Papers menu on each main site was updated to include a "Technical Blog" link:

  • queenofsandiego.com/index.html — Added link to tech.queenofsandiego.com
  • sailjada.com — Added link to tech.sailjada.com
  • dangerouscentaur.com — Added link to tech.dangerouscentaur.com
  • burialsatseasandiego.com — Added link to tech.burialsatseasandiego.com

Menu items are placed in the Ship's Papers/Documents section so stakeholders like Sergio can easily navigate to technical documentation.

Key Decisions & Rationale

Why CloudFront for all sites? Provides consistent delivery performance globally, enables cache invalidation for fresh content delivery, and supports wildcard certificates for cost efficiency.

Why separate S3 buckets per site? Maintains clear logical separation, allows independent access control and versioning policies, simplifies audit logging, and reduces blast radius if a bucket is misconfigured