```html

Building Multi-Site Tech Blog Infrastructure with Auto-Generated Session Capture

What Was Done

Created an automated technical blog generation system that captures detailed session work across four websites (queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com) and publishes granular technical posts to corresponding tech subdomains. This system parses Claude session transcripts, extracts file modifications and commands executed, and generates detailed engineering documentation without exposing credentials.

Architecture Overview

The system consists of three primary components:

  • Session Capture Hook — A Claude Code Stop hook that runs at session end, capturing the transcript
  • Blog Generator — Python script that parses session JSONL transcripts and generates HTML blog posts
  • Infrastructure Layer — S3 buckets, CloudFront distributions, and DNS configuration for each tech blog subdomain

Infrastructure Setup

S3 & CloudFront Distribution

Four S3 buckets were created to host the generated blog content:

  • tech-qos-blog — Static site for tech.queenofsandiego.com
  • tech-jada-blog — Static site for tech.sailjada.com
  • dc-tech-blog — Static site for tech.dangerouscentaur.com
  • bats-tech-blog — Static site for tech.burialsatseasandiego.com

CloudFront distributions were provisioned for each, leveraging existing wildcard ACM certificates:

  • *.queenofsandiego.com — Certificate ARN used for QOS tech blog distribution
  • *.sailjada.com — Certificate ARN used for JADA tech blog distribution
  • *.dangerouscentaur.com — Routed through existing wildcard distribution E2Q4UU71SRNTMB on dc-sites bucket
  • burialsatseasandiego.com — New certificate created via ACM with DNS validation

DNS Configuration

Domain DNS was configured based on existing registrar setup:

  • Route53 Hosted Zones: queenofsandiego.com and sailjada.com — CNAME records created pointing to respective CloudFront distribution domain names
  • Namecheap (dangerouscentaur.com): CNAME record added: tech.dangerouscentaur.com CNAME → d111111abcdef8.cloudfront.net
  • GoDaddy (burialsatseasandiego.com): ACM certificate DNS validation CNAME added, then A record created pointing to CloudFront distribution

Blog Generator Implementation

Session Transcript Parsing

The generator reads Claude session transcripts stored as JSONL files. Each session file contains an array of interaction objects with the following structure:

{
  "type": "tool_use" | "text" | "command",
  "path": "/Users/cb/Documents/repos/...",
  "action": "Write" | "Edit" | "Read",
  "timestamp": "ISO-8601"
}

The parser extracts three categories of session data:

  • File Modifications — Paths, actions (Write/Edit), and counts per session
  • Commands Executed — User commands run during the session (without sensitive output)
  • Infrastructure Changes — AWS resource creation/modification detected from logs

Site Detection Logic

The generator automatically routes posts to the correct tech blog by analyzing file paths:

if "/queenofsandiego.com" in path:
    target_site = "queenofsandiego"
elif "/sailjada.com" in path or "jada" in path.lower():
    target_site = "sailjada"
elif "/dangerouscentaur" in path or "dc" in path.lower():
    target_site = "dangerouscentaur"
elif "/burialsatseasandiego" in path or "bats" in path.lower():
    target_site = "burialsatseasandiego"

Sessions touching multiple sites generate multiple posts, each published to its corresponding tech blog.

HTML Generation

Posts are generated with detailed file modification tables, command execution lists, and infrastructure change documentation. The HTML template includes:

  • Session metadata (timestamp, duration, number of files changed)
  • File modification summary table (path, action, type)
  • Command execution log (with credential redaction)
  • AWS/Infrastructure changes detected and applied
  • Technical decision rationale

Credential & Security Handling

The system implements multiple layers of credential protection:

  • Redaction Filters: Regex patterns strip API keys, tokens, passwords, and AWS credentials from command output before HTML generation
  • Path Filtering: Sensitive file paths (like .claude/hooks/ containing credentials) are excluded from file modification lists
  • Template Truncation: Email addresses and personal data are summarized rather than fully displayed
  • Source Code Redaction: Environment variables, hardcoded secrets in code, and credential references are replaced with placeholders

Claude Code Settings Integration

The Stop hook was registered in Claude Code settings at ~/.claude/settings.json:

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

The hook script runs at session end, executing the blog generator and uploading posts to the appropriate S3 bucket before invalidating CloudFront caches.

Navigation Integration

The tech blog link was added to the Ship's Papers menu on queenofsandiego.com's index.html. This dropdown now includes a link to tech.queenofsandiego.com, making session documentation discoverable by stakeholders like Sergio.

Key Technical Decisions

JSONL Transcript Format

Claude sessions are stored as JSONL (JSON Lines) for efficient streaming. This format allows the generator to process sessions incrementally without loading entire transcripts into memory, critical for long sessions with hundreds of interactions.

Multi-Site Routing

Rather than a single centralized blog, each organization has its own tech blog. This allows filtering by site and maintains organizational boundaries while sharing infrastructure patterns across all four properties.

CloudFront Distribution Reuse

The dangerouscentaur.com tech blog was routed through the existing wildcard distribution (E2Q4UU71SRNTMB) on the dc-sites bucket to avoid unnecessary certificate and distribution overhead, reducing operational complexity.

GoDaddy ACM Certificate Integration

burialsatseasandiego.com was the only domain without a pre-existing wildcard certificate. Rather than requesting a wild