Building a Multi-Domain Automated Technical Blog Pipeline for Real-Time Development Visibility

What Was Done

We implemented a complete automated technical blog generation system across four domain properties: tech.queenofsandiego.com, tech.dangerouscentaur.com, tech.sailjada.com, and tech.burialsatseasandiego.com. This system captures granular development session data and automatically publishes detailed technical posts within minutes of work completion, enabling stakeholders like Sergio to see exactly what was built, why, and how.

The solution extracts file modifications, executed commands, and reasoning from Claude Code session transcripts, filters out sensitive data, and publishes structured HTML articles to CloudFront-distributed S3 buckets. Navigation links were added to the Ship's Papers menu on each site.

Technical Details

Blog Generator Architecture

The core system consists of three Python components:

  • /Users/cb/Documents/repos/tools/tech_blog_generator.py — Parses JSONL session transcripts, extracts tool use entries, file modifications, and command history, then generates HTML articles with sanitization for credentials
  • /Users/cb/Documents/repos/tools/tech_blog_init.py — Infrastructure provisioning script that creates S3 buckets, CloudFront distributions, Route53 DNS records, and ACM certificates for all four tech blog domains
  • /Users/cb/.claude/hooks/tech_blog_stop.sh — Claude Code Stop hook that invokes the blog generator, uploads the post to S3, and invalidates CloudFront cache

The generator parses session transcripts from /Users/cb/.claude/projects/ in JSONL format, where each line contains structured tool-use and command-execution events. It filters entries to extract:

  • File write/edit operations with exact paths (e.g., /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html)
  • Command invocations and their stdout (e.g., AWS CLI calls, git operations)
  • Agent reasoning notes explaining decision rationale

Before publishing, the generator applies regex-based sanitization to remove API keys, credentials, tokens, GoDaddy/Namecheap API tokens, AWS secret keys, and database passwords. This ensures technical depth without security risk.

Infrastructure Provisioning

The init script creates resources for each domain using AWS CDK patterns and boto3:

  • S3 Buckets: Four site-specific buckets: qos-tech-blog, jada-tech-blog, dc-sites (existing, reused), and bats-tech-blog
  • CloudFront Distributions: All four tech blogs are origin-pull distributions with:
    • Default TTL of 3600 seconds (articles stay fresh without excessive API calls)
    • Cache invalidation support for immediate updates
    • Compression enabled for HTML/JSON payloads
  • ACM Certificates: Leveraged existing wildcard certs for *.queenofsandiego.com and *.sailjada.com; created new certs for *.dangerouscentaur.com and *.burialsatseasandiego.com
  • DNS Configuration: Route53 CNAME records for QOS and Jada; Namecheap CNAME for dangerouscentaur; GoDaddy CNAME for burialsatseasandiego (using API)

Session Data Capture

Claude Code hooks are configured in /Users/cb/.claude/settings.json to invoke tech_blog_stop.sh on session end. This script:

  1. Reads the current session transcript from the project memory directory
  2. Determines which domain(s) the session touched based on file paths
  3. Invokes the blog generator with the session transcript and domain mapping
  4. Uploads the generated HTML post to the appropriate S3 bucket
  5. Calls CloudFront invalidation to purge edge caches
  6. Logs all operations to ~/.claude/hooks/logs/tech_blog_stop.log

Infrastructure Changes and Resources

S3 Buckets Created:

  • s3://qos-tech-blog — Stores tech.queenofsandiego.com articles, versioning enabled
  • s3://jada-tech-blog — Stores tech.sailjada.com articles
  • s3://bats-tech-blog — Stores tech.burialsatseasandiego.com articles
  • s3://dc-sites — Existing bucket reused for tech.dangerouscentaur.com (separate prefix)

CloudFront Distributions:

  • QOS tech blog — Distribution ID: E[QOS_DIST_ID], origin: qos-tech-blog.s3.amazonaws.com
  • Jada tech blog — Distribution ID: E[JADA_DIST_ID], origin: jada-tech-blog.s3.amazonaws.com
  • Dangerouscentaur — Reuses existing E2Q4UU71SRNTMB, new origin behavior for /tech/*
  • BATS — Distribution ID: E[BATS_DIST_ID], origin: bats-tech-blog.s3.amazonaws.com

DNS Records Added:

  • QOS: Route53 CNAME tech.queenofsandiego.com → CloudFront domain
  • Jada: Route53 CNAME tech.sailjada.com → CloudFront domain
  • DC: Namecheap CNAME tech.dangerouscentaur.com → existing dangerouscentaur CloudFront
  • BATS: GoDaddy API call to create CNAME tech.burialsatseasandiego.com → CloudFront domain

Navigation Integration

The Ship's Papers dropdown menu in each site's index.html was updated to include a "Development Blog" link:

<li><a href="https://tech.queenofsandiego.com" target="_blank">Development Blog</a></li>

This appears as a submenu item under the Ship's Papers section, making it discoverable from the main navigation without cluttering the primary menu structure.

Key Decisions