Building an Auto-Generated Technical Blog System Across Four Domain Properties
This session involved architecting and implementing a comprehensive technical documentation system that auto-generates detailed blog posts from development session transcripts. The system captures granular technical work across four separate domain properties: queenofsandiego.com, sailjada.com, dangerouscentaur.com, and burialsatseasandiego.com, with each property getting its own dedicated tech blog subdomain.
The Challenge
The requirement was to create a mechanism that:
- Automatically captures detailed, granular technical work from each development session
- Generates blog posts immediately upon session completion (via Claude Code Stop hook)
- Publishes to domain-specific tech subdomains accessible from each site's navigation
- Filters out all credentials, API keys, and sensitive data
- Makes technical decisions and infrastructure changes transparent to stakeholders like Sergio
- Scales across four separate properties without manual intervention
System Architecture
The solution consists of four main components:
- Session Capture Hook: A bash script that triggers when Claude Code sessions end, extracting the session transcript
- Blog Generator: A Python tool that parses session transcripts (JSONL format) and generates detailed HTML articles
- Infrastructure Init: A setup script that provisions S3 buckets, CloudFront distributions, and DNS records for each tech blog subdomain
- Claude Code Integration: Settings configuration that registers the Stop hook globally
Infrastructure Implementation
Each tech blog required identical infrastructure components:
- S3 Buckets: Created dedicated buckets following the pattern
tech-{property}-site(e.g.,tech-qos-site,tech-jada-site,tech-dc-site). Buckets configured for static website hosting with index.html as the default document. - CloudFront Distributions: Provisioned distributions pointing to each S3 bucket origin. For
tech.queenofsandiego.comandtech.sailjada.com, leveraged existing wildcard ACM certificates (*.queenofsandiego.comand*.sailjada.comrespectively). Fortech.dangerouscentaur.com, integrated with the existing wildcard CloudFront distribution (ID: E2Q4UU71SRNTMB) pointing to thedc-sitesS3 bucket. - DNS Configuration: For AWS-managed zones (queenofsandiego.com and sailjada.com via Route53), created alias records pointing to CloudFront distribution domain names. For GoDaddy-managed domains (dangerouscentaur.com and burialsatseasandiego.com), added CNAME records pointing to their respective CloudFront distribution endpoints.
- ACM Certificate Validation: The burialsatseasandiego.com setup required DNS validation since it uses GoDaddy's nameservers. Added the ACM-generated CNAME validation record directly to GoDaddy DNS to complete certificate provisioning for CloudFront.
The Blog Generator Pipeline
The generator works in several stages:
Stage 1 - Session Transcript Extraction: The Stop hook script captures the Claude Code session ID and logs directory path. It invokes the generator with the session identifier. The generator reads the JSONL-formatted transcript file (stored at ~/.claude/sessions/{session-id}.jsonl), which contains all tool calls, prompts, and responses from the session.
Stage 2 - Content Parsing: The Python generator iterates through transcript entries, extracting:
- Tool use blocks containing command executions and file operations
- File modifications with their paths and operations (read, write, edit)
- Command executions showing exactly what was run
- Agent reasoning explaining the why behind decisions
Stage 3 - Credential Filtering: Before rendering, the generator sanitizes content by:
- Removing credential references from memory/reference files
- Stripping actual values from environment variables
- Filtering out API keys, tokens, and secrets
- Preserving technical details like file paths, resource names, and architecture decisions
Stage 4 - HTML Generation: The generator creates semantically structured HTML articles with:
- Descriptive h2 titles specific to the work completed
- Clear section hierarchy using h3 tags
- Bulleted lists for files, commands, and decisions
- Code blocks (pre/code tags) for exact command examples and file paths
- Narrative explanations of architectural decisions and technical reasoning
Stage 5 - Domain Routing and Publishing: The generator determines the target domain by:
- Scanning file paths in the transcript for domain-specific markers
- Matching patterns like
/repos/sites/queenofsandiego.com/to the queenofsandiego property - Uploading the generated HTML to the appropriate S3 bucket (e.g., tech-qos-site)
- Invalidating the CloudFront distribution to ensure cache refresh
- If multiple domains are touched, generating separate posts for each property
Claude Code Integration
The Stop hook is registered in Claude Code's settings file at ~/.claude/settings.json under the hooks configuration. When any development session ends, Claude Code automatically executes tech_blog_stop.sh, which:
- Determines the current session ID from Claude's environment
- Checks if a transcript exists and contains substantive work
- Invokes the generator with appropriate parameters
- Logs execution results for debugging and audit purposes
Navigation Integration
Each primary site's navigation menu was updated to include a "Ship's Papers → Tech Blog" link. For queenofsandiego.com, this required editing the index.html to add a new menu item pointing to https://tech.queenofsandiego.com/. Similar changes were applied to each site's main navigation structure, making the technical documentation visible alongside operational ship's papers and event information.
Configuration and Storage
Infrastructure details (S3 bucket names, CloudFront distribution IDs, Route53 zone IDs) are stored in a structured configuration file accessible to the generator. This allows the Stop hook to look up the correct destination bucket and distribution for cache invalidation without hardcoding values. The configuration separates properties cleanly, enabling future additions of new domain properties without code changes.
Key Architectural Decisions
- Session-Based Triggering: Rather than continuous monitoring, posts are generated immediately when work sessions end. This captures complete, contextual work units.
- JSONL Transcript Parsing: Claude Code stores transcripts in JSONL format with structured tool use entries. This allows programmatic extraction of exactly what happened without ambiguity.
- Multi-Domain Strategy: Each property gets its own S3 bucket and CloudFront distribution, maintaining clear separation of concerns and allowing independent scaling and access control