# Desktop Go Naming Audit — Stage D0

## Scope

This audit covers Go code under `desktop/` after Stage C2 merged into `origin/main`.
The branch was rebased to `origin/main` at audit time (`84e27405d9`, which includes PR #2466).
It is intentionally an audit and batching document only: no production code is
renamed in this branch.

The goal is to find names that still reflect pre-split structure or duplicate
nearby context after the Desktop struct/service refactor, then classify each
candidate by compatibility risk before Stage D implementation starts.

## Scan method

- AST inventory over all `desktop/**/*.go` files. The walk skips only non-source or
  vendor-like directories when present (`vendor`, `node_modules`, `dist`, `build`,
  `.worktrees`); generated-commented Go files are still counted so file, package,
  and declaration totals share one full-Desktop denominator.
- Inventory collected declarations for packages, types, structs, fields,
  embedded fields, functions, methods, receiver names, export status, and tags.
- Reproducible counting rule: one package pair is `filepath.Dir(file) + package
  name`; `Total declarations captured` is the sum of functions, methods, named
  struct fields, embedded struct fields, structs, interfaces, and other type
  aliases/definitions.
- Heuristics used:
  - package stutter such as `agentteam.agentteamMCPToolGroup` or
    `exec.ExecCatalog`;
  - outer/inner repetition after previous extraction work;
  - generic names whose owner context can carry the noun more clearly;
  - explicit contract markers: exported names, JSON/YAML tags, MCP tool names,
    API DTOs, runtime protocol structs, environment variables, and DB/schema
    names.
- Manual call-site checks with `rg` for each high-confidence family below.
- Reference checks against the Desktop agent guide and daemon/runtime outbound
  tool specs so wire/tool/API names are not accidentally treated as local Go
  cleanup.

### Inventory counts

| Metric | Count |
| --- | ---: |
| Go files scanned | 745 |
| Package directory/package pairs | 84 |
| Total declarations captured | 16,948 |
| Functions | 6,573 |
| Fields | 6,060 |
| Methods | 2,654 |
| Structs | 1,338 |
| Interfaces | 135 |
| Type aliases/definitions | 132 |
| Embedded fields | 56 |

Largest Desktop Go surfaces by declaration count:

| Package path | Declarations | Structs | Fields | Methods | Functions |
| --- | ---: | ---: | ---: | ---: | ---: |
| `desktop/internal/channel/agentteam` | 2,148 | 157 | 879 | 329 | 745 |
| `desktop/internal/agent` | 1,818 | 130 | 569 | 453 | 637 |
| `desktop/internal/dispatcher` | 1,816 | 88 | 419 | 455 | 820 |
| `desktop/internal/api/dto` | 1,114 | 198 | 867 | 31 | 2 |
| `desktop/internal/profile` | 974 | 68 | 267 | 156 | 470 |
| `desktop/internal/api/dashboard` | 756 | 99 | 55 | 117 | 480 |
| `desktop/internal/types` | 653 | 70 | 429 | 64 | 68 |
| `desktop/internal/daemon` | 602 | 32 | 146 | 145 | 262 |
| `desktop/internal/promptcompiler` | 486 | 29 | 188 | 22 | 236 |
| `desktop/internal/wire/exec` | 455 | 41 | 267 | 24 | 116 |
| `desktop/internal/cmd` | 422 | 16 | 61 | 40 | 305 |
| `desktop/internal/wire/mcp` | 406 | 23 | 176 | 28 | 176 |
| `desktop/internal/metrics` | 395 | 36 | 191 | 92 | 64 |
| `desktop/internal/appbuild` | 283 | 16 | 101 | 58 | 106 |

## Compatibility classes

| Class | Meaning | Stage D implementation rule |
| --- | --- | --- |
| Direct internal rename | Private names with package-local call sites and no wire tags/contracts. | Rename directly in the module PR; update same-package tests; no alias. |
| Compat bridge / alias | Exported Go names, cross-package interfaces, or names referenced by stable specs but not serialized by name. | Introduce the new idiomatic name and a short-lived alias/forwarding method when external module churn or reviewers need a safer rollout. |
| Protected / defer | Names that are wire/API/schema/tool/protocol contracts, or identifiers whose stutter is semantically useful. | Do not rename in Stage D, or only rename private Go wrapper types while preserving exact serialized/tool names. |

## Findings

### D1 candidate: `channel/agentteam` package-local `agentteam*` names

Risk class: **direct internal rename for Go identifiers; protected for MCP tool
names and JSON schemas**.

The package is already `agentteam`, so private Go identifiers named `agentteam*` duplicate
package context. The raw AgentTeam protocol message types and MCP tool names must stay
unchanged; this finding is about Go helper names only.

| Current name family | Suggested name family | Notes |
| --- | --- | --- |
| `agentteamMCPAgentToolHandler`, `agentteamMCPAPIToolHandler` | `mcpAgentToolHandler`, `mcpAPIToolHandler` | Private function types in registry. |
| `agentteamMCPToolRegistration`, `agentteamMCPToolGroup` | `mcpToolRegistration`, `mcpToolGroup` | Private registry data; tool names remain exact wire strings. |
| `agentteamMCPToolGroups`, `agentteamMCPToolRegistrations`, `agentteamMCPToolByName` | `mcpToolGroups`, `mcpToolRegistrations`, `mcpToolByName` | Direct rename; update inventory tests if they assert helper names. |
| `agentteamAgentLifecycle`, `agentteamDeferredDelivery`, `agentteamRecovery`, `agentteamTrajectoryReader`, `agentteamDispatcher` | `agentLifecycleRuntime`, `deferredDeliveryRuntime`, `recoveryRuntime`, `trajectoryReaderRuntime`, `dispatcherRuntime` | These are agentteam-local ports to dispatcher. Prefer names that describe the port role instead of repeating `agentteam`. |
| `agentteamMetrics` | `metricsCollector` or `operationalMetrics` | Private channel telemetry owner. |
| `agentteamRequestHeaders`, `agentteamRouteWorkspaceHeaders` | `requestHeaders`, `routeWorkspaceHeaders` | `routeWorkspaceHeaders` is referenced by deployment spec prose; Go rename is safe but update spec mention only if it is intended as current code name. |
| `agentteamToolExecutor`, `agentteamLLMProxySessionIssuer`, `agentteamReactionAggregate`, `agentteamMetaSourceTarget`, `agentteamMetaString`, `agentteamAttachmentCacheDir`, `agentteamSkillDocData`, `agentteamAgentToolInstructionRef`, `agentteamAgentToolCommand` | Drop `agentteam` prefix unless it distinguishes remote AgentTeam wire data from local data. | Lower priority if D1 must stay small. |

Protected names in this module:

- MCP tool names such as `send_message` and provider-app tool names.
- JSON/YAML field tags in WebSocket messages, remote endpoint payloads, task
  tool schemas, and channel config.
- Endpoint IDs such as `workspace.list`, `runtime_access.trajectory_history`,
  and daemon transport capability strings.


### Field-level candidates across extracted state structs

Risk class: **direct internal rename** for private state fields; **protected** for
exported/tagged DTO fields.

The AST field scan found many exported `ID`, `ExecutionID`, `AgentID`, and JSON
contract fields. Those are intentionally explicit and should not be shortened.
The high-confidence field cleanup is instead concentrated in private state
structs introduced or clarified during Stage B/C, where the struct name already
provides the noun.

| Current field | Suggested field | Risk notes |
| --- | --- | --- |
| `channelConnectionStatusState.connectionStatus` | `status` | Private embedded state; direct rename if channel state naming stays grouped. |
| `channelAgentSyncState.agentListSyncInFlight`, `agentListSyncWaiters` | `listSyncInFlight`, `listSyncWaiters` | Private state; receiver/struct says agent sync. |
| `channelDaemonTransportState.daemonTransportSessionGeneration` | `sessionGeneration` | Private state; struct already says daemon transport. |
| `channelWorkspaceMismatchState.workspaceMismatchAppliedOnce` | `appliedOnce` | Private state; direct rename. |
| `channelUserTokenState.userToken`, `userTokenIssuedAt`, `userTokenFailures`, `userTokenUnsupported` | `token`, `issuedAt`, `failures`, `unsupported` | Private state; avoid changing config field `AuthToken`. |
| `channelAssetsEventState.assetsEventMu` | `mu` | Private state; struct name carries assets-event context. |
| `codexAppServerLaunchState.launchPermissionMode`, `launchWorkDir` | `permissionMode`, `workDir` | Private state; `launch` duplicates struct. |
| `codexAppServerThreadState.threadID`, `threadStatus` | `id`, `status` if struct is renamed to `codexThreadState`; otherwise keep | Avoid over-shortening unless the state struct rename lands in the same PR. |
| `exec.LeaseManager.leaseTTL`, `leaseByToken` | `ttl`, `byToken` | Private fields; exported `ExecLease` payload fields remain protected/aliased. |
Do not shorten exported or serialized fields such as `ExecutionID`, `AgentID`,
`RuntimeRunID`, `MCPToken`, `ToolsSpecHash`, or `SessionID`; those names are
wire/API readable and much safer than ambiguous `ID` fields in DTOs.

### D1/D2 candidate: `exec` package stutter

Risk class: **compat bridge / alias** for exported Go names; **protected** for
JSON fields, CLI env vars, and spec terms.

The package name is already `exec`, so exported Go names with
`Exec*` read as stutter at call sites. This package is still an internal
module, but the names are referenced across dispatcher, API DTO aliases, e2e,
and the daemon exec catalog.

| Current name | Suggested name | Risk notes |
| --- | --- | --- |
| `ExecCatalog` | `Spec` | Needs `type ExecCatalog = Spec` during transition because `specs/daemon/agent-tools-command-gate.md` documents `ExecCatalog`. |
| `ExecCatalogEntry` | `SpecEntry` | Alias recommended if `Spec` is renamed. |
| `ExecLease` | `Lease` | Alias recommended; spec prose uses `ExecLease` as a concept. |
| `ExecAuthorizeRequest` / `ExecAuthorizeResponse` | `AuthorizeRequest` / `AuthorizeResponse` | API DTO aliases and JSON tags must remain unchanged. |
| `ExecExecuteRequest` / `ExecExecuteResponse` | `ExecuteRequest` / `ExecuteResponse` | API wire shape is protected. |
| `ExecCommandString` | `CommandString` or `CLICommandString` | Exported helper; direct rename plus alias is acceptable. |
| `RenderExecCatalog`, `ValidateExecCatalog` | `RenderSpec`, `ValidateSpec` | Alias or wrapper functions reduce cross-package churn. |
| Dispatcher/API methods `ExecCatalog`, `AuthorizeExec`, `ExecuteExec` | `Spec`, `Authorize`, `Execute` on the exec-specific interfaces/managers | Use short bridge methods only if public interface compatibility is needed for staged PRs. |

Keep the following exact strings and JSON fields protected: `AGENTTEAM_AGENT_TOOLS_*`,
`leaseToken`, `toolId`, `toolsSpecHash`, `toolSpecRevision`, `policyVersion`,
`canonicalBinaryPath`, CLI namespace/action values, and MCP tool names.

### D2 candidate: `appbuild` session status names

Risk class: **compat bridge / forwarding methods**.

The package and receiver context already say app build session. `SessionStatus`
and `(*Session).SessionStatus` duplicate `Session` at call sites such as
`session.SessionStatus()` and `appbuild.SessionStatus`.

| Current name | Suggested name | Risk notes |
| --- | --- | --- |
| `appbuild.SessionStatus` | `Status` | Exported type used by dashboard API and daemon MCP tools. Add `type SessionStatus = Status` initially. |
| `(*Session).SessionStatus` | `Status` | Add forwarding `SessionStatus()` for one release/PR if reviewer wants low-risk rollout. |
| `(*Session).sessionStatusLocked` | `statusLocked` | Private direct rename. |
| `(*Orchestrator).SessionStatus` | `Status` or `Session` status accessor such as `SessionStatus` bridge + `Status` canonical | Because `Orchestrator` manages app sessions, `Status(appID)` is idiomatic but a bridge avoids broad call-site churn. |

JSON DTOs such as `dto.SessionStatusResponse` and HTTP route names are external
contracts and should not be renamed as part of this Go identifier cleanup.

### D2 candidate: managed skills and skill sync naming

Risk class: **mixed direct internal rename and compat bridge**.

| Current name | Suggested name | Risk notes |
| --- | --- | --- |
| `(*profile.SkillManager).SkillsDir` | `Dir` or `RootDir` | Exported but internal module. `Dir` matches `ManagedSkillRepositoryManager.Dir`; add forwarding `SkillsDir()` if touched alongside broad callers. |
| `(*skillprovider.Sync).SyncForAgent` | `ForAgent` or `SyncAgent` | Medium risk: it satisfies dispatcher `SkillSyncer` and test fakes. Prefer `SyncAgent` if the interface remains named `SkillSyncer`; bridge method may be useful. |
| `CachedPathsForAgent`, `CachedRepoIDsForAgent`, `CacheStateForAgent` | `CachedPaths`, `CachedRepoIDs`, `CacheState` | Receiver/interface already scope to skill sync; bridge if renaming the dispatcher interface in same PR. |
| `ManagedSkillRepositoryManager.RepositoryPath` | `Path` or `RepoPath` | Lower priority; `RepositoryPath` is clear with manager receiver and may stay. |

Keep YAML/profile persisted fields and managed repository record fields protected.

### D2 candidate: driver family state names

Risk class: **mostly direct internal rename; protected for runtime protocol DTOs**.

Stage C2 split driver files without changing many names. Most runtime protocol
wire structs carry useful provider context and JSON tags, so only internal state
holders should be renamed.

| Current name | Suggested name | Risk notes |
| --- | --- | --- |
| `codexAppServerRPCState` | `codexRPCState` or `rpcState` embedded in `CodexAppServerDriver` | Private embedded state; direct rename. Keep comments clear that it is Codex App Server JSON-RPC. |
| `codexAppServerLaunchState` | `codexLaunchState` or `launchState` | Private embedded state; direct rename. |
| `codexAppServerThreadState` | `codexThreadState` or `threadState` | Private embedded state; direct rename. |
| `appServerReasoningSectionState` | `reasoningSectionState` | Private and only used inside Codex driver; `appServer` is not adding much. |
| `codexActiveInterruptSnapshot` | `activeInterruptSnapshot` | Private and within Codex driver files. |
| `appServerInFlightRequest`, `appServerToolActivityRef`, `appServerServerRequestLogContext` | `inFlightServerRequest`, `toolActivityRef`, `serverRequestLogContext` | Direct rename only if kept in Codex-specific files; otherwise keep `appServer` if moving shared. |
| `ClaudeDriver` methods `rememberClaudeToolCallName`, `claudeToolCallName`, `rememberClaudeSession`, etc. | `rememberToolCallName`, `toolCallName`, `rememberSession` | Private receiver methods; direct rename. Leave package-level helpers with `claude` prefix if they process Claude wire data outside a receiver. |
| `OpenCodeDriver.nextOpenCodeRuntimeInputMessageID` | `nextRuntimeInputMessageID` | Private receiver method; direct rename. Keep package-level OpenCode ID helpers if they intentionally mirror OpenCode ID format. |

Protected/defer:

- Codex App Server wire DTO types in `driver_codex_wire.go` with JSON tags, such
  as `appServerMCPServerElicitationRequestParams` and `appServerThreadStatus`.
  The Go type names are private, but `appServer` clarifies protocol ownership;
  do not mass-rename them in D2 unless reviewers explicitly accept the churn.
- Runtime names (`codex`, `opencode`, `claude`, `builtin`), recovery strategy
  strings, event kind strings, and MCP prefixes.

### D2 candidate: daemon/window manager names

Risk class: **direct internal rename for private helpers; bridge for API-facing
interfaces**.

| Current name | Suggested name | Risk notes |
| --- | --- | --- |
| `desktopWindowManager` | `windowManager` | Private daemon type. Direct rename is safe but broad; only do it if paired with other window cleanup. |
| `desktopWindowTarget`, `desktopWindowKey`, `desktopWindowURL`, `desktopWebviewWindowOptions` | `windowTarget`, `windowKey`, `windowURL`, `webviewWindowOptions` | Private helper family. Keep `desktop` prefix if needed to distinguish Wails native windows from browser/workspace windows. |
| `windowRecordSync`, `windowURLForTargetSync` | `recordForTargetSync`, `urlForTargetSync` | Private receiver methods; receiver already says manager/window. |
| `daemonLogOutput`, `daemonListenArgs` | `logOutput`, `listenArgs` | Private package-local helpers; direct rename. |
| API `system.WindowManager` and handlers such as `WindowStateHandler` | Keep for now | API package names are user/HTTP-facing and clearer with `Window` prefix. |

Also note a non-naming hygiene issue found during audit: some window manager
comments are duplicated after Stage C2. That should not be fixed in D0; if fixed
later, keep it separate from semantic renaming or include it as comment-only
cleanup in the same D2 PR.

### D2/D3 candidate: metrics query names

Risk class: **compat bridge / defer**.

Metrics has several names that are technically repetitive but semantically clear
because they distinguish model/API-key/time-window aggregates.

| Current name | Suggested name | Risk notes |
| --- | --- | --- |
| `(*ModelStats).Stats` | `ByWindow` or `WindowStats` | Exported within internal metrics; used by API tests and summary builders. Bridge if renamed. |
| `(*APIKeyStats).Stats` | `ByModel` or `ModelStats` | Same compatibility concern. |
| `StatsSummary` on collectors / `DefaultStatsQuerier` | `Summary` / `DefaultQuerier` | Lower confidence: current names communicate LLM stats API intent. Defer unless D2 already touches metrics API naming. |
| `ServiceStatus`, `ServiceStatusQuerier` | Keep | Clear API/domain term and serializes as status response; not worth churn. |
| `ChannelTimeSeriesResponse`, `AgentTokenTimeSeriesResponse`, etc. | Keep | Exported DTO-like Go names align dashboard payload semantics. |

### D3/defer: `desktop/internal/cmd` CLI command surface

Risk class: **protected / explicit CLI review required**.

`desktop/internal/cmd` is included in the full-Desktop surface inventory because
it is one of the larger declaration surfaces, but command-package names are not
a mechanical Stage D rename target. Cobra command names, aliases, flag names,
usage strings, environment-variable references, and package-level command helper
names should be treated as user-facing CLI/documentation contracts unless a
separate CLI compatibility review proves the rename is internal-only. Private Go
helpers inside `cmd` may be renamed later, but only in a small CLI-scoped batch
with before/after command behavior checks, not as part of broad stutter cleanup.

### D3/defer: `promptcompiler.Compiler.Compile*`

Risk class: **defer / likely keep**.

Methods such as `CompileRuntimeInput` and `CompileThreadContract` technically
stutter with `Compiler`, but the verb `Compile` is the domain action and makes
call sites readable. Do not prioritize these in D1/D2.

### Protected contracts and names not to mass-rename

Do not rename these merely for Go stutter cleanup:

- Raw MCP tool names, MCP server names, MCP method strings, OAuth protected
  resource paths, and MCP session ID wire values.
- JSON/YAML tags in DTOs, AgentTeam WebSocket messages, daemon transport remote
  endpoint payloads, app-build API DTOs, and exec catalogs.
- API route names, dashboard response field names, and CLI/environment variable
  names such as `AGENTTEAM_AGENT_TOOLS_LEASE`.
- CLI command-surface names under `desktop/internal/cmd`, including Cobra command
  names/aliases, flag names, usage text identifiers, and command-package helper
  names whose wording appears in docs or user-visible behavior.
- DB/schema labels, Prometheus/TSDB metric labels, profile config keys, runtime
  names, recovery strategy strings, and provider protocol message strings.
- Generated or external protocol DTO names where the provider prefix is useful
  documentation, especially Anthropic DTOs and Codex App Server wire structs.

## Recommended Stage D batches

### D1b: AgentTeam channel private `agentteam*` Go helper cleanup

Scope:

- `desktop/internal/channel/agentteam` private registry/helpers/ports listed above.
- No MCP tool/schema/string changes.

Verification:

- `git diff --check`
- changed Go files `gofmt -l`
- `cd desktop && go test ./internal/channel/agentteam -count=1`
- If MCP inventory files change, run the agentteam MCP inventory tests explicitly.

### D1c: exec exported stutter with aliases

Scope:

- `desktop/internal/wire/exec`, `desktop/internal/api/exec`, relevant
  dispatcher/e2e call sites.
- Introduce canonical `Spec`, `Lease`, `AuthorizeRequest`, `ExecuteRequest`,
  etc., while keeping aliases or forwarding methods for one transition PR if
  reviewers want low-risk rollout.

Verification:

- `git diff --check`
- changed Go files `gofmt -l`
- `cd desktop && go test ./internal/exec ./internal/api/exec ./internal/dispatcher -run 'Exec|RouterExec' -count=1`
- `cd desktop && go test -tags e2e ./e2e -run AgentTool -count=1` if e2e time is acceptable.

### D2a: appbuild/profile/skill sync naming

Scope:

- `appbuild.SessionStatus`/accessors with bridge aliases.
- `profile.SkillManager.SkillsDir` and `skillprovider.Sync*ForAgent` family if
  D1c does not already touch adjacent agent-tools/skill contracts.

Verification:

- `git diff --check`
- changed Go files `gofmt -l`
- `cd desktop && go test ./internal/appbuild ./internal/api/dashboard ./internal/wire/mcp ./internal/profile ./internal/skillprovider ./internal/dispatcher -count=1`

### D2b: driver and daemon/window private naming

Scope:

- Codex/Claude/OpenCode private receiver-state names that duplicate the driver
  receiver.
- Daemon/window manager private helper names where the package/receiver carries
  context.
- Avoid runtime protocol DTO mass-renames unless explicitly reviewed.

Verification:

- `git diff --check`
- changed Go files `gofmt -l`
- `cd desktop && go test ./internal/agent ./internal/daemon ./internal/dispatcher -count=1`
- `cd desktop && go test -tags e2e ./e2e/api ./e2e/protocol -count=1`

### D3: final naming consistency review

Scope:

- Confirm D1/D2 merged or explicitly deferred.
- Re-run the AST inventory and compare high-confidence stutter families.
- Record remaining protected names with reasons.
- Update #t1444/#t1451 handoff with before/after examples.

Verification:

- `git diff --check`
- targeted package tests for any doc/code touched in final cleanup.

## Review checklist for #t1446

- Coverage: `desktop/` Go declarations, not only Stage B/C changed files.
- Every implementation candidate has a compatibility class.
- D1/D2 batches match existing task split (#t1447/#t1449) and remain reviewable.
- Protected contracts are explicit enough to prevent mechanical wire/schema/tool
  renames.
- No production code was renamed in this D0 branch.
