Fix the root cause, not the symptom
Most debug logs are streams of consciousness: "tried this, didn't work, then tried that, weird." Two hours later, you can't remember what you've already tried, what you've ruled out, or what your current hypothesis is. You're not debugging — you're wandering.
CLN turns debugging into structured investigation. Each operator has a role in the diagnostic process.
DEBUG: Orders API returning 500 on bulk create @reported: 2026-02-14 14:32 UTC @severity: P1 (production, affects checkout) @environment: prod-us-east-1 = symptom: POST /api/orders/bulk returns 500 when payload > 50 items = works fine with ≤50 items, started after deploy v2.14.3 —— INVESTIGATION —— ? hypothesis 1: request timeout on large payloads . tested: 51 items with timeout extended to 60s - REJECTED — still fails with extended timeout * error occurs at 1.2s, well within timeout ? hypothesis 2: database connection pool exhaustion . checked: pg_stat_activity during failure - REJECTED — only 12/100 connections active ? hypothesis 3: new validation middleware has N+1 query . checked: git diff v2.14.2..v2.14.3 middleware/ + CONFIRMED — new SKU validator queries DB per item ! 50+ items = 50+ sequential DB calls = connection starvation | file: middleware/validateSKU.js:47 —— ROOT CAUSE —— ! validateSKU middleware performs individual DB lookup per SKU = introduced in v2.14.3 commit a3f7b2c * works ≤50 items due to connection pool grace period * fails at 51+ when sequential queries exceed pool wait timeout —— FIX —— . immediate: batch SKU validation into single IN() query . followup: add integration test for bulk > 100 items . preventive: add middleware performance budget (max 2 DB calls) @fix-branch: fix/bulk-sku-validation @reviewer: @backend-lead
Look at the hypothesis section. Each ? is clearly marked as a hypothesis. Each - REJECTED or + CONFIRMED tells you the outcome at a glance. No scrolling through Slack messages to figure out "wait, did we rule out the timeout theory?" The investigation is its own documentation.
| Operator | Debug Role | Example |
|---|---|---|
! | Error / root cause | ! memory leak in WebSocket handler |
? | Hypothesis (unverified) | ? could be race condition in queue |
= | Confirmed fact | = error only occurs under load >200 rps |
. | Test / action taken | . reproduced locally with k6 load test |
+ | Confirmed / works | + fix verified in staging |
- | Rejected / doesn't work | - rolling restart did not resolve |
| | Tool / file reference | | file: src/handlers/ws.go:142 |
@ | Metadata | @environment: prod-eu-west |
Before touching code, write 5 lines of CLN: the symptom (=), the environment (@), and three hypotheses (?). This forces you to think before you grep. Most developers skip this step — and spend 3x longer as a result.
Nine symbols. Four spaces. Infinite clarity.