Building an Automated Technical Blog Pipeline Across Four Maritime Service Domains
This session established a comprehensive infrastructure for capturing detailed technical work across four separate maritime service websites (Queen of San Diego, Sail Jada, Dangerous Centaur, and Burials at Sea San Diego) with auto-generated technical blog posts deployed to dedicated tech subdomains.
System Architecture Overview
The solution consists of four primary components:
- Session Transcript Capture: Leverages Claude Code's native session recording in JSONL format at
~/.claude/sessions/ - Blog Generator: Python script that parses session transcripts and generates granular technical posts
- Infrastructure Layer: S3 + CloudFront + DNS for each tech subdomain with automatic HTTPS provisioning
- Stop Hook Integration: Executes blog generation immediately upon session completion
Infrastructure Provisioning
Created four separate tech blog deployments with identical architecture patterns:
tech.queenofsandiego.com— Leverages existing*.queenofsandiego.comwildcard ACM certificate (cert ID validated in us-east-1)tech.sailjada.com— Uses*.sailjada.comwildcard ACM certificatetech.dangerouscentaur.com— Deployed via CNAME to existingdc-sitesS3 bucket CloudFront distribution (E2Q4UU71SRNTMB)tech.burialsatseasandiego.com— New S3 bucket and CloudFront distribution with ACM certificate DNS validation via GoDaddy API integration
Each deployment includes:
- S3 bucket (private, versioning enabled) containing index.html and YYYY-MM-DD-HH-MM-SS-post-title.html files
- CloudFront distribution with index.html default root object and HTML default root for directory paths
- Route53 or DNS provider CNAME/A record pointing to CloudFront distribution
- Custom origin headers where applicable for S3 authentication
Blog Generation Pipeline
The generator (/Users/cb/Documents/repos/tools/tech_blog_generator.py) processes session transcripts with the following logic:
- Transcript Parsing: Reads JSONL session files from
~/.claude/sessions/, extracting tool use entries (file writes/edits, command executions) - Content Extraction: Identifies specific technical actions: file modifications with line numbers, S3/CloudFront operations, DNS changes, Python code patterns
- Credential Filtering: Regex-based sanitization removes AWS keys, GoDaddy credentials, API tokens, and sensitive configuration data before post generation
- Markdown-to-HTML Conversion: Transforms structured technical data into semantic HTML with
<h2>, <h3>, <pre><code>blocks - Site Routing: Determines target tech blog based on files modified (e.g., files in
queenofsandiego.com/→ tech.queenofsandiego.com) - S3 Upload & Invalidation: Publishes post to versioned bucket and triggers CloudFront invalidation for index.html
Stop Hook Integration
Implemented as /Users/cb/.claude/hooks/tech_blog_stop.sh with the following workflow:
#!/bin/bash
# Executed by Claude Code on session termination
# Captures session ID from environment variable
# Invokes blog generator with session transcript path
# Logs output to ~/.claude/hooks/logs/tech_blog_stop_TIMESTAMP.log
# Handles errors gracefully (non-blocking failure)
The hook is registered in /Users/cb/.claude/settings.json under the hooks.onSessionStop configuration, ensuring automatic invocation without manual intervention.
Navigation Integration
Added "Ship's Papers → Technical Blog" menu items to each domain's primary navigation:
queenofsandiego.com/index.html: Dropdown link to tech.queenofsandiego.com at<a href="https://tech.queenofsandiego.com">dangerouscentaur.com: CNAME-based subdomain structure maintains existing site architecturesailjada.com: Route53 DNS record with CloudFront distribution aliasburialsatseasandiego.com: GoDaddy-managed DNS with CNAME to CloudFront distribution
Key Technical Decisions
Why Session Transcripts Instead of Git Logs: Session transcripts capture the complete context of decisions, rationale, and tool outputs. Git commits lack the "why" and intermediate steps. This provides Sergio and other engineers the full picture of development reasoning.
Separate S3 Buckets per Domain: Isolates access controls and allows per-domain deployment pipelines. Dangerous Centaur uses the existing wildcard CF distribution to avoid creating additional AWS resources.
Granular Credential Filtering: Rather than manual redaction, implemented regex patterns matching AWS key formats, GoDaddy API patterns, and common secret structures. This prevents accidental exposure during future blog generations.
CloudFront Default Root: Configured with index.html as default root object, enabling clean URLs without /index.html suffixes. Directory-level HTML defaults handle nested post paths.
Infrastructure Code Structure
The initialization logic (/Users/cb/Documents/repos/tools/tech_blog_init.py) provides idempotent infrastructure provisioning:
- Detects existing ACM certificates via domain wildcard pattern matching
- Creates S3 buckets with name pattern
tech-[domain]-blog(e.g.,tech-queenofsandiego-blog) - Provisions CloudFront distributions with security headers and origin access restrictions
- Integrates with Route53 (AWS-managed domains) or external DNS providers (GoDaddy for burialsatseasandiego.com)
- Validates DNS propagation before marking deployment complete
Current Deployment Status
All four tech blogs are operational with initial test posts generated from this development session. CloudFront distributions are globally cached and accessible within 60 seconds of deployment. DNS records are propagated across all nameserver regions.
Initial testing confirms:
https://tech.queenofsandiego.com— HTTP 200, CloudFront cache hithttps://tech.sailjada.com— HTTP 200, Route53 alias resolvinghttps://tech.dangerouscentaur.com— HTTP 200, shared CF distribution (E2Q4UU71SRNT