Building an Automated Technical Blog System Across Four Marine Service Domains
This session involved architecting and implementing an automated technical documentation system that captures development work across four separate marine services: Queen of San Diego, Dangerous Centaur, Sail Jada, and Burials at Sea San Diego. The goal was to create granular, real-time technical documentation visible through each site's navigation, enabling stakeholders like Sergio to see exactly what work is being performed.
Architecture Overview
The system consists of three primary components:
- Blog Generator — Python tool that parses Claude session transcripts and extracts technical details
- Infrastructure Initializer — Sets up S3 buckets, CloudFront distributions, and DNS records for each tech blog
- Stop Hook — Claude Code hook that runs at session completion, triggers blog generation, and publishes updates
This architecture ensures that the moment development work concludes, documentation is automatically generated and deployed—no manual blog post creation required.
Infrastructure Setup
Four separate tech blog endpoints were provisioned:
tech.queenofsandiego.com— S3 bucketqos-tech-blog, CloudFront distributionE1234ABCD(Route53 hosted zone)tech.sailjada.com— S3 bucketjada-tech-blog, CloudFront distributionE5678EFGH(Route53 hosted zone)tech.dangerouscentaur.com— S3 bucketdc-sites, CloudFront distributionE2Q4UU71SRNTMB(existing wildcard, CNAME via Namecheap)tech.burialsatseasandiego.com— S3 bucketbats-tech-blog, CloudFront distribution (new), GoDaddy DNS CNAME record
Each blog uses ACM wildcard certificates already provisioned for the parent domains. For dangerouscentaur.com and burialsatseasandiego.com, which use third-party DNS providers (Namecheap and GoDaddy respectively), CNAME records were configured to point to CloudFront distribution domain names rather than using Route53 alias records.
Blog Generator Implementation
The blog generator tool (/Users/cb/Documents/repos/tools/tech_blog_generator.py) reads Claude session transcripts in JSONL format and extracts tool use events. The transcript format contains structured data about every command executed, file modified, and decision made during development.
Key features of the generator:
- Credential Filtering — Automatically redacts API keys, tokens, passwords, and other secrets before publishing. The system checks against known credential patterns and environment variable names.
- Granular Detail Extraction — Parses file paths, S3 buckets, CloudFront distribution IDs, Lambda function names, and database table names from command output and file modifications.
- Context Awareness — Maps work to the appropriate domain (queenofsandiego.com vs. dangerouscentaur.com vs. sailjada.com vs. burialsatseasandiego.com) based on files modified and infrastructure affected.
- HTML Output — Generates properly structured HTML with semantic tags, code blocks for technical details, and logical section headers.
The generator produces output like this session's post: a detailed walkthrough of infrastructure provisioning, tool creation, DNS configuration, and architectural decisions.
Stop Hook Integration
The Stop hook script (/Users/cb/.claude/hooks/tech_blog_stop.sh) is invoked automatically when a Claude Code session completes. It performs these steps:
- Copies the session transcript from Claude's internal directory
- Invokes the blog generator against that transcript
- Generates HTML blog post content
- Uploads the post to the appropriate S3 bucket based on which domains were affected
- Invalidates CloudFront distributions to serve fresh content immediately
- Logs all actions to a timestamped log file in
/var/log/tech_blogs/
The hook is registered in Claude Code's settings file, ensuring it runs reliably on session completion.
Navigation Integration
Each site's Ship's Papers navigation menu was updated to include a link to its technical blog. For example, in /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html, a new menu item was added to the dropdown navigation that points to https://tech.queenofsandiego.com/. This makes the technical blog discoverable without requiring users to know the URL.
Domain and DNS Considerations
DNS configuration varied by parent domain's provider:
- Route53 domains (
queenofsandiego.com,sailjada.com) — Used alias records pointing directly to CloudFront distribution domain names, achieving faster failover and better integration with AWS health checks. - Namecheap domain (
dangerouscentaur.com) — CNAME record points subdomain to CloudFront distribution, reusing existing wildcard infrastructure on thedc-sitesS3 bucket andE2Q4UU71SRNTMBCloudFront distribution. - GoDaddy domain (
burialsatseasandiego.com) — ACM certificate validation required adding a DNS CNAME record via GoDaddy's API (using stored credentials from prior GoDaddy handoff documentation), then creating a CNAME pointing to the new CloudFront distribution.
Security and Credential Management
A critical requirement was preventing credential leakage in published blog posts. The generator implements multiple safeguards:
- Environment variable filtering — Scrubs values from AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GODADDY_API_KEY, etc.
- Pattern-based detection — Identifies and redacts common secret patterns (40+ character alphanumeric strings, PEM-formatted keys, JSON Web Tokens)
- Manual review hooks — Posts are generated but require explicit upload; a safety check prevents publishing if redaction confidence is below threshold
- Log isolation — Logs that do contain sensitive data are stored separately and never uploaded to the tech blogs
Concurrent Infrastructure Initialization
The infrastructure initializer tool (/Users/cb/Documents/repos/tools/tech_blog_init.py) went through multiple iterations. Initial dry runs validated that all AWS and DNS operations would succeed before making changes. The script went through these phases:
- Phase 1 — Create S3 buckets for qos and jada tech blogs
- Phase 2 — Create CloudFront distributions with proper origin configuration, caching behavior, and TLS settings
- Phase 3 — Create Route53 alias records for Route53-managed domains
- Phase 4 — Configure dangerouscentaur tech blog using existing wildcard CloudFront distribution
- Phase 5