How the Fix Loop Escalates in the Subagent Workflow: Codex-Security Deep-Scan Architecture

The fix loop escalates by propagating unresolved findings to additional subagents when SQLite close_reason flags indicate remediation failure or false positives, iteratively allocating resources based on the configured subagents count until the scan reaches a stable state.

The Codex-Security deep-scan system in the openai/plugins repository implements a multi-agent workflow to automate security vulnerability remediation. Understanding how the fix loop escalates within this subagent architecture is essential for optimizing scan throughput and resource allocation. This article examines the orchestration logic, database schema constraints, and configuration parameters that govern when the system spawns additional subagents to handle unresolved candidates.

Understanding the Subagent Fix-Loop Architecture

The deep-scan system processes security findings through a pool of subagents operating inside an iterative workflow. Each subagent attempts automatic remediation, records the outcome via a constrained SQLite schema, and either completes the task or triggers escalation. According to the source code in plugins/codex-security/scripts/deep_scan_workbench.py, the orchestration layer maintains runtime state—including workers and subagents counts—to determine when to expand the processing pool and continue the loop.

The Three Stages of Fix-Loop Escalation

Stage 1: Attempting Automatic Remediation

When a subagent receives a candidate finding, it first inspects the issue and attempts to apply an automatic fix. The success of this remediation attempt determines the subsequent path through the workflow. Successful fixes proceed to completion, while failed attempts, false positives, or developer-declared "won't fix" statuses initiate the escalation sequence.

Stage 2: Recording the Close Reason in SQLite

The outcome of each remediation attempt is persisted to the database schema defined in plugins/codex-security/scripts/workbench_schema.py. At line 136, the close_reason column enforces a constrained set of values that drive the escalation logic:


# workbench_schema.py – definition of the close_reason column

subagents INTEGER NOT NULL CHECK (subagents >= 0),
...
close_reason IS NULL OR close_reason IN ('already_fixed', 'wont_fix', 'false_positive')

Accepted values include:

  • already_fixed – The subagent successfully remediated the finding
  • wont_fix – The developer explicitly declined to address the issue
  • false_positive – The finding was determined to be invalid

Stage 3: Triggering Escalation via New Subagent Spawning

Escalation occurs whenever the close_reason is set to any value other than already_fixed. The orchestration layer reads the subagents count from the deep-scan configuration to determine whether to instantiate additional agents. As implemented in plugins/codex-security/scripts/deep_scan_workbench.py (lines 61-64), the runtime state exposes both workers and subagents fields, allowing the system to re-evaluate the work queue and spawn new subagents when permitted.

The escalation logic follows this pattern:


# Pseudo-code of the fix-loop escalation

for finding in candidates:
    if can_fix(finding):
        apply_fix(finding)
        close_reason = "already_fixed"
    elif user_declares_no_fix(finding):
        close_reason = "wont_fix"
    else:
        close_reason = "false_positive"

    record_close_reason(finding.id, close_reason)

    if close_reason != "already_fixed":
        # Escalate: let the orchestrator spawn another sub-agent

        increment_subagents_counter()

Configuration and Orchestration Details

Defining Subagent Limits in deep_scan_config.py

The maximum number of subagents permitted during escalation is controlled through the configuration parser in plugins/codex-security/scripts/deep_scan_config.py (lines 81-83). The system retrieves the subagents value using a require_integer validator with a configurable default:


# deep_scan_config.py – pulling the subagents setting from the config

"subagents": require_integer(
    configured.get("subagents", DEFAULT_SUBAGENTS),
    "deep_scan.subagents",
),

This configuration determines the upper bound of how many times the fix loop may escalate by spawning additional agents.

Runtime State Management in deep_scan_workbench.py

The orchestration routine tracks active resources through a runtime state object that informs escalation decisions. In plugins/codex-security/scripts/deep_scan_workbench.py, the configuration block exposes the current allocation:


# deep_scan_workbench.py – exposing subagents in the runtime state

"config": {
    "workers": run["workers"],
    "subagents": run["subagents"],          # ← used to decide whether to spawn more sub-agents

    ...
},

The orchestrator compares these values against the configured limits to determine whether the fix loop should spawn new subagents or mark the finding as requiring human intervention.

Summary

  • The fix loop escalates when findings receive a close_reason of wont_fix or false_positive, or when automatic remediation fails to apply successfully
  • The SQLite schema in workbench_schema.py constrains close_reason to three specific values that function as state machine triggers for escalation logic
  • Configuration parameters in deep_scan_config.py control the maximum subagents count available for iterative escalation
  • The orchestration layer in deep_scan_workbench.py manages runtime state to coordinate subagent spawning across fix-loop iterations until all findings reach a terminal state

Frequently Asked Questions

What triggers the fix loop to escalate in the subagent workflow?

Escalation triggers when a subagent cannot successfully fix a finding, resulting in a close_reason value of wont_fix or false_positive in the SQLite database. The system interprets any non-null close_reason other than already_fixed as a signal that the current subagent has completed its work on that finding, requiring delegation to a new subagent instance if the scan configuration permits additional resources.

How does the system determine when to spawn additional subagents?

The orchestration layer checks the subagents count from the deep-scan configuration against the current runtime state. As defined in deep_scan_config.py, this integer value limits how many subagents may be active simultaneously. The orchestrator in deep_scan_workbench.py re-evaluates this allocation during each iteration of the fix loop, spawning new agents only when the configuration allows and unprocessed candidates remain in the queue.

What database schema supports the fix-loop escalation tracking?

The escalation mechanism relies on the SQLite schema defined in plugins/codex-security/scripts/workbench_schema.py, specifically the close_reason column at line 136. This column accepts only three constrained values (already_fixed, wont_fix, false_positive), creating a finite state machine that determines whether the fix loop should close the finding or escalate it to additional subagents for re-processing.

Where is the subagent orchestration logic implemented?

The primary orchestration logic resides in plugins/codex-security/scripts/deep_scan_workbench.py, which exposes the runtime configuration including workers and subagents fields at lines 61-64. This module coordinates the fix-loop iterations, manages the work queue, and determines when to escalate findings to newly spawned subagents based on the close_reason flags and the limits defined in the scan configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →