Cloudpack series maps native linker innovations to JS bundling at Microsoft Teams scale (50k+ modules). Source: ~/workspace/wundler/ (kenotron-ms/cloudpack on GitHub). Series plan: 1. The Bundle Is Not a File (ThinLTO/mold/BOLT analogy) 2. The 2KB Module Summary (25x compression, content-addressed) 3. Dead Code That Actually Stays Dead (two-layer tree-shaking) 4. The Service Worker as ld.so (ABS delta delivery) 5. Your Users Are Teaching the Bundler (PGO from browser sessions) 6. Signing Manifests, Not Code (ed25519, threat model) Key receipts: 604ms warm rebuild at 10k modules, ~100MB for 50k module summaries (fits L3), ~50% CDN bandwidth saved per deploy. 🤖 Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
11 KiB
Crash Test Dev -- Agent Instructions
Standing Rules
Voice Linting Is Mandatory Before Publishing
Every piece of written content (blog posts, articles, lessons, patterns) MUST pass through the voice-check pipeline before it can be published. No exceptions.
Before creating or modifying any content in src/content/posts/:
- Draft the content
- Run mechanical lint:
./scripts/lint-voice.sh <file>- Must have 0 FAILURES to proceed
- Warnings are acceptable but should be acknowledged
- Run LLM judge: Delegate to self with
model_role: "critique"using the voice-check prompt at.amplifier/skills/voice-check/SKILL.md- Evaluates 8 dimensions: em-dash addiction, conviction posture, evidence instinct, narrative engine match, structural parallelism, opening quality, ending quality, personality presence
- Must reach PUBLISH or REVISE verdict (not REWRITE)
- Fix all failures before committing
- Re-run both checks after fixes to confirm
If the mechanical lint or LLM judge is skipped, the content is not published. This applies even if the user says "just publish it." Run the checks, report the results, and let the user decide whether to fix issues or publish anyway with full awareness of what's wrong.
What the Checks Catch
Mechanical lint (scripts/lint-voice.sh):
- Em-dash density (>5 per post = FAIL, Claude fingerprint)
- AI trigger words (delve, tapestry, nuanced, landscape, etc.)
- Hedging phrases ("it's worth noting", "one might argue")
- Unnecessary negative contrast ("doesn't just X. They Y" -- Claude crutch)
- Filler transitions ("in conclusion", "that being said")
- Resolution closers ("the key takeaway", "at the end of the day")
- Missing receipts (0 links + 0 code + 0 URLs in 500+ words = WARN)
- Sentence length uniformity (>70% same length = WARN)
LLM judge (voice-check skill):
- Voice match against
.amplifier/VOICE.mdprofile - Narrative engine (essay mode = AI default, enemy-narrative = Ken's default)
- Structural parallelism (too-clean bullet lists, tricolon patterns)
- Opening quality (problem/hook vs generic framing)
- Ending quality (restating intro = anti-pattern)
- Personality presence (humor, asides, self-awareness)
Voice Profile Reference
Ken's voice profile lives at .amplifier/VOICE.md. Key traits:
- Conviction: High, earned. States conclusions, doesn't hedge.
- Evidence: Receipt-shower. Links, code, data. Non-negotiable.
- Humor: Playful escalation + dry observation, sparse.
- Sentence rhythm: Short/long alternation, not uniform.
- Narrative: Enemy-narrative diagnostic is the default blog engine.
- Endings: End when done. Never restate the intro.
Em-Dash Budget
Ken's real writing uses 0-2 em-dashes per 1000 words. Claude defaults to 10-15 per 1000. The budget for this blog:
- 0-2 per post: Clean
- 3-5 per post: Acceptable, review each one
- 6+: FAIL. Kill at least half. Replace with periods, colons, or restructure.
When you find yourself typing an em-dash, stop and ask: would a period work here? It almost always does.
Visualization Pass Is Mandatory Before Publishing
Every post gets a visualization pass. The question is not "does this post need a diagram?" The question is "what would illustrate this better than prose?"
For every section of a post, ask:
-
Am I reaching for a bullet list? A diagram might replace it entirely. Bullet lists are a Claude default. Ken's real writing uses prose or visuals, not lists. If you have 3+ items that relate spatially or sequentially, draw them instead of listing them.
-
Am I describing a system, flow, or architecture? Draw it. Code an inline SVG following the diagram design spec, or use a
<Diagram>component. -
Am I comparing two things? A two-column visual or a before/after diagram beats a paragraph explaining the contrast.
-
Am I showing a progression or timeline? A flow diagram with labeled steps beats a numbered list every time.
-
Would a concept illustration anchor the section? Even a simple symbolic SVG (like the masterclass philosophy cards: hub-and-spoke, concentric circles, crossed-out icons) gives the reader a visual anchor.
What the visualization pass produces:
- A list of sections that would benefit from diagrams
- For each: what type (architecture, flow, comparison, concept) and a brief description of what the SVG should show
- Generate the SVGs inline using the diagram design spec (when it exists) or flag them for the author to describe
The rule: If a post has 1000+ words and zero visuals, that's a warning. Not every post needs diagrams, but every post should have been considered for them. The consideration is mandatory. The diagrams are not.
How visuals are made:
- Claude hand-codes SVGs using primitives (
<rect>,<line>,<text>,<circle>) following the diagram design spec constraints - Use the warm palette from DESIGN.md (paper background, brown-black ink, terracotta accent)
- Diagrams break wider than prose (840px vs 720px) using the code-block breakout pattern
- For interactive architecture graphs: DOT source + d3-graphviz runtime
- For concept art / visual targets: use image generation, then code SVG approximations toward the target
Project Context
- Site: Crash Test Dev (Astro blog at blog.ampbox.io / kenotron.github.io/crashtestdev)
- Author: Ken Chau (kenotron on GitHub, @kenneth_chau on Twitter)
- Content types: Posts (war stories), Patterns (reference), Lessons (progressive)
- Design system: DESIGN.md at project root (Google DESIGN.md spec-compliant)
- Aesthetic: "Workbench, not gallery" -- warm, grounded, un-digital
- Voice profile: .amplifier/VOICE.md
- Design specs: .design/AESTHETIC-GUIDE.md, .design/specs/
Content Pipeline
Idea / source material
|
v
Plan visuals FIRST: what diagrams, animations, or visuals
does this piece need? Static SVG? Animated (Remotion)?
Interactive (d3-graphviz)? Plan them alongside the outline,
not as an afterthought.
|
v
Draft post (src/content/posts/slug.md)
|
v
Mechanical lint: ./scripts/lint-voice.sh <file>
|
v
LLM judge: voice-check (8 dimensions)
|
v
Visualization pass: what would illustrate this better than prose?
|
v
Fix failures, add diagrams, re-check
|
v
Rebuild preview: rebuild /tmp/blog-dist, serve on :4321
|
v
Visual check at blog.ampbox.io
|
v
Commit + push
Content Organization: Book, Not Blog
The site is organized as a book of investigations, not a reverse-chronological feed. Inspired by makingsoftware.com. Key principles:
Topics, not dates. Content is grouped by investigation theme (e.g., "Rage: Rebuilding the Build System" is a 5-post series, not 5 unrelated entries). Dates are secondary metadata, not the primary navigation.
The homepage is a pitch, not an index. Lead with a compelling excerpt, a diagram, a question that creates intrigue. Show the reader what the content quality is like before presenting any navigation. A flat list of article cards is a cop-out. The homepage should make you curious.
Series are first-class. Multi-post series (like the Rage build system series) get their own landing page with a visual overview, progress indication, and cross-links between posts. Individual posts link to their series context.
Figure density matters. Target 1 visual per 300-500 words for technical posts. Not decoration, but content: architecture diagrams, flow charts, before/after comparisons, concept illustrations. If 500+ words pass without a visual, ask what would replace them.
No blog chrome. No comments, no share buttons, no "related posts" sidebar, no newsletter popups, no social proof widgets. The content quality is the credibility signal. If it needs a "clap" button, the writing isn't good enough.
Current Content Plan: Rage Series
Source: kenotron-ms/rage repo + ~/workspace/family/Work/Reference/BuildXL spec
| # | Title | Angle | Visuals Needed |
|---|---|---|---|
| 1 | Your Build Cache Is Lying to You | The silent stale cache problem. Make it concrete. | Flow: declared vs observed inputs. Before/after diagram of cache miss. |
| 2 | Two-Phase Fingerprinting: BuildXL's Deep Magic | WF→pathset→SF algorithm deep-dive. | Architecture: the two-phase lookup flow. Code walkthrough diagrams. |
| 3 | Hooking Syscalls Without a Kernel Driver | Three OS, three mechanisms. Most technically dense. | Side-by-side: macOS interpose / Linux eBPF / Windows Detours. Animated (Remotion): syscall interception flow. |
| 4 | TypeScript 7 Makes the Build Harness More Important | Counter-intuitive thesis. Widest reach. | Comparison: single-machine vs distributed. The parallelism table as a visual. |
| 5 | node_modules in a Content-Addressed Store | The unsexy problem that kills CI. | Flow: lockfile → CAS → hardlink restore. Before/after CI times. |
| 6 | What I Learned Maintaining Lage and Why I Rewrote It | Personal narrative, meta post. | Timeline: lage → BuildXL integration hack → rage. |
Each post stands alone but gains context from the series. The series landing page shows progress (like makingsoftware.com's progress bar) and creates anticipation for upcoming posts.
Current Content Plan: Cloudpack Series
Source: ~/workspace/wundler/ (kenotron-ms/cloudpack on GitHub) + architect brief + exec summary
The core idea: the bundle is not a file, it's a query against a continuously-maintained module graph. The architecture maps native linker innovations (ThinLTO, mold, BOLT/Propeller) to JavaScript bundling at Microsoft Teams scale (50k+ modules).
| # | Title | Angle | Visuals Needed |
|---|---|---|---|
| 1 | The Bundle Is Not a File | Linker-world analogy. ThinLTO/mold/BOLT mapped to JS bundling. "Database, not compiler." | Architecture: the 3-phase pipeline. Side-by-side: linker innovation → bundler equivalent. |
| 2 | The 2KB Module Summary That Replaced a Full Parse | ModuleSummary as the core data structure. 25x compression. Content-addressed cache. | Diagram: source file (50KB) → ModuleSummary (2KB). The rayon parallel loop. |
| 3 | Dead Code That Actually Stays Dead | Two-layer tree-shaking: module-level (conservative) + function-level (aggressive via call-edge graph). SideEffectMarker AST analysis. | Flow: BFS reachability + Tarjan SCC + call-edge DCE walk. Before/after module counts. |
| 4 | The Service Worker as ld.so | Adaptive Bundle Service. Delta manifests. Browser tells server what it has, server returns only what's missing. | Architecture: CDN chunks as shared libraries, SW as dynamic linker. Delta computation flow. |
| 5 | Your Users Are Teaching the Bundler | Profile-Guided Optimization from real browser sessions. C³ co-request clustering. SQLite co-request matrix. Prefetch without rebuild. | The feedback loop: browser sessions → JSONL → SQLite → C³ clustering → manifest hints. |
| 6 | Signing Manifests, Not Code | Ed25519 signing of chunk hashes. Threat model: ABS compromise ≠ code injection. PGO fields excluded from signature. | Security model diagram: what's signed, what's not, what an attacker can/can't do. |
Key numbers for receipts:
- 10k modules warm rebuild: 604ms analysis-only
- 50k modules in memory as summaries: ~100MB (fits L3 cache)
- ABS delivery: ~50% CDN bandwidth saved per deploy
- 50k modules, 10k DAU, 1% weekly churn: saves ~47 GB/week