Endpoint Split Strategy¶
Level 3 Parallelism¶
Beyond model routing (Level 1) and scope decomposition (Level 2), the dispatch system supports a third level of parallelism: endpoint splitting. When a scoped sub-agent is assigned more than 12 endpoints, the endpoints are divided into groups, each handled by a separate agent instance.
This addresses a specific failure mode: even after scope decomposition, a sub-agent testing SQLi on 30 endpoints will degrade in quality on the last 10 endpoints compared to the first 10, because the context window fills with previous test results.
Splitting Thresholds¶
| Endpoint Count | Groups | Agents |
|---|---|---|
| 1-12 | 1 | 1 (no split) |
| 13-24 | 2 | 2 |
| 25-36 | 3 | 3 |
| >36 | 3 (capped) | 3 |
The cap at 3 groups exists because each Level 3 agent consumes a wave slot. With 3 agents per wave, a single skill-scope combination can at most consume one entire wave. Exceeding this would delay other skills unacceptably.
Grouping by Resource Similarity¶
Endpoints are not split arbitrarily. The /route skill generates endpoint_groups in test-plan.json that cluster endpoints by resource type:
{
"endpoint_groups": {
"test-injection:sqli": {
"group_count": 2,
"groups": [
["/api/v1/employees?sort=", "/api/v1/leaves?sort=", "/api/v1/tickets?sort=",
"/api/v1/employees?search=", "/api/v1/departments?filter="],
["/api/v1/auth/login", "/api/v1/auth/register", "/api/v1/export",
"/api/v1/reports?date=", "/api/v1/settings"]
]
}
}
}
Grouping by similarity means each agent sees endpoints with related parameter structures and response patterns. An agent testing ?sort= and ?search= parameters across list endpoints builds useful context about the application's query handling, which transfers across endpoints in the same group. Mixing list endpoints with auth endpoints would provide no such transfer benefit.
Dispatch Mechanism¶
The dispatch_scope_agents() function in agent-dispatch.md checks for endpoint groups and launches multiple agents within the same wave:
dispatch_scope_agents() {
local skill="$1" target="$2" edir="$3" scope="$4"
local test_plan="$edir/discovery/test-plan.json"
local group_key="${skill}:${scope}"
# Check if endpoint groups exist for this skill:scope
local group_count=$(python3 -c "..." 2>/dev/null)
if [ "$group_count" -gt 1 ]; then
# Level 3: split into multiple agents per scope
for i in $(seq 0 $((group_count - 1))); do
dispatch_agent "$skill" "$target" "$edir" "$scope" "$endpoints" \
"--group $((i+1))/$group_count"
done
else
# Level 2 only: single agent for scope
dispatch_agent "$skill" "$target" "$edir" "$scope" "$endpoints"
fi
}
Each Level 3 agent receives the --endpoints flag with its specific endpoint list and a --group N/M marker for logging.
Wave Slot Consumption¶
Level 3 splits run within their assigned wave slot. If test-injection --scope sqli splits into 2 groups, both agents run in the same wave (e.g., Wave 0), consuming 2 of the 3 available slots:
Wave 0 -- Critical Path (3 slots)
[agent-1] /test-injection --scope sqli --group 1/2 --endpoints /api/v1/employees,...
[agent-2] /test-injection --scope sqli --group 2/2 --endpoints /api/v1/auth/login,...
[agent-3] /test-access --scope idor
Empty slots in later waves (e.g., Wave 11 slot 3) absorb overflow agents that did not fit in their original wave.
Why Not Split Below 13¶
The initialization overhead of spinning up a new claude -p agent is non-trivial: loading the skill file, parsing context.json, establishing stealth configuration, and validating auth tokens takes 15-30 seconds. For 12 or fewer endpoints, this overhead exceeds the quality benefit of splitting. The threshold of 13 was determined empirically from lab evaluations where coverage quality on the 13th+ endpoint showed measurable degradation compared to the first 12.
Practical Impact¶
On the VulnHR lab (81 vulnerabilities, ~80 testable endpoints), Level 3 splitting typically produces:
- 31 base sub-agents (Level 2)
- 5-8 additional Level 3 agents (for SQLi, XSS, IDOR on high-endpoint-count resources)
- Total: ~38-40 agents across 12 waves
This keeps the total wave count stable while improving per-endpoint coverage quality on applications with large API surfaces.