mirror of
https://github.com/duthaho/claudekit.git
synced 2026-07-16 20:55:17 +03:00
feat: improved the Claude Kit as a plugin
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
---
|
||||
name: root-cause-tracing
|
||||
user-invocable: false
|
||||
description: >
|
||||
Use when a bug manifests far from its origin, when stack traces show multiple layers of indirection, or when data corruption appears with no obvious source. Use for any scenario involving "it was already wrong by the time it got here," deep execution stack errors, constraint violations caused by upstream failures, or mysterious data state issues. Always prefer this over surface-level fixes when the error location differs from the bug location.
|
||||
---
|
||||
|
||||
# Root Cause Tracing
|
||||
|
||||
## When to Use
|
||||
|
||||
- Errors occur far from entry points
|
||||
- Data corruption with unclear source
|
||||
- Need to identify which code path triggers failures
|
||||
- Stack traces show multiple levels of indirection
|
||||
- "It was already wrong by the time it got here"
|
||||
|
||||
## When NOT to Use
|
||||
|
||||
- Surface-level UI bugs where the cause and effect are co-located
|
||||
- Known issues with documented fixes already available in the codebase or issue tracker
|
||||
- Performance optimization work where profiling tools are more appropriate than tracing
|
||||
|
||||
---
|
||||
|
||||
## Core Principle
|
||||
|
||||
**"Trace backward through the call chain until you find the original trigger, then fix at the source."**
|
||||
|
||||
The error location is rarely the bug location:
|
||||
|
||||
```
|
||||
User Input → Validation → Service → Repository → Database
|
||||
^ ^
|
||||
| |
|
||||
Bug HERE Error appears HERE
|
||||
(bad input allowed) (constraint violation)
|
||||
```
|
||||
|
||||
Fixing at the database layer treats the symptom. Fixing at validation prevents the bug.
|
||||
|
||||
---
|
||||
|
||||
## The Tracing Methodology
|
||||
|
||||
### Step 1: Identify Observable Error
|
||||
|
||||
Document exactly what you see:
|
||||
|
||||
```markdown
|
||||
Error: "Cannot insert NULL into column 'user_id'"
|
||||
Location: database-repository.ts:156
|
||||
Stack trace: [full trace]
|
||||
```
|
||||
|
||||
### Step 2: Locate Immediate Cause
|
||||
|
||||
Find the code directly responsible:
|
||||
|
||||
```typescript
|
||||
// database-repository.ts:156
|
||||
async function insertOrder(order: Order) {
|
||||
await db.insert('orders', {
|
||||
user_id: order.userId, // <- This is NULL
|
||||
// ...
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Trace One Level Up
|
||||
|
||||
Who called this function? What did they pass?
|
||||
|
||||
```typescript
|
||||
// order-service.ts:89
|
||||
async function createOrder(orderData: OrderData) {
|
||||
const order = new Order(orderData);
|
||||
await repository.insertOrder(order); // <- Called from here
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Continue Tracing
|
||||
|
||||
Keep going up the call chain:
|
||||
|
||||
```typescript
|
||||
// order-controller.ts:45
|
||||
async function handleCreateOrder(req: Request) {
|
||||
const orderData = req.body; // <- userId might be missing here
|
||||
await orderService.createOrder(orderData);
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Find Original Source
|
||||
|
||||
Reach the entry point where the problem originated:
|
||||
|
||||
```typescript
|
||||
// The real bug: No validation at entry point
|
||||
// req.body.userId was never validated
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Instrumentation Techniques
|
||||
|
||||
When manual analysis fails, add diagnostic logging:
|
||||
|
||||
### Strategic Console.error
|
||||
|
||||
```typescript
|
||||
// Add before suspicious operations
|
||||
console.error('[TRACE] order-service.createOrder input:', {
|
||||
orderData,
|
||||
hasUserId: !!orderData.userId,
|
||||
stack: new Error().stack
|
||||
});
|
||||
```
|
||||
|
||||
### Stack Trace Capture
|
||||
|
||||
```typescript
|
||||
// Capture where a value came from
|
||||
function setUserId(id: string | null) {
|
||||
if (id === null) {
|
||||
console.error('[TRACE] userId set to null from:', new Error().stack);
|
||||
}
|
||||
this.userId = id;
|
||||
}
|
||||
```
|
||||
|
||||
### Boundary Logging
|
||||
|
||||
```typescript
|
||||
// Log at every system boundary
|
||||
async function callExternalApi(params) {
|
||||
console.error('[TRACE] API request:', params);
|
||||
const response = await fetch(url, params);
|
||||
console.error('[TRACE] API response:', response.status, await response.text());
|
||||
return response;
|
||||
}
|
||||
```
|
||||
|
||||
### Environment/Context Logging
|
||||
|
||||
```typescript
|
||||
console.error('[TRACE] Context:', {
|
||||
env: process.env.NODE_ENV,
|
||||
timestamp: new Date().toISOString(),
|
||||
requestId: context.requestId,
|
||||
userId: context.user?.id
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Finding the Instrumentation Output
|
||||
|
||||
After adding logging:
|
||||
|
||||
```bash
|
||||
# Run tests and grep for traces
|
||||
npm test 2>&1 | grep "\[TRACE\]"
|
||||
|
||||
# Or run specific test
|
||||
npm test -- --grep "failing test" 2>&1 | grep "\[TRACE\]"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Root Cause Locations
|
||||
|
||||
| Where Error Appears | Where Bug Often Is |
|
||||
|--------------------|--------------------|
|
||||
| Database constraint | Input validation |
|
||||
| Type error in service | Data transformation |
|
||||
| Null reference | Optional field handling |
|
||||
| API timeout | Connection pool config |
|
||||
| Memory error | Resource cleanup |
|
||||
|
||||
---
|
||||
|
||||
## Defense-in-Depth Integration
|
||||
|
||||
After finding root cause, add validation at multiple layers:
|
||||
|
||||
```typescript
|
||||
// Layer 1: Entry point
|
||||
function handleRequest(req) {
|
||||
if (!req.body.userId) {
|
||||
throw new ValidationError('userId required');
|
||||
}
|
||||
}
|
||||
|
||||
// Layer 2: Service
|
||||
function createOrder(data) {
|
||||
assert(data.userId, 'userId must be provided to createOrder');
|
||||
}
|
||||
|
||||
// Layer 3: Repository
|
||||
function insertOrder(order) {
|
||||
assert(order.userId, 'Cannot insert order without userId');
|
||||
}
|
||||
```
|
||||
|
||||
See `defense-in-depth` skill for comprehensive approach.
|
||||
|
||||
---
|
||||
|
||||
## Critical Warning
|
||||
|
||||
**"NEVER fix just where the error appears."**
|
||||
|
||||
Fixing at the error location:
|
||||
- Treats symptom, not cause
|
||||
- Leaves bug available to trigger from other paths
|
||||
- Creates false confidence
|
||||
- Guarantees the bug will return
|
||||
|
||||
Fixing at the source:
|
||||
- Prevents the bug entirely
|
||||
- Protects all code paths
|
||||
- Creates robust system
|
||||
- Actually solves the problem
|
||||
|
||||
---
|
||||
|
||||
## Tracing Checklist
|
||||
|
||||
- [ ] Error message and location documented
|
||||
- [ ] Immediate cause identified
|
||||
- [ ] Call chain traced backward
|
||||
- [ ] Original source found
|
||||
- [ ] Instrumentation added if needed
|
||||
- [ ] Fix applied at source (not symptom)
|
||||
- [ ] Defense-in-depth validation added
|
||||
- [ ] Test proves fix works
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `systematic-debugging` - General debugging methodology; use root-cause-tracing when the bug location differs from the error location
|
||||
- `defense-in-depth` - After tracing the root cause, apply multi-layer validation to make the bug structurally impossible
|
||||
- `sequential-thinking` - Use sequential thinking to systematically document evidence and hypotheses during complex tracing sessions
|
||||
@@ -0,0 +1,168 @@
|
||||
# Tracing Techniques Reference
|
||||
|
||||
Backward-tracing techniques for systematic root cause analysis.
|
||||
|
||||
## Stack Trace Analysis
|
||||
|
||||
### Reading a Stack Trace
|
||||
|
||||
1. Start at the **bottom** (most recent call) to find the immediate failure
|
||||
2. Scan **upward** to find the first frame in **your code** (not library code)
|
||||
3. That frame is usually the symptom location, not the cause
|
||||
4. Continue upward to find where bad data or state originated
|
||||
|
||||
### Symptom vs Cause
|
||||
|
||||
| What You See | Likely Actual Cause |
|
||||
|---|---|
|
||||
| `NullPointerException` / `TypeError: cannot read property of undefined` | Value not set upstream, missing null check at origin |
|
||||
| `IndexOutOfBoundsException` | Off-by-one in loop logic or empty collection not guarded |
|
||||
| `ConnectionRefusedError` | Service down, wrong port, firewall rule, DNS resolution |
|
||||
| `TimeoutError` | Deadlock, resource exhaustion, slow query, network partition |
|
||||
| `ValidationError` | Caller passing wrong shape, schema mismatch, migration gap |
|
||||
|
||||
### Tips
|
||||
|
||||
- Filter out framework frames to reduce noise
|
||||
- In async code, the stack may be split; look for `caused by` or `previous` sections
|
||||
- In Python, read `__cause__` and `__context__` on chained exceptions
|
||||
- In TypeScript/Node, check `error.cause` (ES2022+)
|
||||
|
||||
## Binary Search / Git Bisect
|
||||
|
||||
### When to Use
|
||||
|
||||
- Bug exists now but worked at some known-good point
|
||||
- Reproducer is automatable (script, test command)
|
||||
|
||||
### Process
|
||||
|
||||
```bash
|
||||
git bisect start
|
||||
git bisect bad # current commit is broken
|
||||
git bisect good <known-good-sha> # last known working commit
|
||||
# Git checks out a midpoint; run your test
|
||||
git bisect good # or bad, based on result
|
||||
# Repeat until Git identifies the first bad commit
|
||||
git bisect reset # return to original branch
|
||||
```
|
||||
|
||||
### Automated Bisect
|
||||
|
||||
```bash
|
||||
git bisect start HEAD <good-sha>
|
||||
git bisect run ./test-script.sh
|
||||
# Exit 0 = good, exit 1 = bad, exit 125 = skip
|
||||
```
|
||||
|
||||
## Log Correlation
|
||||
|
||||
### Technique
|
||||
|
||||
1. Identify the **exact timestamp** of the error
|
||||
2. Search all related service logs within a window (e.g., +/- 30 seconds)
|
||||
3. Filter by **correlation ID**, **request ID**, or **user ID** across services
|
||||
4. Build a timeline of events across services
|
||||
|
||||
### Correlation Fields to Look For
|
||||
|
||||
- `request_id` or `trace_id` (distributed tracing)
|
||||
- `user_id` or `session_id`
|
||||
- Source IP or client identifier
|
||||
- Timestamps (normalize to UTC)
|
||||
|
||||
### Tools
|
||||
|
||||
- `grep` / `rg` with timestamp ranges
|
||||
- Structured logging with JSON output + `jq`
|
||||
- Distributed tracing (OpenTelemetry, Jaeger, Zipkin)
|
||||
|
||||
## Dependency Analysis (Backward Data Flow)
|
||||
|
||||
### Process
|
||||
|
||||
1. Start at the error location
|
||||
2. Identify the **variable or value** that is wrong
|
||||
3. Trace backward: where was this value set?
|
||||
4. At each step, ask: is this value correct here? If yes, move forward. If no, keep going back.
|
||||
5. The root cause is where correct data first becomes incorrect.
|
||||
|
||||
### Common Data Flow Points
|
||||
|
||||
```
|
||||
User Input -> Validation -> Transform -> Business Logic -> Persistence -> Query -> Response
|
||||
```
|
||||
|
||||
Trace backward through this chain from wherever the error manifests.
|
||||
|
||||
### Dependency Categories
|
||||
|
||||
| Dependency | What to Check |
|
||||
|---|---|
|
||||
| Function arguments | Caller passing wrong values |
|
||||
| Config / env vars | Wrong environment, stale config |
|
||||
| Database state | Missing migration, corrupt data |
|
||||
| External API | Changed response format, auth expiry |
|
||||
| Shared state | Race condition, stale cache |
|
||||
|
||||
## Instrumentation Points
|
||||
|
||||
### Where to Add Temporary Logging
|
||||
|
||||
1. **Entry/exit of suspected function** — log arguments and return value
|
||||
2. **Before/after external calls** — log request and response
|
||||
3. **Branch points** — log which path was taken and why
|
||||
4. **Data transformation steps** — log before and after
|
||||
5. **Error handlers** — log the full error with context
|
||||
|
||||
### Guidelines
|
||||
|
||||
- Use a distinct prefix (e.g., `[DEBUG-TRACE]`) so logs are easy to find and remove
|
||||
- Log the **type** as well as the **value** (catches `"null"` vs `null`)
|
||||
- In production, use feature flags or debug log levels, not code changes
|
||||
- Remove all temporary logging before committing
|
||||
|
||||
### Python Example
|
||||
|
||||
```python
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def process_order(order_id: str) -> Order:
|
||||
logger.debug("[DEBUG-TRACE] process_order called with: %s (type: %s)", order_id, type(order_id))
|
||||
order = db.get_order(order_id)
|
||||
logger.debug("[DEBUG-TRACE] db.get_order returned: %s", order)
|
||||
# ... rest of logic
|
||||
```
|
||||
|
||||
### TypeScript Example
|
||||
|
||||
```typescript
|
||||
function processOrder(orderId: string): Order {
|
||||
console.debug(`[DEBUG-TRACE] processOrder called with: ${orderId} (type: ${typeof orderId})`);
|
||||
const order = db.getOrder(orderId);
|
||||
console.debug(`[DEBUG-TRACE] db.getOrder returned:`, order);
|
||||
// ... rest of logic
|
||||
}
|
||||
```
|
||||
|
||||
## Common Root Cause Categories
|
||||
|
||||
| Category | Symptoms | Investigation Approach |
|
||||
|---|---|---|
|
||||
| **Data issues** | Wrong output, validation errors, corrupt state | Trace the bad value backward through the data flow |
|
||||
| **Race conditions** | Intermittent failures, works-on-retry, order-dependent | Look for shared mutable state, add timing logs, test with delays |
|
||||
| **Config drift** | Works locally but not in staging/prod | Diff environment configs, check env vars, verify secrets |
|
||||
| **Dependency changes** | Broke after deploy with no code changes | Check lock file diffs, dependency changelogs, API version headers |
|
||||
| **Resource exhaustion** | Timeouts, OOM, connection pool errors | Monitor metrics (memory, CPU, connections, disk), check for leaks |
|
||||
| **Schema mismatch** | Serialization errors, missing fields | Compare expected vs actual schema, check migration status |
|
||||
|
||||
## Quick Decision: Which Technique to Use
|
||||
|
||||
| Situation | Start With |
|
||||
|---|---|
|
||||
| Have a stack trace | Stack trace analysis |
|
||||
| "It used to work" | Git bisect |
|
||||
| Multi-service issue | Log correlation |
|
||||
| Wrong data in output | Backward data flow |
|
||||
| No idea where to start | Add instrumentation at boundaries |
|
||||
Reference in New Issue
Block a user