Corrective Action: Unnecessary Full Website Builds for SSR-Only Changes

Corrective Action: Unnecessary Full Website Builds for SSR-Only Changes

Date: March 15, 2026 Category: Verification Failure Impact: ~7 minutes wasted per code change; recurring pattern across many sessions Resolution Time: Same session — protocol defined, not yet internalized


Incident

What Happened

V ran a full website build (npx pnpm build, 414 seconds) after adding 3 new SSR components and updating 1 navigation component in the Command Center Collective section. All 4 files are server-rendered pages (export const prerender = false). No static content was modified. A 15-second type check (tsc --noEmit) would have caught any TypeScript errors.

Chris flagged this as a recurring pattern: "i feel like we have tried to fix this build habit so many times. why are we building the whole damn website during each update to a section of the website."

Timeline

Time Event
Session start Created 3 new files (PlatformArchitecture.tsx, DataFlowDiagram.tsx, platform-architecture.astro) + updated CommandCenterNav.astro
Pre-commit Ran cd apps/website && npx pnpm build — took 414 seconds
Post-build Committed (5b02d46e) and pushed to production
Chris review "why are we building the whole damn website during each update to a section of the website"

Root Cause

V defaulted to running a full static site build before every commit, despite the build-verification skill (skills/build-verification/SKILL.md) explicitly documenting a 4-tier verification system that exists to prevent this exact behavior.

Category: Verification Failure

The skill clearly states:

  • Tier 2 (type check, ~10s): For TypeScript/component changes — adding new props, changing type definitions, refactoring imports
  • Anti-Pattern: "Don't: Run full build for every change. Wastes 3-5 minutes per iteration."

The skill was never loaded or consulted. V treated npx pnpm build as the default verification step regardless of change type. This is a training data pattern: LLMs default to "run the full build" because that's the safest, most conservative approach — but it's the wrong approach for server-rendered pages that Vercel builds on-demand at request time.

The SSR Distinction

Astro pages with export const prerender = false are server-rendered on each request by Vercel's serverless functions. They are NOT included in the static build output. Running the full build for SSR-only changes:

  1. Regenerates 635+ episode pages, 23 show pages, 50+ blog posts — none of which were affected
  2. Takes 5-7 minutes for zero benefit
  3. Blocks the commit/push cycle unnecessarily

The correct verification for SSR + TypeScript changes is tsc --noEmit (~15 seconds), which catches type errors without generating any static output.

Why This Keeps Happening

The build-verification skill exists at skills/build-verification/SKILL.md but:

  1. Not in enforcement layer. It's a "development skill," not an enforcement trigger. V's self-correction protocol (vf-self-correction.md) has no trigger for "running full builds unnecessarily."
  2. Not in MEMORY.md. The build notes say "Website build: ~5-6 minutes" as a neutral fact, not as a warning about when it's inappropriate.
  3. Not loaded at session start. Enforcement skills are mandatory at session start; the build-verification skill is loaded only when explicitly needed.
  4. Training data default. "Build before commit" is a deeply ingrained pattern. Without an active trigger catching the behavior, it reasserts every session.

Fix Applied

Immediate Resolution

For this specific commit, the full build succeeded and the code was pushed. No code fix needed — the components work correctly. The fix is procedural.

Verification Approach for SSR Pages

Confirmed that tsc --noEmit in apps/website/ completes in ~15 seconds and catches type errors in new components. Pre-existing type errors (Sanity schemas, tailwind config, test files) are unrelated to new work.

The npx astro check command requires @astrojs/check (not installed). tsc --noEmit is the working alternative.

Decision Matrix (SSR Changes)

Change Type Verification Time
SSR page + TypeScript components tsc --noEmit ~15s
SSR page + visual changes Push, verify on Vercel preview 0s local
Static page content/data changes Full build required 5-7min
Route structure / getStaticPaths Full build required 5-7min
Build config (astro.config.mjs) Full build required 5-7min

Prevention Measures

Rules Added

Layer File Rule
Self-Correction skills/enforcement/vf-self-correction.md Infrastructure Trigger: "Running full website build for SSR-only changes"
Critical Lessons memory/MEMORY.md Build verification tier rule
Anti-Rationalization skills/enforcement/vf-self-correction.md "Better safe than sorry — run the full build" rationalization

Detection Triggers

Infrastructure Trigger: If V is about to run npx pnpm build or npm run build in apps/website/, STOP and check: Do ANY of the changed files affect static content (getStaticPaths, data fetching, build config)? If not, use tsc --noEmit instead.

Rationalization Trigger: "Better safe than sorry — let me run the full build" → The build-verification skill exists for this exact decision. Running a 7-minute build "just to be safe" for an SSR-only change is not safety — it's waste. tsc --noEmit catches type errors. Vercel catches runtime errors on deploy. The full build adds nothing for SSR pages.


Lessons

The build-verification skill documented the correct behavior since its creation, but documentation alone does not change behavior. Skills that define operational constraints must be surfaced as enforcement triggers — the same mechanism that prevents forbidden language and architecture anti-patterns. If a behavior is important enough to document as an anti-pattern, it's important enough to trigger self-correction.


Related Incidents

  • This is a recurring pattern Chris has flagged multiple times across sessions
  • The build-verification skill (skills/build-verification/SKILL.md) was created specifically to address this, but its guidance was never internalized into the enforcement layer
  • No previous CAR exists for this specific incident — it accumulated as informal corrections that didn't persist across sessions