skills-catalog/ln-628-concurrency-auditor/SKILL.md
Checks async races, thread safety, TOCTOU, deadlocks, blocking I/O, resource contention. Use when auditing concurrency safety.
npx skillsauth add levnikolaevich/claude-code-skills ln-628-concurrency-auditorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Paths: File paths (
shared/,references/,../ln-*) are relative to skills repo root. If not found at CWD, locate this SKILL.md directory and go up one level for repo root. Ifshared/is missing, fetch files via WebFetch fromhttps://raw.githubusercontent.com/levnikolaevich/claude-code-skills/master/skills/{path}.
Type: L3 Worker
Specialized worker auditing concurrency, async patterns, and cross-process resource access.
MANDATORY READ: Load shared/references/audit_worker_core_contract.md.
MANDATORY READ: Load shared/references/mcp_tool_preferences.md and shared/references/mcp_integration_patterns.md
Receives contextStore with: tech_stack, best_practices, codebase_root, output_dir.
Use hex-graph first when dataflow or call-path analysis materially improves concurrency findings. Use hex-line first for local code reads when available. If MCP is unavailable, unsupported, or not indexed, continue with built-in Read/Grep/Glob/Bash and state the fallback in the report.
MANDATORY READ: Load shared/references/two_layer_detection.md for detection methodology.
shared/references/audit_scoring.md{output_dir}/ln-628--global.md (atomic single Write)Unified severity escalation: For ALL checks -- if finding affects payment/auth/financial code -> escalate to CRITICAL regardless of other factors.
What: Shared state corrupted across await/yield boundaries in single-threaded async code.
Layer 1 -- Grep patterns:
| Language | Pattern | Grep |
|----------|---------|------|
| JS/TS | Read-modify-write across await | \w+\s*[+\-*/]?=\s*.*await (e.g., result += await something) |
| JS/TS | Check-then-initialize race | if\s*\(!?\w+\) followed by \w+\s*=\s*await in same block |
| Python | Read-modify-write across await | \w+\s*[+\-*/]?=\s*await inside async def |
| Python | Shared module-level state in async | Module-level \w+\s*= + modified inside async def |
| All | Shared cache without lock | \.set\(|\.put\(|\[\w+\]\s*= in async function without lock/mutex nearby |
Layer 2 -- Critical questions:
Severity: CRITICAL (payment/auth) | HIGH (user-facing) | MEDIUM (background)
Safe pattern exclusions: Local variables, const declarations, single-use await (no interleaving possible).
Effort: M
What: Shared mutable state accessed from multiple threads/goroutines without synchronization.
Layer 1 -- Grep patterns:
| Language | Pattern | Grep |
|----------|---------|------|
| Go | Map access without mutex | map\[.*\].*= in struct without sync.Mutex or sync.RWMutex |
| Go | Variable captured by goroutine | go func + variable from outer scope modified |
| Python | Global modified in threads | global\s+\w+ in function + threading.Thread in same file |
| Java | HashMap shared between threads | HashMap + Thread\|Executor\|Runnable in same class without synchronized\|ConcurrentHashMap |
| Rust | Rc in multi-thread context | Rc<RefCell + thread::spawn\|tokio::spawn in same file |
| Node.js | Worker Threads shared state | workerData\|SharedArrayBuffer\|parentPort + mutable access without Atomics |
Layer 2 -- Critical questions:
go func capturing by value (safe) or by reference (unsafe)?Severity: CRITICAL (payment/auth) | HIGH (data corruption possible) | MEDIUM (internal)
Safe pattern exclusions: Go map in init() or main() before goroutines start. Rust Arc<Mutex<T>> (already safe). Java Collections.synchronizedMap().
Effort: M
What: Resource state checked, then used, but state can change between check and use.
Layer 1 -- Grep patterns:
| Language | Check | Use | Grep |
|----------|-------|-----|------|
| Python | os.path.exists() | open() | os\.path\.exists\( near open\( on same variable |
| Python | os.access() | os.open() | os\.access\( near os\.open\(\|open\( |
| Node.js | fs.existsSync() | fs.readFileSync() | existsSync\( near readFileSync\(\|readFile\( |
| Node.js | fs.accessSync() | fs.openSync() | accessSync\( near openSync\( |
| Go | os.Stat() | os.Open() | os\.Stat\( near os\.Open\(\|os\.Create\( |
| Java | .exists() | new FileInputStream | \.exists\(\) near new File\|FileInputStream\|FileOutputStream |
Layer 2 -- Critical questions:
Severity: CRITICAL (security-sensitive: permissions, auth tokens, configs) | HIGH (user-facing file ops) | MEDIUM (internal/background)
Safe pattern exclusions: Check inside try/catch with retry. Check for logging/metrics only. Check + use wrapped in file lock.
Effort: S-M (replace check-then-use with direct use + error handling)
What: Lock acquisition in inconsistent order, or lock held during blocking operation.
Layer 1 -- Grep patterns:
| Language | Pattern | Grep |
|----------|---------|------|
| Python | Nested locks | with\s+\w+_lock: (multiline: two different locks nested) |
| Python | Lock in loop | for.*: with \.acquire\(\) inside loop body |
| Python | Lock + external call | \.acquire\(\) followed by await\|requests\.\|urllib before release |
| Go | Missing defer unlock | \.Lock\(\) without defer.*\.Unlock\(\) on next line |
| Go | Nested locks | Two \.Lock\(\) calls in same function without intervening \.Unlock\(\) |
| Java | Nested synchronized | synchronized\s*\( (multiline: nested blocks with different monitors) |
| JS | Async mutex nesting | await\s+\w+\.acquire\(\) (two different mutexes in same function) |
Layer 2 -- Critical questions:
Severity: CRITICAL (payment/auth) | HIGH (app freeze risk)
Safe pattern exclusions: Reentrant locks (same lock acquired twice). Locks with explicit timeout (asyncio.wait_for, tryLock).
Effort: L (lock ordering redesign)
What: Synchronous blocking calls inside async functions or event loop handlers.
Layer 1 -- Grep patterns:
| Language | Blocking Call | Grep | Replacement |
|----------|--------------|------|-------------|
| Python | time.sleep in async def | time\.sleep inside async def | await asyncio.sleep |
| Python | requests.* in async def | requests\.(get\|post\|put\|delete) inside async def | httpx or aiohttp |
| Python | open() in async def | open\( inside async def | aiofiles.open |
| Node.js | fs.readFileSync in async | fs\.readFileSync\|fs\.writeFileSync\|fs\.mkdirSync | fs.promises.* |
| Node.js | execSync in async | execSync\|spawnSync in async handler | exec with promises |
| Node.js | Sync crypto in async | crypto\.pbkdf2Sync\|crypto\.scryptSync | crypto.pbkdf2 (callback) |
Layer 2 -- Critical questions:
Severity: HIGH (blocks event loop/async context) | MEDIUM (minor blocking <100ms)
Safe pattern exclusions: Blocking call in if __name__ == "__main__" (startup). readFileSync in config loading at init time. Sync crypto for small inputs.
Effort: S-M (replace with async alternative)
What: Multiple concurrent accessors compete for same resource without coordination.
Layer 1 -- Grep patterns:
| Pattern | Risk | Grep |
|---------|------|------|
| Shared memory without sync | Data corruption | SharedArrayBuffer\|SharedMemory\|shm_open\|mmap without Atomics\|Mutex\|Lock nearby |
| IPC without coordination | Message ordering | process\.send\|parentPort\.postMessage in concurrent loops |
| Concurrent file append | Interleaved writes | Multiple appendFile\|fs\.write to same path from parallel tasks |
Layer 2 -- Critical questions:
O_APPEND for small writes)Severity: HIGH (data corruption) | MEDIUM (ordering issues)
Safe pattern exclusions: Single writer pattern. OS-guaranteed atomic operations (small pipe writes, O_APPEND). Message queues with ordering guarantees.
Effort: M
What: Multiple processes or process+OS accessing same exclusive resource, including operations with non-obvious side effects on shared OS resources.
Layer 1 -- Grep entry points:
| Pattern | Risk | Grep |
|---------|------|------|
| Clipboard dual access | OSC 52 + native clipboard in same flow | osc52\|\\x1b\\]52 AND clipboard\|SetClipboardData\|pbcopy\|xclip in same file |
| Subprocess + shared file | Parent and child write same file | spawn\|exec\|Popen + writeFile\|open.*"w" on same path |
| OS exclusive resource | Win32 clipboard, serial port, named pipe | OpenClipboard\|serial\.Serial\|CreateNamedPipe\|mkfifo |
| Terminal escape sequences | stdout triggers terminal OS access | \\x1b\\]\|\\033\\]\|writeOsc\|xterm |
| External clipboard tools | Clipboard via spawned process | pbcopy\|xclip\|xsel\|clip\.exe |
Layer 2 -- This check relies on reasoning more than any other:
Build Resource Inventory:
| Resource | Exclusive? | Accessor 1 | Accessor 2 | Sync present? | |----------|-----------|------------|------------|---------------|
Trace Timeline:
t=0ms operation_A() -> resource_X accessed
t=?ms side_effect -> resource_X accessed by external process
t=?ms operation_B() -> resource_X accessed again -> CONFLICT?
Critical Questions:
Severity: CRITICAL (two accessors to exclusive OS resource without sync) | HIGH (subprocess + shared file without lock) | HIGH (invisible side effect detected via reasoning)
Safe pattern exclusions: Single accessor. Retry/backoff pattern present. Operations sequenced with explicit delay/await.
Effort: M-L (may require removing redundant access path)
MANDATORY READ: Load shared/references/audit_worker_core_contract.md and shared/references/audit_scoring.md.
MANDATORY READ: Load shared/references/audit_worker_core_contract.md and shared/templates/audit_worker_report_template.md.
Write JSON summary per shared/references/audit_summary_contract.md. In managed mode the caller passes both runId and summaryArtifactPath; in standalone mode the worker generates its own run-scoped artifact path per shared contract.
Write report to {output_dir}/ln-628--global.md with category: "Concurrency" and checks: async_races, thread_safety, toctou, deadlock_potential, blocking_io, resource_contention, cross_process_races.
Return summary per shared/references/audit_summary_contract.md.
When summaryArtifactPath is absent, write the standalone runtime summary under .hex-skills/runtime-artifacts/runs/{run_id}/evaluation-worker/{worker}--{identifier}.json and optionally echo the same summary in structured output.
Report written: .hex-skills/runtime-artifacts/runs/{run_id}/audit-report/ln-628--global.md
Score: X.X/10 | Issues: N (C:N H:N M:N L:N)
MANDATORY READ: Load shared/references/audit_worker_core_contract.md.
MANDATORY READ: Load shared/references/audit_worker_core_contract.md.
shared/references/audit_scoring.md{output_dir}/ln-628--global.md (atomic single Write call)shared/references/two_layer_detection.mdshared/references/audit_output_schema.mdVersion: 4.0.0 Last Updated: 2026-03-04
testing
Drafts and publishes fact-checked GitHub Discussions announcements. Use for releases, updates, or project news; not for release creation or issue responses.
testing
Prepares and publishes a tagged GitHub release from repository evidence. Use for an explicit release request; not for ordinary commits, packages, or community news.
testing
Validates, commits, pushes, and remotely verifies approved repository changes. Use when publication is requested; not for releases, package publishing, or announcements.
development
Reviews standalone skills and their configured distribution surfaces before publication. Use for skill release readiness; not for product code or implementation-plan review.