```html

Building Multi-Site Automated Technical Blog Infrastructure with Session-Based Generation

This session implemented a comprehensive system to automatically generate granular technical blog posts across four domain properties: queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com. The system captures development work in real-time and publishes detailed technical documentation without manual intervention.

Problem Statement

Previously, there was no centralized way to document technical work across multiple properties. The goal was to create a system that:

  • Automatically captures session work from Claude development sessions
  • Generates detailed, granular blog posts (not high-level summaries)
  • Posts to separate tech subdomains for each property
  • Integrates with existing site navigation ("Ship's Papers" menu)
  • Strips all credentials and sensitive data automatically
  • Requires zero manual intervention after session completion

Architecture Overview

The implementation uses three core components:

  • tech_blog_generator.py — Parses Claude session transcripts and generates HTML posts
  • tech_blog_init.py — Sets up S3 buckets, CloudFront distributions, and DNS for each tech blog
  • tech_blog_stop.sh — Claude Code Stop hook that triggers post generation at session end

The system integrates with Claude Code's hook system. When a development session ends, the Stop hook automatically invokes the generator, which reads the session transcript, extracts technical work, and publishes to the appropriate blog.

Infrastructure Setup

Each tech blog required provisioning four AWS resources:

S3 Buckets

Four buckets were created to serve as CloudFront origins:

  • qos-tech-blog — origin for tech.queenofsandiego.com
  • jada-tech-blog — origin for tech.sailjada.com
  • bats-tech-blog — origin for tech.burialsatseasandiego.com
  • dc-sites — existing wildcard bucket, reconfigured for tech.dangerouscentaur.com

Each bucket was configured with:

  • Static website hosting enabled
  • Block public access disabled (required for CloudFront access)
  • Bucket policy allowing CloudFront origin access identity (OAI) to read objects

CloudFront Distributions

Three new CloudFront distributions were created (dangerouscentaur reused existing E2Q4UU71SRNTMB):

  • Distribution for tech.queenofsandiego.com with origin qos-tech-blog
  • Distribution for tech.sailjada.com with origin jada-tech-blog
  • Distribution for tech.burialsatseasandiego.com with origin bats-tech-blog

Each distribution was configured with:

  • Default root object: index.html
  • Viewer protocol policy: redirect HTTP to HTTPS
  • Origin access identity for bucket authentication
  • Custom SSL certificate (wildcard for queenofsandiego.com and sailjada.com; GoDaddy managed for burialsatseasandiego.com)

DNS Configuration

DNS entries varied by registrar:

  • queenofsandiego.com and sailjada.com — Route53 hosted zones. CNAME entries created pointing to CloudFront distribution domain names.
  • dangerouscentaur.com — Namecheap DNS. Existing CNAME wildcard configuration reused.
  • burialsatseasandiego.com — GoDaddy DNS. ACM certificate validation required CNAME record addition to GoDaddy DNS console before CloudFront could be activated.

Session Transcript Parsing

The tech_blog_generator.py script extracts technical details from Claude session transcripts (stored as JSONL in ~/.claude/projects). The parsing logic:

  • Reads tool_use entries from the session transcript (e.g., file reads, command executions)
  • Filters for technical operations: file modifications, infrastructure commands, deployments
  • Removes sensitive data patterns: AWS credentials, API keys, passwords, tokens
  • Extracts command examples and shows exact file paths, bucket names, distribution IDs
  • Determines target blog based on which domains/files were modified
  • Generates HTML with proper structure: title, sections, code blocks

The generator creates multiple posts if the session touched multiple properties (e.g., work on both queenofsandiego.com and sailjada.com generates two separate posts).

Integration with Ship's Papers Menu

The queenofsandiego.com navigation was updated to include a "Tech Blog" link in the Ship's Papers dropdown menu. The entry points to tech.queenofsandiego.com. Similar navigation updates will be made to other properties' Ship's Papers menus.

The tech blog index page (index.html) on each S3 bucket lists all published posts in reverse chronological order with publication timestamps and brief descriptions.

Credential Scrubbing Strategy

The system implements multiple layers of scrubbing:

  • Pattern matching — Regex patterns detect AWS key formats, GoDaddy credentials, API tokens
  • Environment variable filtering — Any value from repos.env or AWS_* environment variables is redacted
  • Manual memory files — Sensitive reference files (e.g., reference_godaddy_credentials.md) are excluded from transcript parsing
  • Output validation — Generated HTML is scanned for password-like strings before uploading to S3

If a credential is accidentally captured, the HTML is not published and a warning is logged to ~/.claude/hooks/tech_blog_stop.log.

Stop Hook Integration

The tech_blog_stop.sh hook is registered in Claude Code settings at ~/.claude/settings.json. When a session ends:

  1. Claude Code invokes the hook script
  2. Hook reads the session ID and session directory
  3. Invokes tech_blog_generator.py with the session transcript path
  4. Generator outputs HTML to appropriate S3 buckets
  5. CloudFront distributions are invalidated to ensure fresh content
  6. Log entries are written to ~/.claude/hooks/tech_blog_stop.log

The hook logs all actions including which blog received posts, post titles, and any scrubbing warnings.

Key Technical Decisions

  • Session-based generation vs. real-time — Posts are