Skip to content

Exploit-Strategy Subtree Collapse: Five Simulator Nodes → EvaluateExploitStrategy

Implemented by issue #1309 (task/1309-evaluate-exploit-strategy).

Context and Problem Statement

The simulator BT for exploit acquisition (AcquireExploit) encodes a single policy-driven question — "should we acquire an exploit for this vulnerability?" — as a sequence of five granular nodes: HaveExploit (Retriever), ExploitPrioritySet (ProtocolInternal flag check), EvaluateExploitPriority (Evaluator), ExploitDeferred (ProtocolInternal), ExploitDesired (ProtocolInternal). In production this granularity is unnecessary: the BT needs a structured decision, not a flag-by-flag reconstruction of what would have been one deliberate evaluation.

How should the five simulator nodes collapse in the production BT?

Decision Drivers

  • Minimize the number of external call-out point seams for what is conceptually a single evaluation
  • Keep individual seams independently swappable (Retriever-feeds-Evaluator pattern)
  • Produce a typed, structured output that downstream BT nodes can read directly

Considered Options

  1. Single EvaluateExploitStrategy Evaluator (queries exploit repo internally)
  2. HaveExploit Retriever feeds EvaluateExploitStrategy Evaluator (two seams)
  3. Keep all five nodes (no collapse)

Decision Outcome

Chosen option: Option 2 — HaveExploit Retriever feeds EvaluateExploitStrategy Evaluator. The exploit-repo query is kept as a separate Retriever seam (independently swappable) while collapsing the three ProtocolInternal flag nodes into the Evaluator's output record. The exploit-repo query is a distinct external data dependency from the strategy evaluation; keeping them as separate injection seams allows callers to swap only the repository query (e.g., to a different threat-intel platform) without touching the evaluation logic, and vice versa. Collapsing to a single Evaluator (Option 1) would force the Evaluator implementation to embed the repository query, reducing composability.

Consequences

  • Good, because the three ProtocolInternal flag nodes (ExploitPrioritySet, ExploitDeferred, ExploitDesired) disappear as separate BT leaves — they become internal decision reads on the Evaluator's output record
  • Good, because EvaluateExploitStrategy has a clean typed output contract
  • Neutral, because retaining HaveExploit as a Retriever means two call-out points remain instead of one; this is acceptable given the independent swapability benefit

More Information

  • Planning issue: #1200; implementation issue: #1309
  • Simulator nodes: HaveExploit, ExploitPrioritySet, EvaluateExploitPriority, ExploitDeferred, ExploitDesired (see notes/bt-fuzzer-nodes-report-management.md § "Exploit Acquisition" and "Production Collapse 1")
  • Output schema: ExploitStrategyDecision(have_exploit, acquire, rationale) (Pydantic BaseModel) in vultron/core/behaviors/report/acquire_exploit_strategy_tree.py
  • Fuzzer backend: EvaluateExploitStrategy in vultron/demo/fuzzer/report_management/acquire_exploit.py

Generated spec requirements: behavior-tree-integration.yaml BT-20-001