Rage: The real story is combining lage's dev ergonomics with BuildXL's
correctness at scale. Ken has wanted this synthesis for years since
co-creating lage. Frame the series around ergonomics vs correctness.
Cloudpack benchmarking: synthetic codebases generated from observed
attributes of real shipping code. Pipeline: observe real repo → produce
BenchProfile JSON → corpus_gen creates deterministic synthetic codebase
(same seed = byte-identical) → corpus_verify confirms conformance →
benchmark at various scales (100 to 50k modules).
Three TypeScript module variants (barrel, intermediate, leaf) with
realistic import structures, side effects, and ambient refs. JSON
configs, markdown docs fill out the shape. Tolerances: 2% file count,
5% byte/line count.
This solves 'we can't share the real codebase' for public benchmarks.
Worth a blog post on its own.
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
The novel insight: traditional bundlers are compilers (source in, file out,
start over). Cloudpack is a database: the module graph is the schema, bundle
requests are queries, every output form is a materialization. One truth,
many views. No separate dev/prod pipeline. No divergence.
This concept is the unifying thread of the entire cloudpack series.
From the architect brief: 'The module graph is the software. The bundle is
a query.'
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Key principle added to standing rules: 'Lead with outcomes, not internals.
Nobody cares about a fingerprinting algorithm. They care that their builds
stop lying.'
Rage series retitled:
- 'Two-Phase Fingerprinting: BuildXL's Deep Magic' → 'How We Made the Cache Stop Lying'
- 'Hooking Syscalls Without a Kernel Driver' → 'Zero-Config File Watching Across Three Operating Systems'
- 'TypeScript 7 Makes the Build Harness More Important' → 'TypeScript 7 Is 10x Faster. Your Builds Aren't.'
- 'node_modules in a Content-Addressed Store' → '90 Seconds to 300 Milliseconds: Fixing CI Install Times'
- 'What I Learned Maintaining Lage and Why I Rewrote It' → 'The Architecture Mistake I Made in Lage'
Cloudpack series retitled:
- 'The Bundle Is Not a File' → '604ms Rebuilds at 50,000 Modules'
- 'The 2KB Module Summary' → '50KB Down to 2KB: Why We Stopped Parsing Source Files'
- 'Dead Code That Actually Stays Dead' → 'We Shipped 40% Less JavaScript and Nobody Noticed'
- 'The Service Worker as ld.so' → '50% Less Bandwidth Per Deploy'
- 'Signing Manifests, Not Code' → 'A Compromised Server Can\'t Inject Code'
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
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>
All 6 Rage posts now published and linked on the homepage:
1. Your Build Cache Is Lying to You
2. Two-Phase Fingerprinting: BuildXL's Deep Magic
3. Hooking Syscalls Without a Kernel Driver
4. TypeScript 7 Makes the Build Harness More Important
5. node_modules in a Content-Addressed Store
6. What I Learned Maintaining Lage and Why I Rewrote It
Zero 'Coming soon' items remain. 10 pages total, 9 posts.
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Markdown treats blank lines as paragraph separators, which splits
inline SVGs apart mid-element. The text and rect elements after
the first blank line leaked out as raw HTML instead of rendering
as part of the diagram.
Fixed in:
- two-phase-fingerprinting (ABI Early-Cutoff diagram - 34 blank lines removed)
- typescript-7 (Parallelism Stack + tsgo comparison - 19 blank lines removed)
Also: replaced clipart SVG hero with generated concept art image,
fixed hero illustration CSS for img element.
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
- Full-width hero with CSS grid: site title/tagline (left) + hand-coded
SVG workbench illustration (right), stacks on mobile
- Featured excerpt section with terracotta left border and inline
diagram from 'Your Build Cache Is Lying to You'
- Rage series as 2-column card grid at container width (1100px):
each card shows number, title, description, reading time or
'Coming soon' badge
- All posts as 2-column grid at reading width (720px)
- Three-tier width system: hero (100%), series (--width-container),
all-posts (--width-prose)
- Responsive: collapses to single column below 768px
- Updated tests to verify multi-column layout, SVG illustration,
card grid structure, and responsive breakpoints (41 tests, all pass)
- Fixed author name from 'Ken Hiatt' to 'Ken Chau'
- Rage series items now dynamically link to published posts
(4 linked with reading times, 2 still 'Coming soon')
- Published items show reading time and have hover states
- Series items matched to posts by slug lookup
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Two diagrams in the warm palette (paper bg, terracotta accent):
1. Floor and Ceiling: before/after comparison showing AI raises the
floor (what's functional) while the ceiling (excellence, judgment)
stays where it is. The gap between them IS the argument.
2. Lagged Failure Timeline: decision → invisible degradation →
failure surfaces 12-18 months later → misattributed to market
conditions. Makes the delay visible as a four-node flow.
Both use SVG primitives (rect, line, text, circle) following the
diagram design spec: warm palette, Inter for labels, Source Serif
for descriptions, terracotta for accents.
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Content model inspired by makingsoftware.com:
- Topics not dates (grouped by investigation theme)
- Homepage as pitch not index (show quality before navigation)
- Series are first-class (landing pages, progress, cross-links)
- Figure density: 1 visual per 300-500 words for technical posts
- No blog chrome (no comments, shares, newsletter popups)
Rage series plan (6 posts, all sourced from kenotron-ms/rage):
1. Your Build Cache Is Lying to You (the stale cache problem)
2. Two-Phase Fingerprinting: BuildXL's Deep Magic (WF/SF algorithm)
3. Hooking Syscalls Without a Kernel Driver (3 OS, 3 mechanisms)
4. TypeScript 7 Makes the Build Harness More Important (counter-intuitive)
5. node_modules in a Content-Addressed Store (CI kill shot)
6. What I Learned Maintaining Lage and Why I Rewrote It (meta narrative)
Each post has planned visuals (diagrams, flows, animations via Remotion).
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Content pipeline now starts with visual planning before drafting:
- What diagrams does this piece need?
- Static SVG? Animated (Remotion)? Interactive (d3-graphviz)?
- Plan alongside the outline, not as a decoration pass at the end
Cleaned up duplicate Project Context section in AGENTS.md.
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Every post must be considered for diagrams before publishing.
The question is not 'does this need a diagram?' but 'what would
illustrate this better than prose?'
Visualization approach:
- Claude hand-codes SVGs using primitives following design spec
- Warm palette (paper bg, brown-black ink, terracotta accent)
- Diagrams break wider than prose (840px breakout)
- DOT + d3-graphviz for interactive architecture graphs
- Image generation for concept art / visual targets
Rule: 1000+ words with zero visuals is a warning. The consideration
is mandatory. The diagrams are not.
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
- New lint check: 'doesn't just X. They Y' pattern (Claude rhetorical crutch)
- Fixed last instance in judgment essay: 'doesn't just lose income. They lose'
→ 'loses the acknowledgment... The income is secondary.'
- Updated voice-check skill dimension 2 with the pattern description
- Updated AGENTS.md with the new check
- Tightened regex to avoid false positives on legitimate 'isn't only' framing
🤖 Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
The Astro BASE_URL (/crashtestdev) lacked a trailing slash, causing
post URLs to render as /crashtestdevposts/... instead of
/crashtestdev/posts/... Breaking article card navigation and RSS feed
links.
Applied the same .replace(/\/?$/, '/') normalization pattern already
used in BaseLayout.astro to:
- ArticleCard.astro (card link hrefs)
- NavBar.astro (isActive path matching)
- rss.xml.ts (item link generation)
Also adds final-verification.test.mjs with 31 tests covering:
- Clean build output structure
- Index page cards, shadows, hover states, URL format
- Post page NavBar active state, PostHeader centering
- Three typography voices (prose/structure/evidence)
- Code block breakout width, warm background, terracotta border
- Design token color compliance
- Responsive behavior (nav stacking, title shrinking, gutter respect)
- RSS feed validity and URL correctness
Add .github/workflows/deploy.yml with build and deploy jobs for GitHub Pages. Triggers on push to master and workflow_dispatch. Uses Node 22 with npm cache, uploads dist/ artifact, and deploys via deploy-pages@v4. Add comprehensive tests verifying workflow structure.
Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
This replaces the smoke test index with a real page that:
- Imports getCollection, BaseLayout, NavBar, ArticleCard, getReadingTime
- Fetches all posts and sorts descending by date
- Maps posts to ArticleCard components with title, date, type, summary, slug, readingTime
- Styles .post-list with prose max-width, space-6/space-12 margins, flex column, space-2 gap
Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Copy two existing blog posts from content/posts/ (old Gatsby location)
to src/content/posts/ with updated frontmatter:
- localize-react-without-bloating-the-bundle.md
- speeding-up-webpack-typescript-incremental-builds-by-7x.md (was .mdx)
Frontmatter changes: removed path/heroImage fields, added type/tags/summary,
simplified date to YYYY-MM-DD format. Body content preserved verbatim.
- Created src/content.config.ts with Astro defineCollection using glob loader, pattern '**/*.{md,mdx}', base './src/content/posts', and Zod schema with 5 fields (title, date, type, tags, summary)
- Created src/content/posts/ directory for content storage
- Created src/utils/reading-time.ts with getReadingTime function (split whitespace, 200 WPM, Math.max(1, Math.ceil))
- All 23 new tests pass, all 61 total tests pass, npm run build succeeds
Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
- Import BaseLayout, NavBar, and PostHeader components
- PostHeader with title 'Speeding Up Webpack Typescript Incremental Builds by 7x',
date 2019-08-16, type post, readingTime 12
- Three typography voices in prose-width container:
- Prose voice: Source Serif 4 at 18px (font-prose)
- Structure voice: Inter at 14px in secondary color (font-structure)
- Evidence voice: JetBrains Mono with code-text color, surface-code bg,
rounded-md, accent-primary left border (font-evidence)
- Add build verification test (tests/verify-smoke-page.mjs)
- npm run build succeeds clean
Built the PostHeader.astro component per the design spec. It accepts props {title, date, type, readingTime}, formats dates with toLocaleDateString, renders a centered header with content type badge, h1 title, and meta line with date/reading time. Has responsive typography stepping down at 719px and 479px breakpoints. All 39 tests pass and npm run build succeeds.
Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Created NavBar.astro component with:
- Site name link 'Crash Test Dev' and Posts nav link with active state detection
- aria-label='Site navigation' and aria-current='page' accessibility attributes
- Responsive stacking at 599px breakpoint
- Design token-based styling (structure font, border-subtle, etc.)
- Updated index.astro to include NavBar in nav slot
- Added comprehensive build-output tests (24 assertions)
Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
- Created src/layouts/BaseLayout.astro as the site's base layout component
- Imports tokens.css and fonts.css for design system and typography
- Accepts Props {title: string, description?: string}
- Computes page title (appends ' — Crash Test Dev' unless title is already 'Crash Test Dev')
- Reads import.meta.env.BASE_URL for RSS link generation
- HTML structure: doctype, html lang=en, head with charset/viewport/description meta, computed title, RSS link alternate
- Body: skip-to-content link, named nav slot, main#main-content with default slot
- Global styles: CSS reset, body typography, link styles, skip-link, main container, ::selection
- Updated src/pages/index.astro to use BaseLayout with inline style placeholders demonstrating tokens/fonts
- Added tests/check-base-layout.mjs build-output test with 23 assertions, all passing