```html

Multi-Domain Tech Blog Infrastructure: Auto-Generated Session Transcripts at Scale

Overview

This session implemented a complete technical blogging infrastructure across four domains (queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com). The system automatically captures development work from Claude Code sessions, generates granular technical blog posts, deploys them to dedicated tech subdomains, and integrates navigation links into existing site menus.

Problem Statement

Prior to this work, there was no visibility into the detailed technical changes being made across multiple web properties. Sergio and other stakeholders needed a way to see exactly what was being implemented—down to specific file paths, function names, and infrastructure decisions—without requiring manual summarization or high-level reporting.

Architecture Overview

The solution consists of four primary components:

  • Session Capture Hook: Claude Code stop hook that runs after each session ends, capturing the development transcript
  • Blog Generator: Python script that parses session transcripts, extracts work items, and generates HTML blog posts
  • Infrastructure Init: Terraform/AWS provisioning script that creates S3 buckets, CloudFront distributions, and DNS records for each tech blog domain
  • Navigation Integration: Updates to existing site HTML files to expose tech blogs via Ship's Papers menus

Infrastructure Deployment

Domain-Specific Setup

For each domain requiring a tech blog, we provisioned the following resources:

  • S3 Bucket: Named pattern tech-[domain]-blog (e.g., tech-queenofsandiego-blog, tech-sailjada-blog)
  • CloudFront Distribution: Origin pointing to the S3 bucket with appropriate caching headers and GZIP compression
  • DNS Records: CNAME or A records pointing CloudFront distribution to tech.[domain] subdomain
  • ACM Certificates: Leveraged existing wildcard certificates where available (*.queenofsandiego.com, *.sailjada.com)

DNS Provider Handling

Different domains use different DNS providers, requiring provider-specific approaches:

  • sailjada.com & queenofsandiego.com: Route53 hosted zones (AWS-native). DNS records created directly via Terraform.
  • dangerouscentaur.com: Namecheap DNS. Existing wildcard CloudFront distribution (E2Q4UU71SRNTMB) already configured on dc-sites S3 bucket. CNAME record added to Namecheap pointing tech.dangerouscentaur.com to CloudFront domain.
  • burialsatseasandiego.com: GoDaddy DNS provider. ACM certificate validation required DNS CNAME record addition. API credentials available in environment configuration for programmatic DNS updates.

Session Capture and Blog Generation

Stop Hook Implementation

File: /Users/cb/.claude/hooks/tech_blog_stop.sh

This hook executes when a Claude Code session ends. It:

  • Reads the session transcript from ~/.claude/sessions/[session-id]/transcript.jsonl
  • Invokes the blog generator with the transcript path and detected domain context
  • Logs output to ~/.claude/logs/tech_blog_stop.log for debugging
  • Handles errors gracefully to avoid blocking session termination

Blog Generator Pipeline

File: /Users/cb/Documents/repos/tools/tech_blog_generator.py

The generator performs these operations:

  • Transcript Parsing: Reads JSONL transcript format, extracting file modifications, commands executed, and agent reasoning
  • Content Extraction: Identifies granular work items including:
    • File paths created/modified with full repository paths
    • Specific function names and code changes (sanitized)
    • Infrastructure changes (bucket names, distribution IDs, DNS records)
    • Command examples executed (credentials redacted)
    • Decision rationale from agent notes
  • HTML Generation: Creates semantic HTML with proper heading hierarchy, code blocks, and lists
  • Credential Filtering: Regex patterns detect and remove AWS access keys, API tokens, passwords, and other sensitive data before publishing
  • S3 Upload: Uploads generated HTML to the appropriate tech blog bucket with correct content-type and cache headers
  • CloudFront Invalidation: Triggers distribution invalidation to ensure new content serves immediately

Domain Detection

The system detects which tech blog domain applies to the current session by analyzing modified file paths. If work touches files in /Users/cb/Documents/repos/sites/queenofsandiego.com/, the post publishes to tech.queenofsandiego.com. Multi-domain sessions generate separate posts for each domain.

Navigation Integration

Ship's Papers Menu Updates

Updated HTML files to include tech blog links in navigation dropdowns:

  • /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html — Added "Tech Blog" link to Ship's Papers dropdown
  • /Users/cb/Documents/repos/sites/queenofsandiego.com/concert-nights.html — Updated navigation references
  • Similar updates queued for dangerouscentaur and burialsatseasandiego sites

The navigation structure uses semantic dropdown menus with CSS-driven visibility, ensuring tech blog access without cluttering primary navigation.

Credential Handling and Security

All published blog posts undergo sanitization to prevent credential leakage:

  • AWS access key patterns detected and removed
  • API keys and tokens filtered via regex
  • Environment variable values containing secrets excluded
  • GoDaddy/Namecheap API credentials never included
  • Database connection strings and passwords redacted
  • Personal email addresses and phone numbers removed from context

The generator logs sanitization activities to allow review of what was filtered, supporting audit trails without exposing the secrets themselves.

Key Technical Decisions

  • CloudFront + S3: Chose CloudFront for performance and cache control rather than serving directly from S3, enabling geographic distribution and sophisticated invalidation patterns.
  • Wildcard Certificates: Leveraged existing *.queenofsandiego.com and *.sailjada.com wildcard ACM certificates to avoid per-subdomain cert provisioning and validation.
  • Stop Hook vs. Event-Driven: Implemented stop hook (runs at session end