#6293·CodeWhale

Decompose tools/subagent/mod.rs (19k lines): ordered extraction plan

Author: HmbownCreated Sep 17, 2026Updated Sep 17, 2026

What

crates/tui/src/tools/subagent/mod.rs is ~19,200 lines / 360 top-level items; its tests.rs sibling is ~23,200 lines. Every subagent fix pays the tax of finding the defect site in a file no one can hold in their head, and every edit risks unrelated coupling through use super::*. Extraction has started (advisor, budget_handback, coord, delivery, lifecycle, mailbox, naming, worktree are already siblings) but the bulk is still one file.

How to split it (leaf clusters first, pure moves, one slice per commit)

Order by dependency direction — each slice must compile and pass the subagent suite on its own, with no behavior change:

  1. Done: fallback_partial_text + tool_target_previewbudget_handback.rs (commit 7307f2302c).
  2. Budget context cluster (child_wall_time_exhausted_reason, child_runtime_budget_context, child_budget_pacing_notice, ~80 lines) → budget_handback.rs or a new budgets.rs.
  3. Summary/spill cluster (subagent_summary_char_budget, stamp_subagent_summary*, spill_subagent_final_report, summarize_subagent_result, ~110 lines) → new summary.rs.
  4. Model routing cluster (configured_model_*, resolve_subagent_assignment_route, subagent_reasoning_effort_*, ~470 lines) → new routing.rs.
  5. Usage/accounting cluster (record_provider_response_usage, refresh_usage_note, priced_usd_microusd, AgentRunUsage helpers, ~220 lines) → new usage.rs.
  6. Tool admission policy (is_unbounded_shell_run, reject_network_reaching_input, mutation_paths, build_allowed_tools, ~320 lines of pure predicates) → new admission.rs.
  7. Checkpoint/persistence cluster (SubAgentCheckpoint, PersistedSubAgent*, build_subagent_checkpoint, …) → new checkpoint.rs.
  8. SubAgentToolRegistry impl (~1,400 lines, the single biggest block) → new tool_registry.rs, after 6 removes its predicate dependencies.
  9. Spawn/parse cluster (SpawnRequest, parse_*, launch) → lifecycle.rs or new spawn.rs.
  10. Manager core + run loop stay in mod.rs last; split tests.rs to mirror whatever modules exist by then.

Rules for each slice

  • Pure move: pub(super) visibility, qualified call sites, zero behavior change, subagent suite green before commit.
  • Migrate all callers or do not start the slice (no shims, no re-exports left behind "temporarily").
  • New code goes in the new home from day one; mod.rs only shrinks.

Acceptance

  • mod.rs holds only the manager core + run loop (target: under 5,000 lines)
  • Every slice above landed as behavior-preserving commits with green gates
  • tests.rs split to mirror the module layout
  • Related: #6034 (the crate::config monolith is the same disease one layer down)