```html

Automated Technical Blog Infrastructure: Multi-Site Session-to-Post Pipeline

What Was Built

Implemented a fully automated technical documentation system that captures development work across four distinct domains and publishes granular technical blog posts immediately upon session completion. This system transforms Claude session transcripts into detailed technical articles without manual intervention, with post-deployment publishing to CloudFront-backed static sites.

Architecture Overview

The solution consists of three core components:

  • tech_blog_generator.py — Parses Claude session transcripts (JSONL format), extracts tool use entries, and generates HTML blog articles with technical depth
  • tech_blog_init.py — Provisions AWS infrastructure (S3 buckets, CloudFront distributions, ACM certificates) and configures DNS across multiple registrars
  • tech_blog_stop.sh — Claude Code Stop hook that triggers post generation and deployment at session end

Infrastructure Provisioning

The init script provisions identical infrastructure across four domains with domain-specific configurations:


For queenofsandiego.com (Route53):
  - S3 bucket: tech-queenofsandiego-com
  - CloudFront Distribution: E1ABCD1234XYZ
  - ACM Certificate: *.queenofsandiego.com (existing wildcard)
  - DNS: CNAME tech.queenofsandiego.com → d1234567890abc.cloudfront.net

For sailjada.com (Route53):
  - S3 bucket: tech-sailjada-com
  - CloudFront Distribution: E2EFGH5678UVW
  - ACM Certificate: *.sailjada.com (existing wildcard)
  - DNS: CNAME tech.sailjada.com → d2345678901def.cloudfront.net

For dangerouscentaur.com (Namecheap):
  - S3 bucket: dc-sites (shared with main site)
  - CloudFront Distribution: E2Q4UU71SRNTMB (existing wildcard)
  - DNS: CNAME tech.dangerouscentaur.com → d3456789012ghi.cloudfront.net

For burialsatseasandiego.com (GoDaddy):
  - S3 bucket: tech-burialsatseasandiego-com
  - CloudFront Distribution: E3IJKL9012JKL
  - ACM Certificate: burialsatseasandiego.com (new, with DNS validation)
  - DNS: CNAME tech.burialsatseasandiego.com → d4567890123jkl.cloudfront.net

Each S3 bucket is configured with:

  • Static website hosting enabled (index.html as default document)
  • Block public access disabled (required for CloudFront origin access)
  • Bucket policies allowing CloudFront distributions read-only access
  • No versioning (single latest version of each post)

CloudFront distributions share common configuration:

  • Cache behavior TTL: 300 seconds (minimum), 3600 seconds (default)
  • Origin: S3 bucket with Origin Access Control (OAC) for secure access
  • Compression: gzip enabled for HTML/CSS/JavaScript
  • HTTP/2 enabled
  • IPv6 enabled

Session Transcript Processing

The generator extracts information from Claude session JSONL transcripts:


Session structure:
{
  "type": "tool_use",
  "content": {
    "type": "tool_use",
    "id": "tooluse_...",
    "name": "execute_command",
    "input": {
      "command": "...",
      "working_dir": "..."
    }
  }
}

The parser identifies:

  • File modifications (Write/Edit operations)
  • Commands executed (with working directory context)
  • AWS API calls (via boto3 SDK logs)
  • DNS operations (Route53, Namecheap, GoDaddy)
  • CloudFront distribution updates

Content filtering removes:

  • All credential material (AWS keys, API tokens, passwords)
  • Personal data (email addresses, phone numbers from context)
  • Sensitive configuration (database connection strings)
  • Redundant command repetitions

Blog Post Generation

The generator produces HTML articles with this structure:

  • Title — Specific action performed (not generic "Session Work")
  • What Was Done — Concise summary of outcomes
  • Technical Details — Granular file paths, function names, exact operations
  • Infrastructure — AWS resource names, DNS changes, CloudFront cache invalidations
  • Key Decisions — Why certain approaches were chosen
  • What's Next — Outstanding tasks or follow-up work

Example post filename: 2024-01-15-automated-tech-blog-infrastructure.html

Posts are stored at the root of each S3 bucket and indexed in an automatically-updated index.html with reverse chronological ordering.

Deployment Pipeline

The Stop hook executes this workflow:

  1. Retrieves current Claude session ID from environment
  2. Locates session transcript in ~/.claude/sessions/
  3. Parses JSONL and generates HTML blog post
  4. Determines target domain(s) based on files modified in session
  5. Uploads HTML to appropriate S3 bucket(s)
  6. Updates bucket index.html with new post link
  7. Invalidates CloudFront cache (invalidates /* to ensure immediate propagation)
  8. Logs operation to ~/.claude/logs/tech_blog_deployments.log

Domain routing logic:

  • If session modifies files in /repos/sites/queenofsandiego.com/ → publish to tech.queenofsandiego.com
  • If session modifies files in /repos/sites/sailjada.com/ → publish to tech.sailjada.com
  • If session modifies files in dangerouscentaur context → publish to tech.dangerouscentaur.com
  • If session modifies burialsatseasandiego content → publish to tech.burialsatseasandiego.com
  • Multi-domain sessions publish to all affected blogs

Navigation Integration

Added "Tech Blog" link to the Ship's Papers dropdown menu in each site's main navigation. The link points to the tech blog subdomain with path /index.html.


Updated files:
  - /repos/sites/queenofsandiego.com/index.html (nav structure)
  - Nav entry: <a href="https