Skip to content

Cleanup: remove unused Level-3 dynamic-DAG subagent machinery from production path #414

Closed

Description

@NOirBRight

Problem Statement

The subagent system was migrated from proxy-driven DAG orchestration to direct model tool calls (multi_agent_v1 namespace: spawn_agent / wait_agent / close_agent / resume_agent / send_input). The old DAG machinery is now almost entirely unused by production traffic, but it still ships in the production source tree and adds branching to hot request paths:

  • subagent_dynamic_dag.py (133 lines) is a Level-3 test-scenario harness, not production logic. It activates only when the literal string LEVEL3_DYNAMIC_DAG appears in user input, and its node prompts are hardcoded test fixtures ("You are a Level 3 Dynamic DAG worker... Return exactly one line: A_DONE"). No real user request ever triggers it.
  • Despite that, the production request path carries its wiring: marker detection and dynamic_dag_intent on SubagentState, plus roughly a dozen dynamic_dag_* branches in the gateway orchestration code that gate tool injection, spawn suppression, and guidance messages.
  • subagent_scheduler.py is only partially alive: bounded_workflow_from_exact_prompts + compute_allowed_actions still serve the production bounded exact-prompts path, but workflow_from_role_sequence, append_node, and the generic WorkflowState DAG-building surface appear to exist only for the Level-3 scenario (usage audit needed).

Keeping a marker-triggered test scenario in production source means dead branches on every subagent request, extra state fields every reader must understand, and a magic string in user input that silently changes gateway behavior.

Solution

Remove the Level-3 dynamic-DAG scenario machinery from the production path and slim subagent_scheduler down to what the bounded exact-prompts path actually uses.

Recommended direction: delete the scenario outright (production code + its scenario-specific tests), on the grounds that native subagent spawn semantics are now covered by direct-tool-call tests, and the scenario validates behavior no production request can reach. If triage decides the Level-3 scenario still has validation value, the fallback is to relocate it into the test tree as a test-only helper that builds workflows directly — but that fallback still requires removing marker detection from production state building, so the production-side commits below are the same either way.

Commits

Each commit leaves the codebase green; run the listed targeted tests before committing.

  1. Usage audit (no code change, records findings in this issue): enumerate every caller of subagent_scheduler symbols (workflow_from_role_sequence, append_node, node_complete, workflow_complete, compute_allowed_actions, WorkflowState/WorkflowNode) across production source and tests; record which are reachable only from the dynamic-DAG scenario versus the bounded exact-prompts path.
  2. Remove the dynamic-DAG scenario tests: the dedicated scenario test file, the dynamic-DAG cases in the subagent-state tests, and the dynamic-DAG routing tests (including the duplicate-spawn-suppression case whose event_context fixture only exists for this scenario).
  3. Remove the dynamic-DAG branches from the gateway orchestration: the dynamic_dag_active / dynamic_dag_intent conditionals in tool-injection gating, spawn suppression, and guidance injection, plus the workflow-building block and its subagent_dynamic_dag_ready_nodes event-context keys.
  4. Remove dynamic-DAG handling from subagent state building: the dynamic_dag_intent field on the state object, marker detection, and the lifecycle_complete computation that depends on it. Adjust remaining state tests that referenced the field.
  5. Delete subagent_dynamic_dag.py and the gateway's import of it.
  6. Trim subagent_scheduler.py to the symbols the bounded exact-prompts path uses (per the audit in commit 1): remove workflow_from_role_sequence, append_node, and any other scenario-only helpers.
  7. Candidate verification: full local Python core suite python -m pytest -q --ignore=tests/test_real_client_e2e.py; run python scripts/report_quality_gates.py (report-only) to confirm no new dead-code findings.

Decision Document

  • Scope decision: the bounded exact-prompts workflow path (bounded_workflow_from_exact_prompts, compute_allowed_actions) is production behavior and stays; only the marker-triggered Level-3 scenario machinery is removed.
  • Delete vs relocate: default is delete; relocation into the test tree is the documented fallback if triage wants to keep the scenario. The implementer should confirm at triage time which option was chosen before starting commit 2.
  • No behavior change for reachable paths: every removed branch must be provably unreachable without the LEVEL3_DYNAMIC_DAG marker; the bounded path and plain direct-tool-call subagent flows must behave identically before and after.
  • Verification class: standard (contained to the subagent boundary, deterministic test coverage exists); escalate to strict if the audit in commit 1 finds the scenario machinery entangled with routing or transport behavior.

Testing Decisions

  • This change removes code and tests; the safety net is the remaining suite, especially the subagent state tests, the routing tests, and the bounded exact-prompts coverage, which must pass unchanged (except deletions listed in commit 2).
  • No new tests are added. If the audit finds any production-reachable behavior that was only covered by a dynamic-DAG test, that coverage gap must be recorded in this issue and filled with a direct-tool-call test before removal.
  • A good test here = the surviving suite passing unchanged proves reachable behavior is preserved; tests must not be edited to accommodate the removal other than deleting scenario-specific cases.

Out of Scope

  • Any change to the bounded exact-prompts workflow behavior or its tool-gating semantics.
  • Any change to the multi_agent_v1 tool schemas, injection logic, or semantic-repair behavior.
  • Splitting or refactoring codex_proxy.py beyond deleting the dynamic-DAG branches (the monolith split is tracked separately in Refactor: extract route-plan and SSE helper clusters from codex_proxy.py monolith #413).
  • Removing subagent_scheduler.py wholesale — it still serves the bounded path.

Further Notes

  • Context: the DAG-to-direct-tool-calls migration is complete on the general path; this issue is the cleanup tail.
  • The magic-marker behavior (LEVEL3_DYNAMIC_DAG in user input changes gateway behavior) is worth calling out in the changelog/commit message when removed, in case any external test tooling still sends it.

Activity

  1. added
    campaign:gateway-chatGateway deep modules and Codex↔Chat bridge
    ready-for-agentFully specified, ready for an AFK agent
    and removed
    needs-triageMaintainer needs to evaluate this issue
    on Aug 19, 2026
  2. NOirBRight commented on Aug 19, 2026

    @NOirBRight
    OwnerAuthor

    Campaign decision from #441: delete the Level-3 dynamic-DAG scenario. Do not relocate it into the test tree unless the usage audit finds production-reachable behavior that only those tests cover.

    This is now ready-for-agent and is the first Track 1 code ticket. It blocks #413.

  3. self-assigned this
    on Aug 19, 2026
  4. NOirBRight commented on Aug 19, 2026

    @NOirBRight
    OwnerAuthor

    Claimed for WP1: usage audit then delete the Level-3 dynamic-DAG production path.

  5. NOirBRight commented on Aug 19, 2026

    @NOirBRight
    OwnerAuthor

    Usage audit (WP1 commit 1, no code change):

    Keep (production bounded exact-prompts path)

    • bounded_workflow_from_exact_prompts, compute_allowed_actions, WorkflowState, WorkflowNode, WorkflowAction
    • node_complete (used internally by compute_allowed_actions)
    • workflow_complete remains a generic scheduler helper used by tests; after DAG removal it has no production caller. Leaving it unless a follow-up wants a further trim.

    Delete with the Level-3 scenario

    • src-python/subagent_dynamic_dag.py and all LEVEL3_DYNAMIC_DAG marker detection
    • SubagentState.dynamic_dag_intent plus lifecycle_complete seeding from workflow_complete(dynamic_dag_workflow)
    • Gateway branches in codex_proxy.py around spawn suppression, event_context subagent_dynamic_dag_*, and the not dynamic_dag_intent conjuncts on workflow plan-read / node_repl injection
    • workflow_from_role_sequence and append_node (no remaining production caller)

    Tests to delete, not rewrite

    • tests/test_subagent_dynamic_dag.py
    • test_subagent_state.py methods that assert marker-driven intent
    • test_routing.py dynamic-DAG spawn/guidance cases
    • test_subagent_scheduler.py cases for append_node / workflow_from_role_sequence

    Keep

    • test_dynamic_dag_node_prompt_is_worker_request: leftover worker prompt text must still classify as a worker, not as workflow intent. That is reachable without the marker machinery.

    No production-reachable behavior is covered only by the marker tests. Proceeding with delete.

  6. NOirBRight commented on Aug 19, 2026

    @NOirBRight
    OwnerAuthor

    Implementation is in the working tree (not committed yet).

    Deleted:

    • src-python/subagent_dynamic_dag.py
    • tests/test_subagent_dynamic_dag.py
    • marker-driven state/orchestration/tests

    Kept:

    • bounded exact-prompts path
    • leftover worker-prompt classification tests so old DAG worker text still does not become coordinator workflow

    Targeted: 143 passed (subagent state/scheduler + related routing). py_compile on the touched modules is green. Python core is running next.

  7. NOirBRight commented on Aug 19, 2026

    @NOirBRight
    OwnerAuthor

    Landed on main as 4763f29.

    • Deleted subagent_dynamic_dag.py and the marker-triggered Gateway/state branches.
    • Trimmed workflow_from_role_sequence / append_node.
    • Bounded exact-prompts path is unchanged.
    • Targeted suite: 143 passed. Python core on Linux: 2383 passed; remaining failures are host gaps (powershell, OLLAMA_API_KEY), not this deletion.

    #413 is now unblocked for the import-surface freeze.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

campaign:gateway-chatGateway deep modules and Codex↔Chat bridgeready-for-agentFully specified, ready for an AFK agent

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions