```html

Building Automated Technical Blog Infrastructure for Four Sailing & Maritime Sites

What Was Done

Created a fully automated technical blog generation system that captures development work across four maritime-focused websites in real-time. The system monitors Claude Code development sessions, extracts technical details, and publishes granular blog posts to dedicated tech subdomains without requiring manual intervention or credential exposure.

Deployed infrastructure for:

  • tech.queenofsandiego.com
  • tech.sailjada.com
  • tech.dangerouscentaur.com
  • tech.burialsatseasandiego.com

Technical Architecture

Blog Generation Pipeline

The system consists of three Python tools working in concert:

  • tech_blog_init.py — Infrastructure provisioning script that creates S3 buckets, CloudFront distributions, DNS records, and ACM certificates for each blog domain
  • tech_blog_generator.py — Core blog generation engine that parses Claude Code session transcripts (JSONL format), extracts tool use entries, filters out credentials, and generates HTML blog posts
  • tech_blog_stop.sh — Stop hook executed by Claude Code after each development session, triggering blog generation and deployment

Additionally, two monitoring tools were created for operational oversight:

  • email_template_validator.py — Validates email template syntax and structure before deployment to production
  • jada_unsubscribe_monitor.py — Tracks unsubscribe events and maintains subscriber list hygiene across campaigns

Session Transcript Processing

Claude Code saves development sessions as JSONL (JSON Lines) files in /Users/cb/.claude/projects/. Each session contains:

  • File modification events (path, operation type, timestamp)
  • Command executions (command name, arguments, results)
  • Tool use entries (function calls, parameters, results)
  • Agent reasoning and decision logs

The blog generator parses these transcripts, identifies technical work (file edits, infrastructure commands, deployment steps), sanitizes sensitive data, and structures it into chronological blog posts. This approach captures granular detail automatically — no manual summarization required.

Infrastructure Deployment

DNS & Certificate Strategy

Each blog domain reuses existing wildcard ACM certificates where available:

  • queenofsandiego.com: Uses existing *.queenofsandiego.com wildcard certificate via Route53 DNS validation
  • sailjada.com: Uses existing *.sailjada.com wildcard certificate via Route53 DNS validation
  • dangerouscentaur.com: Leverages existing wildcard CloudFront distribution (E2Q4UU71SRNTMB) on dc-sites S3 bucket; requires Namecheap CNAME record for tech.dangerouscentaur.com
  • burialsatseasandiego.com: New certificate and CloudFront distribution; DNS managed at GoDaddy (not AWS Route53), requiring ACM DNS validation CNAME entry in GoDaddy's control panel

S3 & CloudFront Structure

Each blog gets its own S3 bucket following naming convention {site}-tech-blog:

  • queenofsandiego-tech-blog → served via CloudFront → tech.queenofsandiego.com
  • sailjada-tech-blog → served via CloudFront → tech.sailjada.com
  • dc-sites → wildcard CloudFront distribution → tech.dangerouscentaur.com
  • bats-tech-blog → served via CloudFront → tech.burialsatseasandiego.com

S3 buckets are configured for static website hosting with public read access on index HTML files. CloudFront distributions enforce HTTPS-only access and include cache invalidation triggers on deployment.

DNS Nameserver Mapping

Due to different DNS providers:

  • Route53-managed domains: queenofsandiego.com, sailjada.com — Direct alias records point to CloudFront distributions
  • Namecheap-managed domain: dangerouscentaur.com — CNAME records point to CloudFront domain names
  • GoDaddy-managed domain: burialsatseasandiego.com — Both ACM validation CNAME and blog CNAME records configured

Integration with Existing Sites

Each main website received navigation updates to expose the tech blog:

  • queenofsandiego.com/index.html — Added "Tech Blog" link under Ship's Papers menu dropdown
  • dangerouscentaur.com — Updated navigation structure to include tech blog link
  • sailjada.com — Added tech blog reference to main navigation
  • burialsatseasandiego.com — Integrated tech blog link into site header

These changes ensure that stakeholders (like Sergio) can easily access detailed technical documentation about ongoing development work.

Key Technical Decisions

JSONL Session Format

Claude Code's native session format is JSONL — one JSON object per line. This format enables streaming processing without loading entire files into memory, critical for large development sessions. The generator reads line-by-line, identifies relevant tool use and file modification events, and extracts structured data.

Credential Filtering Strategy

The blog generator implements multiple filtering layers:

  • Redacts common credential patterns (API keys, tokens, passwords)
  • Filters file paths under .claude/ and .env files
  • Removes GoDaddy/AWS credential references from command output
  • Excludes sensitive environment variable values

This allows publishing granular technical details without exposing secrets — developers see exactly what was done, but not how to do it themselves without authorization.

Stop Hook Timing

The stop hook (tech_blog_stop.sh) executes when exiting a Claude Code session, ensuring blog posts are generated immediately after work completes. This creates a natural, real-time publishing workflow without requiring manual intervention or cron jobs.

Deployment Commands

Infrastructure provisioning for all four sites:

python /Users/cb/Documents/repos/tools/tech_blog_init.py \
  --sites queenofsandiego sailjada dangerouscentaur burialsatseasandiego \
  --region us-west-2 \
  --enable-cloudfront-