Skip to content

Decompose ui/app.py into focused controllers without changing behavior #187

Description

@hellices

Goal

Decompose src/korvid/ui/app.py into focused UI controllers while preserving
all current behavior and the existing approval/audit security invariants.

Current gap

app.py is currently about 10,000 lines and centralizes application
composition, navigation, watches, context switching, manual writes, agent/MCP
bridging, Helm/OLM workflows, logs, shells, transfer, port-forwarding, and
several modal lifecycles.

The test suite is strong, but this concentration still creates practical risk:

  • unrelated features collide in the same file and class;
  • safe changes require holding too much state and control flow in one context;
  • ownership and lifecycle boundaries are difficult to review;
  • security-sensitive write paths are mixed with ordinary presentation logic;
  • future integrations will make the file grow faster unless the boundary is
    corrected now.

Refactoring approach

This must be an incremental extraction, not a rewrite.

  1. Produce a responsibility/state map for KorvidApp.
  2. Add characterization tests where behavior is not already pinned.
  3. Extract cohesive controllers behind typed interfaces, starting with the
    least coupled area and merging one responsibility at a time:
    • navigation, namespace/context, and pane lifecycle;
    • write preparation, confirmation, preview, execution, and audit outcomes;
    • embedded agent, follow mode, and MCP bridge/proposals;
    • Helm and OLM workflows;
    • logs, shell/debug, transfer, and port-forward session operations.
  4. Keep Textual message handling and composition in the UI layer.
  5. Keep dependency construction in __main__.py; do not introduce a DI
    container, service locator, or module-level mutable singleton.

Non-negotiable invariants

  • Agent writes still enter only through the user-confirmation path.
  • Approval dialogs remain confirmable only by user keystrokes.
  • Audit-before-mutation remains fail-closed.
  • Read-only and protected-context behavior remain unchanged.
  • Context switches invalidate or retarget every context-bound operation.
  • Existing layer rules continue to pass tach check.

Acceptance criteria

  • app.py is reduced to at most 5,000 lines and primarily owns composition,
    Textual event translation, and top-level lifecycle.
  • Each extracted controller has one documented responsibility, typed
    dependencies, and focused tests.
  • No controller reaches back into KorvidApp through an untyped app/service
    locator.
  • Security-sensitive write orchestration has a single reviewable entry path,
    with characterization tests proving the invariants above.
  • The full quality gate and live-cluster contract suite remain green after the
    staged extraction.
  • A dependency diagram in developer documentation reflects the resulting
    boundaries.

Out of scope

  • UI redesign or keybinding changes.
  • Replacing Textual's message system.
  • Combining the extraction with new product features.
  • Chasing line count by creating thin pass-through modules without coherent
    ownership.

Metadata

Metadata

Assignees

Labels

area: uiTextual application, screens, widgets, and interaction designconcern: architectureModule boundaries, dependency direction, and system structureconcern: reliabilityGraceful degradation, lifecycle safety, and operational correctnessenhancementNew feature or requestpriority: highShould be scheduled ahead of normal-priority work

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions