# Driver subpackage split evaluation

Context: concrete runtime drivers currently live in the root `agent` package
while shared helper ownership and constructor boundaries are still stabilizing.

## Decision

Do **not** move concrete drivers into
`desktop/internal/agent/drivers/{codex,opencode,claude}` until the package
boundary criteria below are met.

The package still benefits from smaller driver files, but a subpackage migration is
not yet a mechanically safe boundary change. Keeping the drivers in the root
`agent` package avoids introducing root facade constructors, compatibility alias
packages, or import cycles while the process/driver seams are still being
stabilized.

## Evidence after A-H

Current top-level driver file sizes are uneven, but only one implementation is
still clearly oversized:

| File | Lines | Notes |
| --- | ---: | --- |
| `driver_codex.go` + split siblings | 3,060 | Codex has already been mechanically split by concern in the same package. |
| `driver_opencode.go` | 1,452 | Still large; should be split in-package before any package move. |
| `driver_claude.go` | 608 | Manageable as a single implementation file. |

The concrete drivers still depend on root-package helpers that are not driver
specific enough to duplicate and not yet extracted into neutral subpackages:

- process command helpers: `configureRuntimeCommand`, `terminateRuntimeCommand`,
  `prefixWriter`;
- cleanup telemetry: `logIgnoredCleanupError`;
- event/read helpers: `translatedEvent`, `parseStdout`, `readLineWithLimit`;
- runtime/provider setup: `applyCodexProviderConfig`,
  `materializeContractCarrier`;
- MCP environment/header helpers used by the Codex launch path.

`agent.NewDriver` also still constructs the concrete root types consumed by the
process, recovery, prompt, and tests. Moving drivers to subpackages while keeping
`agent.NewDriver` as the main constructor would turn the root package into a
facade over `agent/drivers/*`, which is explicitly not desired for this cleanup.
Removing that facade requires a larger constructor/registry ownership change and
consumer migration than a narrow driver cleanup should take on.

## Why not split now

A direct subpackage split that preserves behavior would need at least one of the
following extra changes:

1. export or duplicate the helpers above;
2. extract multiple shared helper packages first;
3. keep a root-level compatibility constructor/facade;
4. let driver subpackages import root `agent`, which would cycle once `agent`
   imports those subpackages to construct drivers.

Each option is larger than a package move, increases API surface, or violates the
no-facade/no-alias/no-cycle constraints for this boundary.

## Future split criteria

Revisit `agent/drivers/*` only after these conditions are true:

1. `driver_opencode.go` has first been split mechanically in the root package,
   matching the Codex same-package split style.
2. Shared helpers used by drivers live in neutral packages with narrow names and
   no dependency on root `agent` process state.
3. Driver packages can import only `agent/drivercontract`, `agent/runtimeconfig`,
   `agent/runtimeevents`, `agent/runtimeproc`, and other neutral desktop
   packages; they must not import root `agent`.
4. Constructor ownership is intentionally redesigned so consumers use direct
   imports or an accepted registry pattern, not a root compatibility facade.
5. `go list` confirms no import cycles, and focused driver/process tests cover
   the migrated constructors and event translation paths.

Until those criteria are met, same-package splits plus contract and mapping
guardrails give a better risk/reward balance than a package migration.
