Building Automated Technical Documentation: Multi-Site Blog Generation Infrastructure
What Was Done
We implemented a comprehensive automated technical blog generation system across four domains (queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com) that captures detailed session-by-session development work and publishes it automatically to dedicated tech subdomains. The system integrates with Claude's session transcripts, extracts granular technical details, and publishes formatted blog posts without exposing credentials or sensitive data.
Architecture Overview
The system consists of three core components:
- Session Hook Integration: A stop hook script that executes at the end of each Claude development session
- Blog Generation Engine: A Python-based generator that parses session transcripts, extracts technical details, and formats them as HTML articles
- Cloud Infrastructure: S3 buckets, CloudFront distributions, and DNS configurations for each tech blog subdomain
Technical Details
Session Transcript Processing
The generation system reads Claude Code session transcripts stored in JSONL format at /Users/cb/.claude/projects/[project-path]/sessions/. Each session file contains structured tool use entries with the following pattern:
{"type": "tool_use", "name": "[tool_name]", "input": {...}, "output": "..."}
{"type": "text", "text": "..."}
The generator parses these entries to extract:
- File modifications (paths, operations)
- Commands executed (without credential exposure)
- Infrastructure changes (AWS resources, DNS records)
- Technical decision points
Credential Filtering
Before publishing, the system sanitizes all output through multiple filters:
- Regex patterns matching common credential formats (API keys, tokens, passwords)
- Environment variable redaction (any `$VAR` references)
- AWS credential patterns (access keys, secret keys)
- SSH key material detection
- Domain credentials and authentication tokens
This ensures that sensitive data from development work (like GoDaddy API credentials, AWS IAM keys, or ACM certificate details) never reaches published blog posts.
Blog Generator Implementation
File: /Users/cb/Documents/repos/tools/tech_blog_generator.py
The generator takes a session transcript and produces formatted HTML articles with:
- Structured sections (What Was Done, Technical Details, Infrastructure, Key Decisions)
- Granular technical specificity (exact file paths, bucket names, distribution IDs)
- Command examples and code snippets
- Explanations of architectural choices
- Links to related resources where applicable
The generator maintains context about each domain (queenofsandiego.com, sailjada.com, etc.) and filters content appropriately—for example, only including burialsatseasandiego.com-related work in posts destined for tech.burialsatseasandiego.com.
Infrastructure Initialization
File: /Users/cb/Documents/repos/tools/tech_blog_init.py
This script provisions cloud infrastructure for each tech blog subdomain. For each domain, it creates:
- S3 Bucket: Named pattern `{domain}-tech-blog` (e.g., `queenofsandiego-tech-blog`, `sailjada-tech-blog`). Configured with:
- Block public access settings
- Website endpoint configuration
- CORS headers for cross-domain requests
- CloudFront Distribution:
- S3 origin pointing to the tech blog bucket
- HTTP to HTTPS redirect
- Cache behaviors optimized for HTML static content (24-hour TTL)
- Associated with existing ACM wildcard certificate (e.g., `*.queenofsandiego.com`)
- DNS Records:
- Route53: For queenofsandiego.com and sailjada.com—created CNAME records pointing to CloudFront distribution domains
- Namecheap: For dangerouscentaur.com—added CNAME record `tech.dangerouscentaur.com` → CloudFront distribution
- GoDaddy: For burialsatseasandiego.com—added CNAME record pointing to CloudFront distribution
Session Hook Integration
File: /Users/cb/.claude/hooks/tech_blog_stop.sh
This bash script executes when a Claude Code session ends. It:
- Detects the active project context
- Locates the most recent session transcript
- Invokes the blog generator with appropriate domain filtering
- Uploads the generated HTML to the corresponding S3 bucket using AWS CLI
- Invalidates the CloudFront distribution cache to ensure immediate visibility
- Logs all operations to
/Users/cb/.claude/logs/tech_blog_hook.logfor debugging
The hook is registered in Claude Code settings file /Users/cb/.claude/settings.json with:
"hooks": {
"session_stop": "/Users/cb/.claude/hooks/tech_blog_stop.sh"
}
Domain-Specific Configurations
Each domain maintains its own infrastructure configuration stored in /Users/cb/.claude/projects/-Users-cb-Documents-repos/memory/project_tech_blogs.md:
- queenofsandiego.com: Route53 hosted zone, wildcard cert `*.queenofsandiego.com`, CloudFront distribution for tech subdomain
- sailjada.com: Route53 hosted zone, wildcard cert `*.sailjada.com`, CloudFront distribution for tech subdomain
- dangerouscentaur.com: Namecheap DNS, wildcard CloudFront distribution `E2Q4UU71SRNTMB` on `dc-sites` S3 bucket
- burialsatseasandiego.com: GoDaddy DNS (verified via domain handoff notes), ACM certificate with DNS validation via GoDaddy API
Key Decisions
Why CloudFront instead of direct S3 hosting? CloudFront provides HTTPS support, caching for performance, and a unified distribution approach. It allows us to use wildcard certificates and manages DNS complexity across multiple registrars (Route53, Namecheap, GoDaddy).
Why filter at generation time rather than runtime? Filtering during generation ensures blogs are clean before publication and reduces the risk of credential leakage through any misconfiguration. It also improves blog readability by removing technical noise unrelated to each domain.