| name | rootscan |
| description | Systematic bug-hunting mode with logic reasoning. Use when user wants to find bugs before they happen โ combines pattern-based detection (fast) with logic reasoning (deep) to find structural defects, design flaws, and edge cases. Forces 2-phase scan, severity rating, and actionable report before any fix. |
| triggers | ["๋ฒ๊ทธ ์ฐพ์","๋ฒ๊ทธ ์ฐพ์์ค","๋ฒ๊ทธ ์๋์ง","๋ฒ๊ทธ ๊ฒ์ฌ","๋ฒ๊ทธ ์ค์บ","๋ฌธ์ ์ฐพ์","์ทจ์ฝ์ ์ฐพ์","์ทจ์ฝ์ ๊ฒ์ฌ","์ฝ๋ ๊ฒ์ฌ","์ฝ๋ ๋ฆฌ๋ทฐ","์ ์ฌ์ ๋ฒ๊ทธ","์จ์ด์๋ ๋ฒ๊ทธ","์์ ํ์ง ํ์ธ","๋ณด์ ๊ฒ์ฌ","์ฑ๋ฅ ๋ฌธ์ ","๋ฉ๋ชจ๋ฆฌ ๋์","find bugs","scan bugs","code scan","vulnerability scan","security scan","performance issues","rootscan","๋ฃจํธ์ค์บ"] |
rootscan โ Logic-Driven Bug Hunting Mode
Don't wait for bugs to bite. Find them before they escape to production. When this skill activates, run 2-phase scan: Phase 1 (pattern detection) finds known anti-patterns, Phase 2 (logic reasoning) finds structural defects that only appear when understanding code flow.
Activation
Explicit: /rootscan
Auto-triggers (when these phrases appear in user message):
- "๋ฒ๊ทธ ์ฐพ์์ค", "๋ฒ๊ทธ ์๋์ง ํ์ธ"
- "์ทจ์ฝ์ ์ฐพ์", "๋ณด์ ๊ฒ์ฌ"
- "์ฝ๋ ๊ฒ์ฌ", "์ ์ฌ์ ๋ฒ๊ทธ"
- "์ฑ๋ฅ ๋ฌธ์ ", "๋ฉ๋ชจ๋ฆฌ ๋์"
- "find bugs", "scan bugs", "vulnerability scan"
What's Different (vs general code review)
| General Review | rootscan Mode |
|---|
| Read code + spot issues | 2-phase: pattern scan (fast) + logic reasoning (deep) |
| Subjective "looks OK" | Severity-rated findings (๐ด HIGH / ๐ก MEDIUM / ๐ข LOW) |
| Mixed findings | Categorized report (Logic / Security / Performance / Type) |
| Text feedback | Actionable items (file:line + trace + fix suggestion) |
| One-pass read | Multi-pass: pattern โ logic โ cross-file โ report |
| Finds known bugs | Finds known bugs + structural defects + design flaws |
4-Category Bug Hunt
Category 1: Logic Bugs ๐งฉ
What to find: Edge cases, race conditions, null/undefined handling gaps, off-by-one errors, async coordination issues.
Patterns to detect:
- Null/Undefined:
obj.prop without obj?.prop or null check, array access without bounds check
- Edge Cases: loop with
i < arr.length but arr[i+1] access, division without zero check, string operations without empty check
- Race Conditions: multiple
asyncio.create_task or Promise.all with shared state mutation, no lock/event for concurrent access
- Async Coordination:
await inside loop without considering parallelism, missing error handling in async tasks, dangling promises
- Off-by-One:
range(len(arr)) then arr[i+1], slice(0, n) logic errors
- Boolean Logic: complex
if conditions with mixed and/or, De Morgan's law violations, redundant checks
Detection method:
- Grep for risky patterns:
\.\w+\( without null check, arr\[.*\+.*\], asyncio.create_task, Promise.all
- Read functions with >3 branches or >2 levels of nesting
- Check all async functions for error handling + coordination
Severity rating:
- ๐ด HIGH: Null dereference in hot path, race on shared state, async coordination gap
- ๐ก MEDIUM: Missing edge case handling, off-by-one in non-critical path
- ๐ข LOW: Redundant checks, minor boolean logic simplification
Category 2: Security Vulnerabilities ๐
What to find: SQL injection, XSS, command injection, path traversal, authentication bypass, authorization gaps, secrets in code.
Patterns to detect:
- Injection:
- SQL: string concatenation in queries (
f"SELECT * FROM {table}" or "SELECT * FROM " + table)
- Command:
os.system(user_input), subprocess.call with shell=True + user input
- Path Traversal:
open(user_path) without validation, ../ not blocked
- XSS: HTML output with user input without escaping (
innerHTML = userInput)
- Authentication/Authorization:
- Missing auth check: endpoints without
@require_auth decorator or similar
- JWT: hardcoded secrets, no expiration check, no signature verification
- Session: session ID in URL, no CSRF token
- Secrets:
- Hardcoded:
password = "...", API_KEY = "...", token = "..."
- Logged:
logger.info(f"password: {pw}"), sensitive data in error messages
- Cryptography:
- Weak hash: MD5, SHA1 for passwords (instead of bcrypt/argon2)
- ECB mode, hardcoded IV/salt
Detection method:
- Grep for injection patterns:
f".*SELECT.*{, os.system, subprocess.*shell=True, innerHTML
- Grep for secrets:
password\s*=\s*["'], api_key\s*=, token\s*=, secret\s*=
- Check all route handlers for auth decorators
- Check crypto usage:
hashlib.md5, Cipher.*MODE_ECB
Severity rating:
- ๐ด HIGH: SQL injection, command injection, hardcoded secrets in production code, auth bypass
- ๐ก MEDIUM: Path traversal without validation, weak hash, missing CSRF
- ๐ข LOW: Secrets in test fixtures, verbose error messages
Category 3: Performance Issues โก
What to find: N+1 queries, memory leaks, infinite loops, O(nยฒ) algorithms, redundant API calls, unindexed DB queries.
Patterns to detect:
- N+1 Query:
- Loop with DB query inside:
for item in items: db.query(...)
- ORM lazy load in loop:
for user in users: user.profile.name
- Memory Leaks:
- Unclosed resources:
open(file) without with, requests.get without .close()
- Event listeners without cleanup:
addEventListener without removeEventListener
- Growing cache without eviction: unbounded dict/map used as cache
- Algorithmic:
- Nested loops on same data:
for i in arr: for j in arr:
- Linear search in loop:
for item in big_list: if item == x
- Repeated sorting:
sorted(arr) called multiple times on same data
- Redundant Work:
- Same API call in loop:
for id in ids: api.get(id)
- Repeated computation: same calculation in loop without memoization
Detection method:
- Grep for N+1:
for.*in.*:.*\.(query|get|fetch)
- Grep for unclosed:
open\( not in with, requests\.(get|post) without context manager
- Read nested loops (>2 levels)
- Check functions with >50 lines for repeated patterns
Severity rating:
- ๐ด HIGH: N+1 query in production hot path, memory leak in long-running service
- ๐ก MEDIUM: O(nยฒ) algorithm on medium-size data, unclosed file handle
- ๐ข LOW: Minor redundant computation, non-critical repeated API call
Category 4: Type Safety Holes ๐ท๏ธ
What to find: any type abuse, type assertion without validation, runtime type mismatch, missing null checks in typed code.
Patterns to detect (TypeScript/Python typed context):
- Type Escape Hatches:
- TypeScript:
as any, @ts-ignore, // @ts-expect-error without explanation
- Python:
cast() without runtime check, # type: ignore without reason
- Runtime Mismatch:
- JSON parsing without validation:
JSON.parse(data) then direct property access
- API response without schema check:
response.data.field without validating structure
- User input cast:
int(user_input), Number(input) without try-catch
- Null Unsafety (in strict-null-check context):
- Non-null assertion without check:
obj!.prop, obj.prop! in TypeScript
- Optional chaining overuse masking real issue:
a?.b?.c?.d?.e (design smell)
- Type Declaration Drift:
- Interface/type definition doesn't match actual usage
- Function signature says
X but returns X | null in some paths
Detection method:
- Grep for escape hatches:
as any, @ts-ignore, cast\(, # type: ignore
- Grep for non-null assertions:
!\\., \\..*!
- Check JSON.parse call sites for validation
- Run type checker and check for
any in inferred types
Severity rating:
- ๐ด HIGH:
as any in production code bypassing critical type check, JSON parse without validation in API handler
- ๐ก MEDIUM:
@ts-ignore without explanation, missing null check in typed code
- ๐ข LOW: Type declaration comment out of sync, harmless
any in test code
6-Step Scan Workflow
Step 1: Scope Definition
- What to scan: user specifies file/directory/entire project
- Focus area: user can request specific category (e.g., "security only") or all 4
- Depth:
- shallow = entry points only (API handlers, main functions) + pattern scan
- deep = all files + pattern scan + logic reasoning
Ask user if not clear:
Scanning scope:
- Files: [which files/directories?]
- Categories: [all 4, or specific ones?]
- Depth: [shallow = pattern scan only, deep = pattern + logic reasoning]
Default: If user says "๋ฒ๊ทธ ์ฐพ์์ค" without specifying, use deep scan on current directory.
Step 2a: Pattern Detection (Phase 1 - Fast)
Purpose: Find known anti-patterns via automated checks.
For each category, run the detection method:
- Grep for known patterns
- Read flagged files
- Cross-reference with checklist
Output format per finding:
[Category] Severity: Issue Title
File: path/to/file.py:42
Pattern: [pattern name]
Code:
41 | def process(data):
42 | result = data.field # โ no null check
43 | return result
Why risky: [explanation]
Fix suggestion: [actionable fix]
Time estimate: ~30 seconds per 1000 LOC
Step 2b: Logic Reasoning (Phase 2 - Deep)
Purpose: Find bugs that pattern matching can't catch โ structural defects, design flaws, edge cases that only appear when understanding code flow.
When to run: Only when depth = deep. Skip if shallow.
7-Point Logic Reasoning Checklist
For each critical function (API handlers, core business logic, async coordinators):
1. State Flow Tracing
Question: "If I trace all possible state transitions, where does it break?"
Method:
- Identify all mutable state (class vars, DB fields, cache keys, async events)
- Trace state changes through function calls
- Look for paths where state becomes inconsistent
Example findings:
๐ด HIGH: State inconsistency in order processing
File: services/order.py:67
Logic: order.status = 'paid' but order.payment_id is None
Why risky: Later code assumes payment_id exists when status='paid'
Trace:
- Line 45: status set to 'paid'
- Line 52: payment_id set only if payment_method == 'card'
- Line 67: returns order (payment_id may be None)
Fix: Set payment_id before setting status, or add validation
2. Auth/Permission Boundary Check
Question: "Who can access what, and is it enforced everywhere?"
Method:
- Map all resources (DB rows, files, API data)
- Check if access control is consistent across read/write/delete
- Look for "owner checks" that only check user_id but not resource_id
Example findings:
๐ด HIGH: Authorization bypass in analysis results
File: api/analysis.py:34
Logic: Only checks user_id match, but analysis can be shared
Why risky: User A shares analysis with User B โ both have same user_id in sharing table
โ User C can read if they guess analysis_id
Boundary: Should check (user_id OR analysis_id in user's shared list)
Fix: Add analysis ownership/sharing check in middleware
3. Edge Case Enumeration
Question: "What inputs/states would make this function do something unexpected?"
Method:
- For each function, enumerate input dimensions: empty, zero, null, negative, very large, concurrent
- Check if each edge is handled
Example findings:
๐ก MEDIUM: Unhandled empty list in batch processor
File: workers/batch.py:23
Logic: Assumes items list is non-empty
Edge cases:
- items = [] โ range(len(items)) = range(0) โ loop never runs
- Line 45: result[0] access โ IndexError
Why risky: Batch queue can send empty list during backpressure
Fix: Add early return if not items
4. Async Coordination Gaps
Question: "What happens if two async tasks run this code at the same time?"
Method:
- Find all
asyncio.create_task / Promise.all / background jobs
- Check shared resources (DB, cache, file, state)
- Look for read-modify-write without locks
Example findings:
๐ด HIGH: Race condition in token refresh
File: auth/token.py:56
Logic:
T=0: Task A reads token (expires_at = T+5)
T=1: Task B reads token (expires_at = T+5)
T=2: Task A refreshes โ new token written
T=3: Task B refreshes โ overwrites A's token with older one
Why risky: Token becomes invalid, all requests fail
Fix: Use lock or atomic compare-and-swap
5. Error Propagation Analysis
Question: "If step 3 fails, does step 5 know about it?"
Method:
- Trace error paths (try-except, return None, error callbacks)
- Check if errors propagate or get silently swallowed
- Look for "optimistic" code that assumes success
Example findings:
๐ก MEDIUM: Silent failure in notification sender
File: notifications/email.py:78
Logic:
- send_email() catches all exceptions, logs, returns None
- Caller doesn't check return value
- User thinks notification sent, but it failed
Why risky: Users miss critical alerts (payment failed, account locked)
Fix: Return success/failure status, or raise exception
6. Data Schema Drift Detection
Question: "Does code assume a schema that may not be true?"
Method:
- Check API response handling: does code assume fields exist?
- Check DB queries: does code assume row shape matches model?
- Look for dict access
data['field'] without checking key existence
Example findings:
๐ด HIGH: Missing field handling in external API response
File: integrations/payment.py:45
Logic: response.data.transaction_id accessed directly
Schema risk:
- External API docs say transaction_id is optional
- Code assumes it always exists
- Error: KeyError when payment pending (no transaction_id yet)
Why risky: Breaks checkout flow
Fix: Use response.data.get('transaction_id') with fallback
7. Implicit Assumptions Hunt
Question: "What does this code assume that might not be true?"
Method:
- Read function comments/docstrings for assumptions
- Check "obvious" behavior that's not validated
- Look for magic constants without explanation
Example findings:
๐ก MEDIUM: Unvalidated assumption about list order
File: ranking/scorer.py:34
Logic: Assumes items are sorted by score descending
Assumption: Caller sorts before passing
Risk: If caller doesn't sort, top 10 may not be actual top 10
Evidence: No sorting in this function, no assertion
Fix: Add assert items == sorted(items, key=...) or sort here
When to flag as finding vs. when to skip
Flag if:
- Assumption can be violated in real usage
- Failure mode is data loss / security breach / user-facing error
- Code in critical path (auth, payment, core business logic)
Skip if:
- Assumption is guaranteed by framework/library contract
- Only breaks in test scenarios
- Already covered by existing validation layer
Step 3: Severity Triage
Group findings by severity:
- ๐ด HIGH: Must fix before merge (blocks PR)
- ๐ก MEDIUM: Should fix soon (follow-up ticket)
- ๐ข LOW: Optional improvement (backlog)
Step 4: Cross-File Analysis
Some bugs only appear when reading multiple files together:
- Inconsistent Error Handling: one file throws, another returns null for same error
- Shared State Race: file A writes
_cache[key], file B reads it without lock
- API Contract Drift: caller expects
{status, data}, but handler returns {ok, result}
Method:
- Identify shared state (global vars, class attributes, DB tables)
- Trace access patterns across files
- Flag inconsistencies
This step is enhanced by Step 2b logic reasoning โ cross-file issues are often caught during state flow tracing and async coordination checks.
Step 5: Report Generation
Summary:
๐ด HIGH: N findings (must fix)
๐ก MEDIUM: M findings (should fix)
๐ข LOW: L findings (optional)
Top 3 risks:
1. [most critical finding]
2. [second most critical]
3. [third most critical]
Detailed Findings (grouped by category โ severity):
## ๐งฉ Logic Bugs
### ๐ด HIGH
- [finding 1]
- [finding 2]
### ๐ก MEDIUM
- [finding 3]
## ๐ Security Vulnerabilities
### ๐ด HIGH
- [finding 4]
...
Actionable Next Steps:
Immediate (before merge):
1. Fix [file:line] - [issue]
2. Fix [file:line] - [issue]
Follow-up (next sprint):
1. Add [test/validation] for [pattern]
2. Refactor [area] to eliminate [risk]
Optional (backlog):
1. Consider [improvement]
Output Format
[rootscan โ <scope>]
Scan Summary:
- Scope: [files/directories]
- Categories: [Logic / Security / Performance / Type]
- Depth: [shallow = pattern only / deep = pattern + logic reasoning]
- Phase 1 (Pattern): N findings
- Phase 2 (Logic): M findings (only if deep scan)
- Total Findings: ๐ด X HIGH / ๐ก Y MEDIUM / ๐ข Z LOW
Top 3 Risks:
1. [most critical]
2. [second most critical]
3. [third most critical]
---
## ๐งฉ Logic Bugs
### ๐ด HIGH
[findings...]
### ๐ก MEDIUM
[findings...]
### ๐ข LOW
[findings...]
---
## ๐ Security Vulnerabilities
[same structure...]
---
## โก Performance Issues
[same structure...]
---
## ๐ท๏ธ Type Safety Holes
[same structure...]
---
## Next Actions
๐จ Immediate (before merge):
1. [action]
2. [action]
๐ Follow-up (next sprint):
1. [action]
๐ก Optional (backlog):
1. [action]
---
Confidence: HIGH | MEDIUM | LOW
Reason: [why this confidence level]
Termination Conditions
Scan complete โ report delivered when ALL of:
Any unchecked item โ scan incomplete.
Confidence rating guide:
- HIGH: Deep scan completed, all 7 logic checks passed, cross-file analysis done
- MEDIUM: Pattern scan completed, partial logic reasoning (some checks skipped due to code complexity)
- LOW: Shallow scan only, or deep scan blocked by missing context (unclear requirements, external dependencies)
Anti-Patterns (forbidden in this mode)
- "Looks OK to me" โ skipping systematic checklist, relying on intuition
- Pattern-only when user wants deep โ skipping Phase 2 logic reasoning when depth = deep
- Unfocused scan โ reading code without specific pattern/logic check in mind
- No severity โ listing findings without priority (user can't triage)
- Vague fix โ "improve error handling" instead of "add try-catch at line 42"
- False negatives โ missing patterns because grep wasn't run, or missing logic flaws because trace wasn't done
- Category mixing โ security + performance in one finding (separate them)
- Claiming HIGH confidence without Phase 2 โ can't be HIGH if you skipped logic reasoning
Notes
- Derived from real-world code review sessions where critical bugs were missed because review was unfocused or pattern-only.
- Phase 2 logic reasoning is the differentiator โ finds bugs that static analyzers can't catch.
- Pairs with rootfix: scan โ find issue โ rootfix โ fix root cause.
- Works in any language. Adjust patterns per language (e.g., Python vs TypeScript vs Go).
- Can be run as pre-commit hook (shallow), PR gate (deep), or periodic audit (deep).
- Time estimate: shallow ~1 min per 1000 LOC, deep ~5 min per 1000 LOC (depends on complexity).
Example Usage
User: "๋ฒ๊ทธ ์ฐพ์์ค ์ด API ํธ๋ค๋ฌ์"
Agent (rootscan activated):
[rootscan โ api/handlers/]
Scan Summary:
- Scope: api/handlers/*.py
- Categories: All (Logic, Security, Performance, Type)
- Depth: Deep (pattern + logic reasoning)
- Phase 1 (Pattern): 3 findings
- Phase 2 (Logic): 2 findings
- Total Findings: ๐ด 3 HIGH / ๐ก 2 MEDIUM / ๐ข 1 LOW
Top 3 Risks:
1. Authorization bypass in analysis results (logic reasoning - no pattern match)
2. SQL injection in user_search() - no parameterized query
3. Race condition in async cache update - no lock
---
## ๐งฉ Logic Bugs
### ๐ด HIGH (Phase 1 - Pattern)
**Race condition in cache update**
File: api/cache.py:34
Pattern: Shared state mutation without lock
Code:
33 | async def update_cache(key, value):
34 | _cache[key] = value # โ no lock, multiple tasks can race
35 | await notify_subscribers(key)
Why risky: Multiple concurrent calls can interleave, leading to lost updates
Fix suggestion: Use asyncio.Lock() or single-writer pattern
### ๐ก MEDIUM (Phase 1 - Pattern)
**Missing null check in profile access**
File: api/user.py:67
Pattern: Null dereference
Code:
66 | user = get_user(id)
67 | return user.profile.bio # โ user could be None
Why risky: If user not found, AttributeError crashes handler
Fix suggestion: Add `if user is None: return 404` before access
---
## ๐ Security Vulnerabilities
### ๐ด HIGH (Phase 1 - Pattern)
**SQL injection in search**
File: api/search.py:23
Pattern: String concatenation in SQL
Code:
22 | query = request.args.get('q')
23 | sql = f"SELECT * FROM users WHERE name LIKE '%{query}%'" # โ injection!
24 | results = db.execute(sql)
Why risky: Attacker can inject `'; DROP TABLE users; --`
Fix suggestion: Use parameterized query: `db.execute("... WHERE name LIKE ?", (f"%{query}%",))`
### ๐ด HIGH (Phase 2 - Logic Reasoning)
**Authorization bypass in analysis results**
File: api/analysis.py:34
Logic Check: Auth/Permission Boundary
Code:
33 | def get_analysis(analysis_id):
34 | analysis = db.query(Analysis).filter_by(id=analysis_id).first()
35 | if analysis.user_id == current_user.id:
36 | return analysis
Why risky: Only checks user_id match, but analysis can be shared
Trace:
- User A creates analysis (owner)
- User A shares with User B via sharing_table
- User C guesses analysis_id โ Line 34 succeeds
- Line 35 fails (not owner) โ but C already saw analysis in line 34 query
Boundary violation: Should check (user_id == current OR analysis_id in shared_with_user)
Fix suggestion: Add sharing check in query filter or middleware
---
## โก Performance Issues
### ๐ก MEDIUM (Phase 1 - Pattern)
**N+1 query in user list**
File: api/users.py:45
Pattern: DB query inside loop
Code:
44 | for user in users:
45 | user.profile = db.query(Profile).filter_by(user_id=user.id).first() # โ N queries
Why risky: 1000 users = 1000 DB queries, scales poorly
Fix suggestion: Use `joinedload(User.profile)` to fetch in one query
---
## ๐ท๏ธ Type Safety Holes
### ๐ข LOW (Phase 1 - Pattern)
**Type ignore without reason**
File: api/utils.py:12
Pattern: Type escape hatch
Code:
11 | def parse(data):
12 | return json.loads(data) # type: ignore
Why risky: Bypasses type checker, actual issue could be signature mismatch
Fix suggestion: Add proper return type annotation or explain why ignore is needed
---
## Next Actions
๐จ Immediate (before merge):
1. Fix authorization bypass in api/analysis.py:34 [rootfix]
2. Fix SQL injection in api/search.py:23 [rootfix]
3. Fix race condition in api/cache.py:34 [rootfix]
๐ Follow-up (next sprint):
1. Add integration test for concurrent cache updates [rootbuild]
2. Add sharing matrix test for analysis permissions [rootbuild]
3. Refactor user list to use joinedload [rootclean]
๐ก Optional (backlog):
1. Add type validation for JSON.parse calls [rootclean]
---
Confidence: HIGH
Reason: Deep scan completed - all 4 categories + 7 logic checks performed. Phase 2 found authorization bypass that pattern matching missed.