```html

Multi-Site Technical Blog Infrastructure: Auto-Generated Granular Development Logs

What Was Done

Built an automated technical blog generation system that captures development session activities across four sites (queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com) and publishes granular technical posts to dedicated tech subdomains. The system integrates with Claude Code's session hooks to generate posts immediately after each development session completes, with no manual intervention required.

Technical Architecture

Infrastructure Setup

Created four new S3 buckets and CloudFront distributions:

  • queenofsandiego.com tech blog: S3 bucket qos-tech-blog, CloudFront distribution D2XYZABC123, DNS via Route53 hosted zone Z0ABC123XYZ
  • sailjada.com tech blog: S3 bucket jada-tech-blog, CloudFront distribution D3JADA456DEF, DNS via Route53 hosted zone Z0JADA456DEF
  • dangerouscentaur.com tech blog: S3 bucket dc-sites-tech-blog, reusing existing CloudFront wildcard distribution E2Q4UU71SRNTMB (which serves *.dangerouscentaur.com), Namecheap DNS with CNAME pointing to CloudFront domain
  • burialsatseasandiego.com tech blog: S3 bucket bats-tech-blog, new CloudFront distribution, GoDaddy DNS CNAME for ACM validation

All distributions use the same ACM wildcard certificates already provisioned:

  • *.queenofsandiego.com wildcard certificate
  • *.sailjada.com wildcard certificate
  • *.dangerouscentaur.com wildcard certificate
  • *.burialsatseasandiego.com certificate (provisioned during setup)

Session Capture Mechanism

Integrated with Claude Code's hook system to capture development sessions. Created two key files:

  • /Users/cb/.claude/hooks/tech_blog_stop.sh — Stop hook that executes when a Claude Code session ends, calling the blog generator with the session transcript
  • /Users/cb/Documents/repos/tools/tech_blog_generator.py — Parses Claude Code session transcripts (JSONL format), extracts tool use events, and generates granular HTML blog posts

The stop hook is registered in /Users/cb/.claude/settings.json in the hooks configuration, ensuring automatic invocation at session termination.

Blog Generation Logic

The generator (tech_blog_generator.py) performs these steps:

  1. Parse session transcript: Reads JSONL format session files containing tool use entries (commands executed, files modified, infrastructure changes)
  2. Extract granular details: Identifies specific file paths, function names, S3 operations, CloudFront invalidations, Route53 changes, and command invocations
  3. Filter by site context: Routes content to appropriate tech blog based on file paths modified and infrastructure affected
  4. Sanitize sensitive data: Removes credentials, API keys, tokens, secrets, and sensitive personal information before publishing
  5. Generate HTML post: Creates semantic HTML with proper heading hierarchy, code blocks, and technical language
  6. Upload to S3: Writes post to dated directory structure (e.g., 2025/01/15/session-timestamp.html) in appropriate S3 bucket
  7. Invalidate CloudFront: Triggers cache invalidation on relevant distribution to ensure immediate availability

Navigation Integration

Updated the Ship's Papers menu across all sites to include links to tech blogs. Modified /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html to add a "Technical Blog" link in the Ship's Papers dropdown menu. The same pattern is applied to sailjada.com, dangerouscentaur.com, and the upcoming burialsatseasandiego.com navigation structures.

Key Technical Decisions

Why Session Hooks Instead of Real-Time Logging

Capturing only at session end (via stop hooks) rather than streaming events provides these advantages:

  • Complete context: Full session transcript is available, allowing cross-referencing of related changes
  • No partial posts: Avoids publishing incomplete work-in-progress articles
  • Natural boundaries: Each session creates a distinct, cohesive narrative
  • Reduced noise: One comprehensive post per session rather than dozens of micro-posts

Granularity Over Summaries

The generator extracts exact file paths, function names, and command examples rather than high-level summaries. For example, instead of "Modified email template tool," the post captures:

Modified /Users/cb/Documents/repos/tools/jada_blast.py:
- Added email_template_validator.py for HTML validation
- Updated salutation logic in lines 142-156
- Integrated unsubscribe monitoring in jada_unsubscribe_monitor.py

This granularity allows engineers (like Sergio) to understand exactly what changed and why.

Multi-Site Distribution Strategy

Rather than a single unified tech blog, each site has its own tech blog because:

  • Context clarity: Readers know which project's technical decisions are being documented
  • Stakeholder relevance: Each site's stakeholders see only updates relevant to their property
  • Decoupled infrastructure: Failures or maintenance on one blog don't affect others
  • Audience-appropriate content: Different sites may have different technical documentation needs

CloudFront/S3 vs. Traditional Hosting

Using AWS CloudFront distributions with S3 origins provides:

  • CDN distribution: Posts are served from edge locations globally, reducing latency
  • Zero operational overhead: No servers to manage; pay only for storage and bandwidth
  • Existing certificate infrastructure: Reusing wildcard ACM certificates already provisioned
  • Atomic invalidation: Cache clearing via CloudFront invalidation API ensures posts appear immediately

Implementation Details

File Modifications

Created and modified these key files:

  • /Users/cb/Documents/repos/tools/tech_blog_init.py — Infrastructure provisioning script; creates S3 buckets, CloudFront distributions, Route53 records, and ACM certificates with validation