```html

Building an Automated Multi-Site Technical Blog System with Session-Based Post Generation

What Was Done

Implemented a fully automated technical blog infrastructure across four domains (tech.queenofsandiego.com, tech.sailjada.com, tech.dangerouscentaur.com, and tech.burialsatseasandiego.com) that captures development session activity and generates granular technical posts immediately upon session completion. The system uses Claude Code's hook mechanism to intercept session transcripts, parse them for file modifications and commands executed, and publish detailed posts to S3-backed CloudFront distributions without manual intervention.

Technical Architecture

Core Components

  • tech_blog_generator.py — Main post generation engine that parses Claude Code session transcripts in JSONL format, extracts file modifications (reads, writes, edits), command executions, and agent reasoning, then renders them into structured HTML blog posts with syntax highlighting and navigation.
  • tech_blog_init.py — Infrastructure provisioning script that creates S3 buckets, CloudFront distributions, ACM certificates, and DNS records for each tech blog domain. Validates existing wildcard certificates before creating new resources.
  • tech_blog_stop.sh — Claude Code hook executed at session end that invokes the Python generator, uploads posts to appropriate S3 buckets, and invalidates CloudFront caches for instant publication.

Infrastructure Setup

Each tech blog uses an identical pattern:

  • S3 bucket: tech-{domain} (e.g., tech-queenofsandiego-com) configured for static web hosting with public read access on HTML files only.
  • CloudFront distribution: Points to S3 bucket origin with brotli/gzip compression enabled, 1-hour default TTL, and HTTP→HTTPS redirect.
  • ACM certificate: Leverages existing wildcard certs (*.queenofsandiego.com, *.sailjada.com) or creates new ones; uses DNS validation via Route53 or GoDaddy depending on domain registrar.
  • DNS: Route53 alias records for queenofsandiego.com and sailjada.com; CNAME records at Namecheap for dangerouscentaur.com and GoDaddy for burialsatseasandiego.com.

Session Transcript Parsing

The generator reads session files from ~/.claude/projects/{workspace}/sessions/ in JSONL format. Each line contains either:

  • file_write/file_edit events: Path, action type (Write/Edit), and timestamp
  • tool_use blocks: Command name, input parameters, and execution results
  • text blocks: Agent reasoning explaining decisions and architecture choices

The parser extracts:

Files modified: Path normalization, grouping by directory
Commands run: Exact command names and arguments (redacting sensitive parameters)
Agent notes: Direct extraction from reasoning blocks for "Why" context
Timestamps: Session start/end with duration calculation

Key Implementation Details

Credential Redaction

The system implements strict filtering:

  • Any tool_use with parameters containing password, token, key, secret, credential fields is scrubbed before publishing.
  • Environment variable references are preserved; actual values are never extracted.
  • GoDaddy API credentials, AWS keys, and DNS passwords are logged to ~/.claude/hooks/logs/ separately for audit but never included in public posts.

Domain-Specific Routing

Posts are routed based on file paths modified:

  • Modifications to queenofsandiego.com/ → Published to tech.queenofsandiego.com
  • Modifications to sailjada.com/ → Published to tech.sailjada.com
  • Modifications to both or infrastructure code → Published to all four sites with domain-specific sections

S3 Upload & CloudFront Invalidation

Post-generation workflow:

aws s3 cp post-YYYYMMDD-HHMMSS.html s3://tech-{domain}-com/posts/
aws cloudfront create-invalidation --distribution-id {ID} --paths "/*"

Invalidations are queued and processed within 60 seconds, ensuring posts appear live before session context windows close.

Navigation Integration

Updated queenofsandiego.com/index.html ship's papers menu to include "Tech Blog" link pointing to tech.queenofsandiego.com. Similar navigation updates applied to other primary sites. Blog index pages auto-generate tables of contents from S3 object listings, sorted by post date descending.

Why This Approach

Granularity Over Summaries

Rather than end-of-month high-level reports, the system captures every file edit, every command, and every decision rationale. This allows Sergio to drill down into specific changes (e.g., "What changed in the booking flow?") without losing implementation context.

Session-Based Triggers

Using Claude Code's native hook mechanism means no external polling, cron jobs, or manual triggers. The moment a development session ends, the hook fires automatically. This eliminates the "did someone document this?" problem.

Infrastructure as Code**Reproducibility

The tech_blog_init.py script is idempotent—running it multiple times is safe and enables disaster recovery. All resource names, bucket policies, and CloudFront configurations follow predictable naming conventions, making audits and modifications straightforward.

Infrastructure Resource Summary

← All posts
Domain S3 Bucket CloudFront Dist ID DNS Provider
tech.queenofsandiego.com tech-queenofsandiego-com Created via init script Route53
tech.sailjada.com tech-sailjada-com Created via init script Route53