```html

Building an Automated Technical Blog System Across Four Maritime Domain Properties

This session involved architecting and implementing a comprehensive system to automatically generate granular technical blog posts across four separate domain properties: queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com. The goal was to create a transparent record of all development work that could be audited by stakeholders like Sergio, capturing implementation details rather than high-level summaries.

System Architecture Overview

The system consists of three core components:

  • Stop Hook Script (/Users/cb/.claude/hooks/tech_blog_stop.sh) — Automatically triggered when Claude sessions end, capturing the session transcript
  • Infrastructure Initialization Script (/Users/cb/Documents/repos/tools/tech_blog_init.py) — Provisions S3 buckets, CloudFront distributions, and DNS records for each tech blog domain
  • Blog Generator (/Users/cb/Documents/repos/tools/tech_blog_generator.py) — Parses JSONL session transcripts, extracts tool usage and file modifications, and generates HTML articles

Infrastructure Provisioning Decisions

Each of the four maritime properties needed its own technical blog subdomain. The infrastructure decisions reflect careful consideration of existing AWS resources:

  • queenofsandiego.com and sailjada.com: Both had existing wildcard SSL certificates (*.queenofsandiego.com and *.sailjada.com) already provisioned in ACM. This meant we could immediately create tech.queenofsandiego.com and tech.sailjada.com without certificate delays.
  • dangerouscentaur.com: Already had a wildcard CloudFront distribution (ID: E2Q4UU71SRNTMB) pointing to the dc-sites S3 bucket. We leveraged this existing distribution rather than creating a new one, adding a /tech prefix route.
  • burialsatseasandiego.com: Uses GoDaddy for DNS management (not Route53). The infrastructure script automatically detects GoDaddy-managed domains and uses the GoDaddy API to add CNAME records for ACM certificate validation, then creates the CloudFront distribution once the certificate is validated.

S3 Bucket and CloudFront Configuration

For each domain, the init script creates:

aws s3api create-bucket \
  --bucket tech-[domain]-sites \
  --region us-west-2 \
  --create-bucket-configuration LocationConstraint=us-west-2

aws cloudfront create-distribution \
  --distribution-config file://cf-config.json

The CloudFront distributions use origin access control (OAC) to securely serve content from S3 without public bucket permissions. Each distribution is configured with:

  • Default root object: index.html
  • Custom domain CNAME records
  • Gzip compression enabled for HTML, CSS, and JavaScript
  • Cache TTLs: 3600 seconds for HTML (allowing frequent updates), 86400 for static assets
  • HTTP/2 and HTTP/3 support

Session Transcript Parsing and Blog Generation

The blog generator parses Claude's JSONL session transcript format to extract:

  • File modifications: Reads entries where "type": "write" or "type": "edit", capturing file paths and operation types
  • Tool executions: Identifies "type": "tool_use" entries to document AWS CLI commands, API calls, and system operations performed
  • Commands run: Extracts "type": "command" entries showing all commands executed in the session
  • Context window: Extracts the session's initial request to understand the business goal

The generator filters out sensitive data patterns before publishing:

  • AWS credentials and tokens
  • API keys and authentication headers
  • Personal credentials (GoDaddy, Namecheap, etc.)
  • Private IP addresses and internal hostnames
  • Database connection strings

Integration with Ship's Papers Navigation

The main index.html files for each property were updated to include a "Technical Blog" link in the Ship's Papers dropdown menu. For queenofsandiego.com, the navigation structure was updated from:

<li><a href="/ship's-papers">Ship's Papers</a>
  <ul class="dropdown">
    <li><a href="/captains-log">Captain's Log</a></li>
    <li><a href="/concert-nights">Concert Nights</a></li>
  </ul>
</li>

To include:

<li><a href="/ship's-papers">Ship's Papers</a>
  <ul class="dropdown">
    <li><a href="/captains-log">Captain's Log</a></li>
    <li><a href="/concert-nights">Concert Nights</a></li>
    <li><a href="https://tech.queenofsandiego.com">Technical Blog</a></li>
  </ul>
</li>

Claude Code Hook Integration

The stop hook script was registered in Claude Code's configuration at /Users/cb/.claude/settings.json, ensuring it runs automatically at the end of each session. The hook:

  • Captures the current session transcript
  • Invokes the blog generator
  • Determines which domain(s) the work affects based on file paths modified
  • Uploads the generated HTML article to the appropriate S3 bucket
  • Invalidates the CloudFront distribution cache to ensure immediate visibility

Key Decisions and Rationale

  • Automatic generation on session end: Rather than requiring manual blog post creation, the hook runs automatically. This ensures no work is forgotten and reduces friction for documentation.
  • Granular, not summarized: The generator includes specific file paths, function names, and command examples. This allows Sergio to understand exactly what was changed and why, supporting detailed code reviews and audits.
  • Reusing existing infrastructure: Rather than creating new CloudFront distributions and certificates where they already existed, we leveraged what was in place. The dangerouscentaur setup particularly benefits from this approach since it already had a wildcard cert and distribution.
  • GoDaddy integration: Detecting and using