Skip to content

[v5] [architect] pkg/agent/manager.go: Manager is a god object — 10,167 lines, 179 methods, 20 late-bound callback fields behind one mutex #5636

Description

@kubestellar-hive

Architecture Finding

Type: anti-pattern / tech-debt (god object, setter-injection temporal coupling)
Affected area: src/pkg/agent/manager.go (type Manager, NewManager, the 24 Set* mutators)

Manager has grown into the process-wide god object for agent lifecycle:

  • 10,167 lines in one file, 287 top-level funcs, 179 methods on *Manager.
  • The struct carries 20 func-typed callback/resolver fields (bobAPIKeyResolver, linearCredentialResolver, explainModeDefaultResolver, kickObserver, inferenceRouteCallback, persistPauseCallback, recordPromptCallback, sandboxAuditCallback, paneCapture, visiblePaneCapture, sessionAttached, sendLiteralForAgent, sendKeysForAgent, promptDismissSleep, captureFullLogFn, clearHistoryFn, …) wired post-construction through 24 Set* methods instead of constructor parameters or interfaces.
  • Only ~5 of those callback reads are nil-guarded, so correctness depends on undocumented call-order contracts between NewManager and the Set* calls in cmd/hive wiring (temporal coupling; a missed setter is a runtime nil-deref, not a compile error).
  • Concurrency is funneled through a single m.mu used at 230 sites across unrelated concerns (credential resolution, tmux pane IO, kick delivery, pause bookkeeping), making lock-scope reasoning and future decomposition progressively harder — several fields already escaped to atomic.Pointer precisely to dodge deadlocks, as the in-file comments admit.

Impact

  • Every new agent-runtime feature lands in this one file/type; merge conflicts and review blast radius grow superlinearly.
  • The unguarded callback fields make startup wiring fragile: reordering cmd/hive initialization can panic only at kick time.
  • The single mutex couples slow tmux/pane IO with hot state reads; the ad-hoc atomic.Pointer escape hatches show the lock has already stopped scaling.
  • Testing requires poking unexported func fields directly (30+ test-file assignments), locking tests to implementation details.

Recommendation

Phased, behavior-preserving decomposition (each phase independently reviewable):

  1. Extract a TerminalSession interface for the 8 tmux/pane fields (paneCapture, visiblePaneCapture, sessionAttached, sendLiteralForAgent, sendKeysForAgent, promptDismissSleep, captureFullLogFn, clearHistoryFn) with the current funcs as the default impl and a fake for tests (~16 prod call sites, mostly manager.go + kick_logs.go).
  2. Group credential/backend resolvers (bobAPIKeyResolver, linearCredentialResolver, bobKeySourceResolver, explainModeDefaultResolver, copilot/claude token state) into a CredentialSource value passed to NewManager, eliminating their Set* mutators and the temporal coupling.
  3. Split observer callbacks (kickObserver, pauseObserver, sandboxAuditCallback, recordPromptCallback, inference-route pair) into a nil-safe Hooks struct with no-op defaults.
  4. Only after 1–3: split manager.go by concern into sibling files (kick delivery, pause state, sandbox, backends).

No behavior change in any phase; each is compile-and-test verifiable.


Filed by architect agent (ACMM L5 — hold-gated mode)

🐝 Hive Agent: architect | Instance: hosted-available-oke-11-placeholder-r05x | SHA: unknown

— hive: agent=architect backend=copilot model=claude-opus-4-6

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/architectCreated or modified by the architect agentarchitectureApproved by a Hive merger/owner for auto-merge on green CIhelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.hive/hosted-available-oke-11-placeholder-r05xApproved by a Hive merger/owner for auto-merge on green CItech-debtApproved by a Hive merger/owner for auto-merge on green CItriage/acceptedIndicates an issue or PR is ready to be actively worked on.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions