Quality Gate Skill (Bun-Only)
Verify code quality before commits and deployments using Bun exclusively.
⚠️ CRITICAL: Bun-Only Approach (MANDATORY)
ALL commands MUST use bun
- NEVER use pnpm , npm , or npx .
Why:
-
pnpm run X spawns: pnpm (node) + command (node) = 2 processes
-
bun run X spawns: bun only = 1 process (6x lighter than node)
-
With --smol flag: 54MB vs 343MB memory footprint
❌ NEVER USE THESE
pnpm run typecheck # Spawns extra node process npm run test # Spawns extra node process npx tsc # Spawns node
✅ ALWAYS USE THESE
bun run typecheck # Direct bun execution bun test # Native bun test runner (17x faster) bun run lint # Single process
⚠️ CRITICAL: Serialized Execution (MANDATORY)
Quality gates MUST run serially, never in parallel.
Multiple agents running quality gates simultaneously causes system crash:
-
3 agents × 3 commands = resource exhaustion
-
Result: Load 500+, kernel_task spike, system freeze
Use flock to enforce serialization:
LOCK_FILE="/tmp/rad-engineer-quality-gate.lock"
⚠️ CRITICAL: JIT Resource Check (MANDATORY)
BEFORE running any quality gate, check system resources:
Quick inline resource check (embedded in skill)
check_resources() { local load kernel_cpu load=$(sysctl -n vm.loadavg | awk '{print $2}') kernel_cpu=$(ps -Ao %cpu,comm | grep kernel_task | head -1 | awk '{print $1}') kernel_cpu=${kernel_cpu:-0}
if (( $(echo "$load > 8.0" | bc -l) )); then
echo "BLOCKED: Load too high ($load). Wait 30 seconds."
return 1
fi
if (( $(echo "$kernel_cpu > 40" | bc -l) )); then
echo "BLOCKED: kernel_task too high (${kernel_cpu}%). Wait 30 seconds."
return 1
fi
return 0
}
Use before quality gates
check_resources || { sleep 30; check_resources; } || exit 1
Full resource check script: .claude/hooks/check-system-resources.sh
Quality Stages
Stage 1: Static Analysis
LOCK="/tmp/rad-engineer-quality-gate.lock" cd rad-engineer
Check resources first
.claude/hooks/check-system-resources.sh || { sleep 30; .claude/hooks/check-system-resources.sh; } || exit 1
TypeScript check - MUST pass with 0 errors (SERIALIZED)
flock -w 300 "$LOCK" bun run typecheck
Lint check - MUST pass (SERIALIZED)
flock -w 300 "$LOCK" bun run lint
Failure Actions:
-
List all TypeScript errors with file:line
-
Separate lint errors into auto-fixable vs manual
Stage 2: Tests
LOCK="/tmp/rad-engineer-quality-gate.lock" cd rad-engineer
Check resources first
.claude/hooks/check-system-resources.sh || { sleep 30; .claude/hooks/check-system-resources.sh; } || exit 1
Run all tests (SERIALIZED) - uses --smol from bunfig.toml
flock -w 300 "$LOCK" bun test
Coverage (run separately when needed - NOT by default)
flock -w 300 "$LOCK" bun test --coverage
Requirements:
-
All tests must pass
-
Coverage ≥ 80% (when explicitly checked)
Stage 3: Build (if applicable)
LOCK="/tmp/rad-engineer-quality-gate.lock" cd rad-engineer
Verify build succeeds (SERIALIZED)
flock -w 300 "$LOCK" bun run build
One-Liner for All Quality Gates
Use this single command that runs all gates serially with resource check:
cd rad-engineer &&
LOCK="/tmp/rad-engineer-quality-gate.lock" &&
( ../.claude/hooks/check-system-resources.sh || { sleep 30; ../.claude/hooks/check-system-resources.sh; } ) &&
flock -w 300 "$LOCK" sh -c 'bun run typecheck && bun run lint && bun test'
This ensures:
-
Resources are checked BEFORE spawning processes
-
Only one quality gate runs at a time across ALL agents
-
Typecheck → Lint → Test run sequentially
-
Early exit on first failure
-
All processes use Bun (no node overhead)
Bun Configuration (bunfig.toml)
The project is configured with memory optimization:
[test] smol = true # Reduces memory from 343MB to 54MB coverage = false # Disabled by default (run explicitly when needed) timeout = 300000 # 5 min timeout for integration tests coverageSkipTestFiles = true
Output Format
All Passing
✓ TypeScript: 0 errors ✓ Lint: Clean ✓ Tests: XX passed ✓ Coverage: XX% (if explicitly run) ✓ Build: Success ━━━━━━━━━━━━━━━━━━━━━━ Ready to commit!
Failures
✗ TypeScript: X errors
- src/file.ts:42 - Error message
✗ Tests: X failed
- test/file.test.ts - Test name Expected: X Received: Y
━━━━━━━━━━━━━━━━━━━━━━ BLOCKED: Fix issues before commit
Quality Standards
Metric Minimum Target
TypeScript Errors 0 0
Lint Errors 0 0
Test Pass Rate 100% 100%
Coverage 80% 90%
Build Pass Pass
Why Bun-Only Matters
Process comparison per quality gate run:
Command Processes Spawned Memory
pnpm run typecheck
pnpm + tsc = 2 ~200MB
bun run typecheck
bun only = 1 ~54MB
pnpm run test
pnpm + bun = 2 ~400MB
bun test
bun only = 1 ~54MB
With 3 agents running quality gates:
Approach Total Processes Total Memory
pnpm (old) 3 × 6 = 18 ~1.8GB
bun (new) 3 × 3 = 9 ~162MB
Result: 90% memory reduction, 50% fewer processes
Why Serialization Matters
Without flock (BROKEN):
Agent 1: bun run typecheck → runs immediately Agent 2: bun run typecheck → runs in PARALLEL! Agent 3: bun run lint → runs in PARALLEL! Result: 3+ heavy processes, potential overload
With flock (CORRECT):
Agent 1: flock ... bun run typecheck → runs, holds lock Agent 2: flock ... bun run typecheck → WAITS for lock Agent 3: flock ... bun run lint → WAITS for lock Result: Only 1 quality gate at a time
Quick Reference Card
ALWAYS CHECK RESOURCES FIRST
.claude/hooks/check-system-resources.sh || sleep 30
ALWAYS USE FLOCK
LOCK="/tmp/rad-engineer-quality-gate.lock"
ALWAYS USE BUN
flock -w 300 "$LOCK" bun run typecheck # NOT pnpm flock -w 300 "$LOCK" bun run lint # NOT npm flock -w 300 "$LOCK" bun test # NOT npx
ONE-LINER (copy-paste ready)
cd rad-engineer && LOCK="/tmp/rad-engineer-quality-gate.lock" && flock -w 300 "$LOCK" sh -c 'bun run typecheck && bun run lint && bun test'
Version: 3.0.0 (Bun-Only + JIT Resource Check) Last Updated: 2026-01-13