Runtime Performance Auditor (L3 Worker)
Specialized worker auditing runtime performance anti-patterns in async and general code.
Purpose & Scope
- Worker in ln-650 coordinator pipeline - invoked by ln-650-persistence-performance-auditor
- Audit runtime performance (Priority: MEDIUM)
- Check async anti-patterns, unnecessary allocations, blocking operations
- Return structured findings with severity, location, effort, recommendations
- Calculate compliance score (X/10) for Runtime Performance category
Inputs (from Coordinator)
MANDATORY READ: Load
shared/references/task_delegation_pattern.md#audit-coordinator--worker-contract
for contextStore structure.
Domain-aware: Supports
+
.
Workflow
-
Parse context from contextStore
- Extract tech_stack, best_practices
- Determine scan_path
- Detect async framework: asyncio (Python), Node.js async, Tokio (Rust)
-
Scan codebase for violations
- Grep patterns scoped to
- For Rules 1, 3, 5: detect blocks first, then check for violations inside them
-
Collect findings with severity, location, effort, recommendation
-
Calculate score using penalty algorithm
-
Return JSON result to coordinator
Audit Rules (Priority: MEDIUM)
1. Blocking IO in Async
What: Synchronous file/network operations inside async functions, blocking event loop
Detection (Python):
- Find functions
- Inside them, grep for blocking calls:
- File: , , , , ,
- Network: , ,
- Subprocess: ,
- Exclude: calls wrapped in
await asyncio.to_thread(...)
or await loop.run_in_executor(...)
Detection (Node.js):
- Inside or arrow async, grep for , ,
Severity:
- HIGH: Blocking IO in API request handler (blocks entire event loop)
- MEDIUM: Blocking IO in background task/worker
Recommendation: Use
,
, or
for file operations; use
instead of
Effort: S (wrap in to_thread or switch to async library)
2. Unnecessary List Allocation
What: List comprehension where generator expression suffices
Detection:
- - allocates list just to count; use
- - allocates list for short-circuit check; use
- - same pattern; use
- - use set comprehension
"".join([x for x in ...])
- use generator directly
Severity:
- MEDIUM: Unnecessary allocation in hot path (API handler, loop)
- LOW: Unnecessary allocation in infrequent code
Recommendation: Replace
with generator
or set comprehension
Effort: S (syntax change only)
3. Sync Sleep in Async
What: inside async function blocks event loop
Detection:
- Grep for inside blocks
- Pattern: ... ...
Severity:
- HIGH: in async API handler (freezes all concurrent requests)
- MEDIUM: in async background task
Recommendation: Replace with
Effort: S (one-line change)
4. String Concatenation in Loop
What: Building string via
inside loop (O(n^2) for large strings)
Detection:
- Pattern: variable , , , with inside / loop
- Grep for: variable followed by containing string operand inside loop body
Severity:
- MEDIUM: String concat in loop processing large data (>100 iterations)
- LOW: String concat in loop with small iterations (<100)
Recommendation: Use
+
, or
, or f-string with
Effort: S (refactor to list + join)
5. Missing for CPU-Bound
What: CPU-intensive synchronous code in async handler without offloading to thread
Detection:
- Inside , find CPU-intensive operations:
- JSON parsing large files: ,
- Image processing: ,
- Crypto: ,
- XML/HTML parsing: ,
- Large data transformation without await points
- Exclude: operations already wrapped in or executor
Severity:
- MEDIUM: CPU-bound operation in async handler (blocks event loop proportionally to data size)
Recommendation: Wrap in
await asyncio.to_thread(func, *args)
(Python 3.9+) or
loop.run_in_executor(None, func, *args)
Effort: S (wrap in to_thread)
6. Redundant Data Copies
What: Unnecessary
,
,
when data is only read, not mutated
Detection:
- where is only iterated (never modified)
config = config_dict.copy()
where is only read
- where is returned without modification
Severity:
- LOW: Redundant copy in most contexts (minor memory overhead)
- MEDIUM: Redundant copy of large data in hot path
Recommendation: Remove unnecessary copy; pass original if not mutated
Effort: S (remove copy call)
Scoring Algorithm
See
shared/references/audit_scoring.md
for unified formula and score interpretation.
Output Format
Return JSON to coordinator:
json
{
"category": "Runtime Performance",
"score": 7,
"total_issues": 5,
"critical": 0,
"high": 2,
"medium": 2,
"low": 1,
"findings": [
{
"severity": "HIGH",
"location": "app/infrastructure/messaging/job_processor.py:444",
"issue": "Blocking IO: input_path.read_bytes() inside async function blocks event loop",
"principle": "Async Best Practices / Non-Blocking IO",
"recommendation": "Use aiofiles or await asyncio.to_thread(input_path.read_bytes)",
"effort": "S"
}
]
}
Critical Rules
- Do not auto-fix: Report only
- Async context required: Rules 1, 3, 5 apply ONLY inside async functions
- Exclude wrappers: Do not flag calls already wrapped in /
- Context-aware: Small files (<1KB) read synchronously may be acceptable
- Exclude tests: Do not flag test utilities or test fixtures
Definition of Done
- contextStore parsed (tech_stack, async framework)
- scan_path determined
- Async framework detected (asyncio/Node.js async/Tokio)
- All 6 checks completed:
- blocking IO, unnecessary allocations, sync sleep, string concat, CPU-bound, redundant copies
- Findings collected with severity, location, effort, recommendation
- Score calculated
- JSON returned to coordinator
Version: 1.0.0
Last Updated: 2026-02-04