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.comand*.sailjada.com) already provisioned in ACM. This meant we could immediately createtech.queenofsandiego.comandtech.sailjada.comwithout certificate delays. - dangerouscentaur.com: Already had a wildcard CloudFront distribution (ID:
E2Q4UU71SRNTMB) pointing to thedc-sitesS3 bucket. We leveraged this existing distribution rather than creating a new one, adding a/techprefix 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