Files
cowork-local/docs/refactor/COWORK_LOCAL_REFACTOR_PLAN.md
T
thanhnv 9fbebb668a
CI / test (pull_request) Canceled after 0s
Cowork Local Refactor Plan
2026-08-14 19:11:44 +07:00

97 KiB
Raw Blame History

Cowork Local Refactor Plan

Phạm vi: phân tích source và lập kế hoạch; tài liệu này không thực hiện refactor, không di chuyển file và không thay đổi hành vi runtime.

Baseline tại thời điểm phân tích: 162 file được CodeGraph index, khoảng 45.000 dòng Python; 81 passed khi chạy .venv/bin/python -m pytest tests -q.

1. Executive Summary

Cowork Local là ứng dụng desktop Python/PySide6 chạy local-first. Luồng chính hiện tại đi từ __main__.py tới app.run(), dựng một AppContext, sau đó để MainWindow khởi tạo UI, scheduler và phần lớn lifecycle của ứng dụng. Runtime agent, provider, MCP, connector, workspace và persistence đã có các module riêng, nhưng UI vẫn trực tiếp điều phối nhiều concern đó. Kết quả là repository có module decomposition nhưng chưa có dependency boundary rõ.

Các điểm quan trọng nhất từ source hiện tại:

  • ui/chat_panel.py::ChatPanel, ui/co4e_tab.py::Co4ETab, ui/folder_tab.py::FolderTab, app.py::MainWindow, state.py::AppContext và config.py::AppConfig đang là các điểm coupling lớn.
  • Model routing, provider selection, usage tracking, persistence và filesystem operation bị lặp hoặc gọi trực tiếp từ nhiều screen.
  • core/chat_agent.py là runtime seam có giá trị: phần lớn Cowork, scheduled Cowork và Co4E cuối cùng đều dùng run_cowork(). Tuy nhiên orchestration trước/sau runtime vẫn nằm trong UI hoặc executor.
  • Tool security chưa có capability model thống nhất. Built-in command có classifier/sandbox/confirmation, nhưng generic MCP/REST tool có thể đi qua đường thực thi khác mà không được phân loại read/write/execute tương đương.
  • active_project_id, project history directory và routed provider/model là mutable state dùng chung. Một turn chạy nền có thể quan sát project hoặc route mới nếu người dùng đổi selection trong lúc turn đang chạy.
  • Persistence là nhiều JSON/JSONL store tự quản lý, chủ yếu ghi trực tiếp, không có atomic-write/schema-version/locking policy dùng chung. Routing assessment store là ví dụ tốt hiếm hoi đã có atomic replace và backup.
  • Hai circular import ở mức module được CodeGraph phát hiện: core.model_pricing ↔ core.usage_tracker và core.agent_security ↔ core.agent_security_alert.
  • Test baseline xanh nhưng rất hẹp: đa số test dành cho core/routing; ngoài routing chỉ có coverage đáng kể cho config security. Runtime agent, UI orchestration, tool policy, MCP/connectors, persistence và scheduler chưa có safety net tương xứng.

Khuyến nghị không chia repository thành “frontend/backend”. Đây là một process desktop; boundary phù hợp hơn là:

Presentation (PySide6)
        ↓
Application services / use cases
        ↓
Domain & runtime contracts
        ↑
Infrastructure adapters

Composition root nối Presentation, Application và Infrastructure.

Đơn vị refactor chính nên là subsystem/capability, bên trong chia tiếp thành module → class → function. Sau khi application service đã có, UI mới được migrate theo từng screen. Đây là cách giảm conflict tốt nhất giữa nhiều contributor mà vẫn tránh big-bang rewrite.

Roadmap đề xuất 10 EPIC:

  1. Architecture Foundation & Characterization
  2. Configuration, Secrets & Persistence
  3. Model Providers & Routing
  4. Agent Runtime & Conversation Application Service
  5. Tool, MCP & Connector Policy
  6. Workspace, Filesystem & History Isolation
  7. Scheduling & Workflow Runtime
  8. UI/Application Separation
  9. Security Runtime, Sandbox & Observability
  10. Testing, Packaging & Contributor Experience

2. Current Repository Structure

2.1 Cấu trúc cấp cao

cowork_local/
├── __main__.py                 # Python module entrypoint
├── app.py                      # QApplication, MainWindow, bootstrap/lifecycle
├── state.py                    # AppContext service locator + mutable app state
├── config.py                   # DEFAULT_CONFIG + AppConfig JSON persistence
├── paths.py                    # package/resource path helpers
├── i18n.py                     # global translations + listener registry
├── theme.py                    # application styling
├── core/
│   ├── chat_agent.py           # Cowork agent loop
│   ├── code_agent.py           # code-oriented agent loop
│   ├── worker.py               # AgentWorker/QThread bridge
│   ├── task_executors.py       # scheduled task dispatch
│   ├── tasks.py                # task repository + schedule calculation
│   ├── projects.py             # project repository
│   ├── history.py              # conversation persistence
│   ├── co4e*.py                # Co4E definitions, runner, run manager
│   ├── flows.py                # second flow/workflow concept
│   ├── tools.py                # built-in tool schemas + giant dispatcher
│   ├── mcp_client.py           # MCP process/client adapter
│   ├── ext_connectors.py       # generic REST/MCP connectors
│   ├── ms365_*.py              # MS365 auth/Graph/tool adapters
│   ├── routing/                # model routing service/orchestrator/store/prober
│   ├── agent_security*.py      # AI-assisted prompt/command guardrails
│   ├── sandbox_manager.py      # command execution and sandbox selection
│   ├── *_sandbox*.py           # integrity/AppContainer/Windows VM helpers
│   ├── audit_log.py            # active audit query/write path
│   └── ...                     # skills, agents, docs, pricing, telemetry
├── security/
│   ├── command_risk_classifier.py
│   ├── audit_logger.py
│   ├── prompt_validator.py
│   ├── attachment_validator.py
│   └── action_validator.py
├── providers/
│   ├── base.py                 # provider contract and ToolSpec
│   ├── anthropic.py
│   ├── openai_compat.py
│   └── factory.py
├── ui/
│   ├── chat_panel.py
│   ├── cowork_tab.py
│   ├── workspace_tab.py
│   ├── co4e_tab.py
│   ├── folder_tab.py
│   ├── structure_graph_view.py
│   ├── schedule_task_tab.py
│   ├── monitoring_tab.py
│   ├── settings_dialog.py
│   └── ...                     # dashboard, admin, skills, reusable widgets
├── mcp_servers/
│   └── ms365_server.py
├── tests/
│   ├── test_config_security.py
│   └── test_routing_*.py
├── docs/
│   ├── governance/
│   ├── integration/
│   └── gitea/
└── requirements-test.txt

2.2 Nhận xét về package structure

  • Tên core/ hiện không đồng nghĩa với “domain thuần”. Nó chứa Qt worker/scheduler, MCP transport, filesystem repositories, security, telemetry và agent loop; provider adapters lại nằm ở package top-level providers/.
  • ui/ không chỉ chứa presentation. Nhiều widget gọi provider, routing, filesystem, persistence và agent runtime trực tiếp.
  • security/ và các file security trong core/ tạo hai namespace có responsibility chồng lấn.
  • Root modules app.py, state.py, config.py, i18n.py có fan-in/fan-out cao và hoạt động như global infrastructure.
  • core/flows.py và core/co4e*.py cùng mô tả workflow nhưng có model/runtime khác nhau.
  • core/custom_agents.py, core/admin_agents.py và custom agents trong Co4E là ba đường quản lý agent chưa có taxonomy chung.

3. Current Architecture

3.1 Composition và lifecycle

__main__.main() lazy-import app.run(). app.run():

  1. Khởi tạo QApplication.
  2. Load AppConfig.
  3. Tạo AppContext.
  4. Áp dụng language/theme.
  5. Best-effort prune/seed skills và Co4E flows.
  6. Gán audit/usage identity cho account local, role admin.
  7. Tạo và hiển thị MainWindow.
  8. Vào Qt event loop.

MainWindow đồng thời là:

  • composition root của phần lớn screen;
  • controller cho navigation;
  • owner của TaskScheduler;
  • owner của tray/lifecycle;
  • cầu nối settings/theme/language;
  • coordinator cho history/task notification;
  • điểm shutdown MCP.

Đây là kiến trúc “UI-centric service locator”: widget nhận AppContext, rồi tự lấy config/provider/routing/MCP/repository cần dùng.

3.2 Runtime architecture thực tế

flowchart TD
    Entry["__main__.py::main"] --> Run["app.py::run"]
    Run --> Config["AppConfig.load"]
    Run --> Context["AppContext"]
    Run --> Window["MainWindow"]

    Window --> Scheduler["TaskScheduler"]
    Window --> Workspace["WorkspaceTab"]
    Window --> Dashboard["DashboardTab"]
    Window --> Schedule["ScheduleTaskTab"]
    Window --> Monitoring["MonitoringTab"]

    Workspace --> Cowork["CoworkTab / ChatPanel"]
    Workspace --> Co4E["Co4ETab"]
    Workspace --> Folder["FolderTab"]
    Workspace --> Graph["StructureGraphView"]

    Cowork --> Worker["AgentWorker"]
    Co4E --> Worker
    Scheduler --> Worker
    Worker --> ChatRuntime["chat_agent.run_cowork"]
    Worker --> CodeRuntime["code_agent.run_code"]
    Worker --> WorkflowRuntime["Co4ERunner / task_executors"]

    ChatRuntime --> Provider["ProviderFactory → ModelProvider"]
    CodeRuntime --> Provider
    ChatRuntime --> Tools["Built-in tools / MCP / connectors"]
    CodeRuntime --> Tools
    Tools --> FS["Workspace filesystem"]
    Tools --> Security["PermissionGate / security / sandbox"]

    Context --> Config
    Context --> Provider
    Context --> Routing["RoutingService"]
    Context --> MCP["MCP clients and connector cache"]
    Context --> Project["Active project"]

3.3 Business logic đang nằm ở đâu?

Business logic phân tán ở bốn vùng:

  • UI: turn orchestration, routing interaction, provider/model selection, session save, usage labels, filesystem editing, workflow CRUD và settings persistence.
  • Core runtime: agent loop, tool dispatch, context budgeting, task/flow execution.
  • AppContext/config: runtime object construction, mutable current project, connector lifecycle, provider factory, routing singleton.
  • Infrastructure-like modules: JSON repositories, providers, MCP transport, REST connector, sandbox và audit.

Không có application layer ổn định đứng giữa PySide6 và runtime/infrastructure.

4. Main Application Flow

4.1 Startup

python -m cowork_local
  → __main__.main()
  → app.run()
  → AppConfig.load()
  → AppContext(config)
  → seed/prune defaults
  → MainWindow(ctx)
  → eager screens + TaskScheduler
  → lazy Dashboard/Schedule/Monitoring
  → QApplication.exec()

Ứng dụng hiện chạy local/admin; LoginDialog không nằm trên startup path.

4.2 Cowork chat turn

Composer.submitted
  → ChatPanel.submit()
  → ChatPanel._start_turn()
      → parse /skill and /agent
      → snapshot messages and output directory
      → UI-owned model routing
      → CoworkTab.build_job()
      → AgentWorker(QThread)
          → attachment extraction
          → CoworkTab worker job
              → build provider
              → AppContext.build_mcp_tools()
              → load project context
              → optionally create PermissionGate
              → chat_agent.run_cowork()
                  → compose prompt/tool set
                  → provider.chat()
                  → execute external or built-in tool
                  → emit events
      → ChatPanel._on_event()
      → ChatPanel._on_finished() / _on_failed()
          → render
          → save history
          → promote output
          → record usage/notifications
          → start queued turn

Điểm tốt: provider call và phần lớn task nặng chạy trong AgentWorker, không nằm trên UI thread. Điểm yếu: execution context chưa được snapshot đầy đủ; worker vẫn đọc mutable selection/project từ widget và AppContext.

4.3 Agent loop

core/chat_agent.py::run_cowork():

  1. Tạo ToolContext từ workspace/sandbox config.
  2. Ghép built-in tools với MCP/connector tools.
  3. Ghép system prompt, skill, security và project context.
  4. Gọi provider theo vòng lặp.
  5. Compact context khi cần.
  6. Xử lý tool call:
    • internal plan event;
    • external tool executor;
    • built-in execute_tool();
    • command confirmation/security cho một số đường;
  7. Emit stream/event về UI.
  8. Cleanup scratch/intermediate output.

core/code_agent.py::run_code() có loop tương tự nhưng có Plan mode và tập write-tool gate riêng. Hai runtime có common concepts nhưng chưa dùng chung một runtime kernel.

4.4 Scheduled task

TaskScheduler (QTimer)
  → due task
  → AgentWorker
  → task_executors.execute_task()
      → cowork / code / co4e / flow / script branch
      → runtime tương ứng
      → save artifact + history + status

core/tasks.py vừa là repository, vừa tính lịch; core/task_executors.py vừa dispatch type, vừa orchestration, persistence và notification-related output.

4.5 Co4E

Co4ETab
  → workflow CRUD/canvas
  → Co4ERunManager
  → Co4ERunner
      → execute graph in waves
      → each agent node calls run_cowork(run_to_completion=True)

Co4E chat riêng trong UI cũng gọi run_cowork() nhưng dùng enforce_rules=False và không có PermissionGate, tạo policy khác Cowork chính.

4.6 Folder AI và GraphRAG

  • FolderTab quản lý tree/editor/viewer/terminal, tự gọi routing/provider, tạo plan/edit response, ghi file sau confirm và có image generation path.
  • StructureGraphView scan graph ở background worker, nhưng hỏi đáp graph tự build prompt, chọn provider, stream response và record usage trong widget.

5. UI / Screens Map

5.1 Số lượng surface chính

  • 4 top-level navigation page: Dashboard, Schedule, Workspace, Monitoring.
  • 5 Workspace surface: Project Settings, Cowork, Co4E, Folder, GraphRAG.
  • 8 Monitoring view khi chạy local/admin: Overview, Security Events, MCP History, Action Logs, Agent Status, Agents Admin, Tools, Icons.
  • 1 floating Help Agent surface.
  • 16 QDialog class được định nghĩa. Một số là dormant/legacy (LoginDialog, account flow, MCP server dialog cũ), do đó không nên dùng con số này như active product flow mà chưa xác nhận runtime navigation.

5.2 Screen/component map

Surface File/class hiện tại Responsibility thực tế Business logic trực tiếp Direct dependencies đáng chú ý Vấn đề / hướng refactor
Application shell app.py::MainWindow Navigation, lazy tabs, tray, lifecycle, scheduler, settings, notifications Có AppContext, TaskScheduler, hầu hết screen Giữ shell chỉ làm navigation/lifecycle; chuyển bootstrap và app coordination sang composition/application services
Dashboard ui/dashboard_tab.py::DashboardTab Summary, suggestions, history/usage views Có provider-backed suggestion jobs và direct telemetry query usage, history, provider, worker Tách dashboard query service và suggestion use case
Schedule ui/schedule_task_tab.py::ScheduleTaskTab Task list/editor/run controls CRUD, schedule/run orchestration core.tasks, scheduler, worker, providers Tách TaskApplicationService; UI chỉ edit command/view state
Task editor ui/task_editor_dialog.py::TaskEditorDialog Create/edit task, AI assist _save và AI creation logic lớn config, providers, tasks, flows/Co4E Tách validation, DTO mapping, AI task drafting
Workspace shell ui/workspace_tab.py::WorkspaceTab Project selection, history, surface switching Mutate global project/history context projects, history, config, child screens Tạo immutable WorkspaceSession; không mutate config directory toàn cục
Project settings ui/workspace_tab.py::_build_project_tab và các project CRUD methods Project metadata and settings Direct project/config persistence project repo, filesystem Dùng workspace use case/repository interface
Cowork ui/cowork_tab.py::CoworkTab + ui/chat_panel.py::ChatPanel Conversation UI và agent execution Rất nhiều: routing, job build, MCP, provider, persistence, output, queue provider factory, routing, runtime, history, tools, security, worker Tách ConversationApplicationService, execution snapshot, presenter/event reducer
Co4E ui/co4e_tab.py::Co4ETab Workflow canvas/CRUD/run/chat/history Rất nhiều Co4E repo/runner, routing, provider, usage, runtime Chia editor presenter, run service, chat service; dùng chung policy Cowork
Folder ui/folder_tab.py::FolderTab File browser/editor/viewer/terminal và AI editing Rất nhiều filesystem/provider/routing/image logic filesystem, provider, routing, image endpoint, worker Tách file service, AI edit use case, terminal adapter; giữ UI diff/confirm
GraphRAG ui/structure_graph_view.py::StructureGraphView Scan graph và graph Q&A Provider prompt/stream/usage trong widget structure graph, codebase memory, provider, worker Tách graph index/query service và Q&A use case
Monitoring shell ui/monitoring_tab.py::MonitoringTab 8 admin/observability views Query/refresh orchestration audit, usage, agents, tools, MCP Mỗi view dùng read-only query service; giữ refresh timer ở presenter
Settings ui/settings_dialog.py::SettingsDialog Provider, security, sandbox, UI settings Direct mutate/save config, model lookup, provider calls config, providers, routing, sandbox Dùng typed settings facade và secret store; không ghi secret trực tiếp
Accounts/agents/tools/skills dialogs ui/accounts_tab.py, ui/agents_admin_tab.py, ui/tools_admin_tab.py, ui/skills_dialog.py Admin CRUD Direct repositories và một số AI jobs JSON stores, provider, worker Tách CRUD application services; xác nhận active/dormant trước migrate
Help agent ui/help_agent_widget.py::HelpAgentWidget Floating assistant Direct agent/provider orchestration provider, worker, config Reuse conversation service với tool profile riêng
Connector dialogs connector/Jira dialogs trong ui/ Configure/test integrations Direct config save và network test REST/MCP/Jira, config Tách connector service; test connection phải chạy worker

5.3 UI-specific findings

  • Provider/model được gọi trực tiếp từ nhiều screen, không chỉ Cowork.
  • Filesystem access xuất hiện trên nhiều UI module; FolderTab là nơi tập trung nhất nhưng Workspace, history, settings và editor dialogs cũng ghi trực tiếp.
  • Routing interaction bị lặp giữa ChatPanel._apply_routing, Co4ETab._apply_co4e_routing và FolderTab._ai_apply_routing.
  • ChatPanel xử lý agent event như một state machine ngầm nhưng state, rendering và persistence nằm trong cùng class.
  • Hầu hết heavy provider/extraction job dùng AgentWorker; tuy nhiên connector connection test có synchronous REST/MCP startup từ click handler và có thể block UI.
  • Reusable primitives như AgentWorker, provider picker, usage context, modal routing confirmation và tool/event rendering chưa được đóng thành application/adapter APIs dùng chung.

6. Core Subsystems Map

Subsystem Current responsibility Files/modules chính Public API thực tế Dependencies/coupling Potential boundary
Agent Runtime Prompt assembly, provider loop, tool calls, context compaction, event emission core/chat_agent.py, core/code_agent.py, core/context_budget.py, core/plan.py run_cowork(), run_code() config dict, providers, tools, security, filesystem, usage Runtime kernel nhận typed request + ports, trả typed events/result
Qt execution bridge Chạy synchronous job trên QThread, permission request/event core/worker.py, core/permissions.py AgentWorker, PermissionGate PySide6, UI callback conventions Platform/Qt adapter; domain không import Qt
Model Provider Normalize message/tool/stream API; call Anthropic/OpenAI-compatible endpoints providers/* ModelProvider.chat, ToolSpec, ProviderFactory.create config shape, usage tracking, HTTP SDKs Provider contract trong domain; descriptors/implementations ở infrastructure
Model Routing Probe/assess/route model, cache/store assessment core/routing/* RoutingService.route, orchestrator/prober/store provider metadata, config, UI routing mode Application routing service + provider catalog port
Workspace Project/workspace metadata, active project, history/output paths core/projects.py, core/history.py, ui/workspace_tab.py, state.py dict CRUD functions + mutable active_project_id config path mutation, UI, filesystem WorkspaceSession snapshot + repository/filesystem ports
Filesystem/tools Read/write/edit/run/install/fetch/Jira core/tools.py, sandbox modules tool schemas, execute_tool() workspace path, audit, security, subprocess/network Tool registry of handlers with capability metadata
MCP Spawn/communicate with MCP servers, expose tools core/mcp_client.py, state.AppContext.build_mcp_tools, mcp_servers/* client start/call/close, external executor config, process lifecycle, UI monitoring ToolSource/McpClient adapters + lifecycle manager
Connectors Generic REST/MCP and MS365 actions core/ext_connectors.py, core/ms365_*.py connector tool specs/executors config secrets, HTTP, MCP, Graph Connector plugin descriptor + secret reference + capability policy
Security Prompt/attachment/command checks, permission, sandbox, audit core/agent_security*.py, core/security_rules.py, security/*, sandbox files multiple validators/classifiers/loggers runtime, UI, provider, filesystem One policy decision API; sandbox executor and audit as adapters
Scheduling Store tasks, calculate due time, timer/run dispatch core/tasks.py, core/task_scheduler.py, core/task_executors.py CRUD functions, TaskScheduler, execute_task Qt, runtime, persistence, UI Task repository + scheduler clock + execution application service
Workflows Co4E graph and separate flows core/co4e.py, core/co4e_runner.py, core/co4e_run_manager.py, core/flows.py dict CRUD, runner callbacks runtime, usage, UI, tasks Explicit workflow definitions + runner port; preserve product concepts until unified intentionally
Configuration Defaults, env overrides, runtime settings config.py AppConfig.load/save, nested dict almost every module typed settings sections + config repository
Persistence JSON/JSONL across config directory projects/history/tasks/skills/agents/co4e/flows/usage/audit/routing stores module-level CRUD returning dict direct Path, shared mutable config paths repository interfaces + common atomic JSON/JSONL primitives
Observability Usage, pricing, audit, shared telemetry, monitoring core/usage_tracker.py, core/model_pricing.py, core/audit_log.py, telemetry modules global record/load/summarize functions global identity/thread-local context/files event sink/query services

7. Dependency Map

7.1 Static hotspots

CodeGraph cho thấy fan-out cao nhất ở:

  • ui.chat_panel (21 module dependencies)
  • app (20)
  • core.task_executors (16)
  • ui.folder_tab (16)
  • ui.co4e_tab (15)
  • ui.structure_graph_view (14)
  • core.chat_agent (13)

Fan-in cao nhất gồm i18n, ui.icons, config, core.worker, state và providers.base. Impact analysis cho thấy thay đổi AppConfig có thể chạm 310 symbol, ChatPanel 246 symbol và AppContext 181 symbol; trong khi run_cowork() có impact hẹp hơn, 17 symbol. Điều này xác nhận runtime function là seam tốt hơn để ổn định contract so với tiếp tục thêm responsibility vào context/UI.

7.2 Dependency map hiện tại

flowchart LR
    UI["ui/* + MainWindow"] --> State["AppContext"]
    UI --> Config["AppConfig / dict"]
    UI --> Runtime["chat/code/Co4E/task runtime"]
    UI --> Providers["providers + routing"]
    UI --> Repos["projects/history/tasks/skills/agents"]
    UI --> FS["Path / filesystem"]

    State --> Config
    State --> Providers
    State --> Routing["routing"]
    State --> MCP["MCP/connectors"]
    State --> Project["active project"]

    Runtime --> Providers
    Runtime --> Tools["tools"]
    Runtime --> Security["security/permission"]
    Runtime --> Repos
    Runtime --> Usage["usage/audit"]

    Tools --> FS
    Tools --> Sandbox["sandbox/subprocess"]
    Tools --> MCP
    Tools --> Security

    Repos --> ConfigDir["~/.cowork_local"]
    Config --> ConfigDir
    Usage --> ConfigDir

Vấn đề không phải là dependency tồn tại, mà là presentation có thể đi thẳng tới mọi tầng và concrete infrastructure import ngược vào runtime. Không có một direction rule có thể enforce.

7.3 Circular dependencies

Cycle Nguyên nhân Hướng xử lý
core.model_pricing ↔ core.usage_tracker Pricing và usage vừa dùng default/format của nhau vừa cùng chịu responsibility tính cost Tách value types/rate calculation thuần ra module domain; usage writer chỉ ghi event
core.agent_security ↔ core.agent_security_alert Decision/evaluation và alert UI/notification tham chiếu ngược Security policy trả decision/event; presentation adapter quyết định alert

8. Architecture Problems

8.1 Findings ưu tiên

ID File / symbol Current problem Why it is a problem Suggested direction
A01 ui/chat_panel.py::ChatPanel God class: UI, queue, routing, attachments, provider job, events, output, history, usage Impact 246 symbol; khó test và thay đổi một concern mà không ảnh hưởng turn lifecycle Conversation application service + immutable request + presenter/event reducer
A02 ui/co4e_tab.py::Co4ETab Workflow editor, persistence, runner, chat, routing, usage cùng class Hai lifecycle editor/run/chat đan nhau; khó chia contributor Tách editor controller, workflow service, run service, chat adapter
A03 ui/folder_tab.py::FolderTab File manager, editor, terminal, AI plan/edit, routing, image generation Direct FS/network/provider; rủi ro data loss và UI khó test File workspace service + AI edit use case + terminal/image adapters
A04 app.py::MainWindow Composition, navigation, scheduler, tray, settings, notifications, shutdown App lifecycle và UI shell coupling bootstrap.py/composition root; MainWindow chỉ shell
A05 state.py::AppContext Service locator và mutable global state Widget lấy bất kỳ concrete service; background job có thể đọc state đã đổi Explicit dependencies; immutable execution/workspace snapshot
A06 config.py::AppConfig/DEFAULT_CONFIG Untyped god config, nested dict mutate rải rác, save không atomic Impact 310 symbol; typo/dynamic attr không bị phát hiện; corrupt file khi crash Typed setting sections + repository + atomic writes
A07 Nhiều UI modules UI gọi provider/routing/filesystem/repository trực tiếp Không có application boundary; duplicate workflow Use cases trả DTO/event, UI chỉ bind/render/confirm
A08 ChatPanel._apply_routing, Co4ETab._apply_co4e_routing, FolderTab._ai_apply_routing Routing logic/modal flow bị lặp Fix hoặc policy change phải sửa nhiều screen Một routing application service; UI callback cho confirmation
A09 providers/factory.py, config.py, Settings UI Provider registry hard-code và metadata phân tán Thêm provider phải sửa factory, defaults, labels, settings và routing metadata Provider descriptor registry là single source of truth
A10 core/tools.py::execute_tool Giant if/elif dispatch Handler, schema, capability, audit không co-locate; khó thêm/test tool Tool registry: descriptor + handler + capability + tests
A11 MS365/external connector executors Action dispatch lớn, semantics read/write không chuẩn hóa Permission behavior khác built-in tools Chuẩn hóa connector action thành tool descriptor/capability
A12 run_cowork() external tool path extra_tools có thể execute trước built-in command gate MCP/REST write/delete có thể không nhận cùng confirmation/security policy Policy gateway áp dụng cho mọi tool call trước executor
A13 Co4ETab chat path Gọi run_cowork(enforce_rules=False, gate=None) Policy khác Cowork chính và khó audit Named policy profile; không dùng boolean bypass mơ hồ
A14 core/*security*, security/* Hai security namespace, validator/audit chồng lấn Không rõ authoritative path; dead wrapper dễ tạo cảm giác bảo vệ giả Security decision service duy nhất; consolidate sau characterization
A15 security/prompt_validator.py, security/attachment_validator.py, security/action_validator.py Không thấy active call site trong graph/source Candidate dead code làm contributor hiểu sai Xác nhận bằng runtime/contract tests rồi deprecate/remove ở PR riêng
A16 core/audit_log.py và security/audit_logger.py Hai event format/store path Monitoring và sandbox có thể đọc/ghi dữ liệu không đồng nhất Canonical audit event schema + append/query adapters
A17 core/ext_connectors.py::RestApiConnector Generic method gồm cả DELETE; secret/config và execution gần nhau Không có per-action capability/approval rõ Allow-list action descriptors; secret reference; policy gateway
A18 Settings/Jira/connector dialogs API key/token được lưu plaintext trong config.json Vi phạm expectation production-grade và tăng blast radius OS keyring/secret store; config chỉ lưu reference/non-secret
A19 core/agent_security.py AI-assisted guardrail fail-open theo thiết kế Không thể coi là hard security boundary Ghi rõ advisory vs enforced; deterministic policy phải fail-closed ở action boundary
A20 sandbox config/manager Một số option/backend field không ảnh hưởng đường chạy; direct backend “block network” chủ yếu qua proxy env UI/config có thể overstate mức isolation Capability matrix theo platform + integration tests + honest UI copy
A21 Hầu hết JSON repositories Ghi trực tiếp, không schema version/locking/backups dùng chung Crash/concurrent writer gây corrupt/lost update Common atomic store; per-repository schema/migration
A22 WorkspaceTab._load_current + history/config path Mutate config._project_history_dir toàn cục Turn của project A hoàn tất sau khi chuyển B có thể save vào history B Snapshot repository/path theo turn, không resolve từ global lúc finish
A23 CoworkTab.build_job/ChatPanel routed fields Worker lấy provider/model/project policy từ mutable UI/context Concurrent/queued turn có thể dùng route hoặc policy của turn khác Tạo immutable ConversationExecutionRequest trước khi start worker
A24 AppContext.active_project_id Current project dùng chung cho UI và background work Race logic dù Python data access không crash WorkspaceSessionId truyền explicit qua use case
A25 core/flows.py và core/co4e*.py Hai workflow model không có boundary/taxonomy rõ Contributor không biết extend concept nào Document semantics; adapter/common run contract trước khi cân nhắc unify
A26 agents/accounts/login modules Một số flow không reachable từ startup local/admin Maintenance burden, docs/source drift Mark dormant; telemetry/source graph confirmation; removal riêng, không lẫn refactor
A27 Runtime/provider/store functions Nhiều dict contract và hidden side effect Khó type-check, mock và biết required fields Typed DTO ở boundary; internal migration incremental
A28 core/tasks.py, core/task_executors.py Repository, scheduling math, dispatch và artifact persistence đan nhau Scheduler test cần filesystem/Qt/runtime Tách TaskRepository, schedule calculator, execution service
A29 core/usage_tracker.py và global identity/context Global identity + thread-local usage labels + file append Khó inject/test; lifecycle implicit Usage event sink/context explicit trong execution request
A30 i18n.py Gần 3.000 dòng data và global listener registry Merge conflict cao khi nhiều screen thêm text Tách catalogs theo feature ở phase cuối; giữ API tr() tương thích

8.2 Testability và hidden side effects

  • Provider implementations tự record usage; caller cũng quản lý usage context bằng thread-local.
  • UI completion handler vừa render vừa persist/promote/notify.
  • AppConfig.save() và repository CRUD ghi filesystem ngay.
  • AppContext.build_mcp_tools() có lifecycle/cache side effect.
  • Scheduler là Qt timer, clock và repository không inject được.
  • Một số error path “best effort” nuốt exception; production symptom có thể chỉ xuất hiện như dữ liệu thiếu.

8.3 Dead code policy

Các module login/account/legacy MCP/security validator chỉ được coi là candidate dormant/dead, chưa phải kết luận xóa. Mỗi removal cần:

  1. CodeGraph caller/import check.
  2. Search literal registration/config entrypoint.
  3. Characterization test cho active replacement.
  4. Deprecation note hoặc migration note.
  5. PR removal riêng, không trộn với boundary refactor.

9. Backend/Frontend vs Layered Architecture Decision

9.1 Có nên gọi là backend/frontend?

Không. Cowork Local là một desktop process:

  • PySide6 widget và agent runtime sống cùng process.
  • Không có network API boundary nội bộ ổn định.
  • “Backend” theo cách gọi web sẽ gom provider, runtime, filesystem và persistence vào một hộp quá rộng, không giải quyết dependency direction.
  • “Frontend” dễ khiến team coi widget là nơi hợp lệ để orchestration chỉ vì không có server.

Tên phù hợp hơn:

  1. Presentation: widget, dialog, view state, user confirmation.
  2. Application: use case/coordinator cho chat, routing, workspace, tasks, workflows, connectors.
  3. Domain & Runtime: contract, value object, deterministic policy, agent loop không phụ thuộc Qt/concrete filesystem.
  4. Infrastructure: provider SDK, MCP/REST, filesystem/JSON, config/secrets, sandbox, telemetry.
  5. Platform/Composition: Qt worker/timer, desktop lifecycle và dependency wiring.

9.2 Dependency direction

flowchart TD
    Presentation["Presentation / PySide6"] --> Application["Application services"]
    Application --> Domain["Domain & runtime contracts"]
    Infrastructure["Infrastructure adapters"] --> Domain
    Qt["Qt platform adapters"] --> Application
    Composition["Desktop composition root"] --> Presentation
    Composition --> Application
    Composition --> Infrastructure
    Composition --> Qt

Rules:

  • Domain/runtime contract không import PySide6, concrete provider, AppConfig hoặc Path repository implementation.
  • Application không lấy dependency từ global AppContext; dependency được inject qua constructor/factory.
  • Presentation không gọi provider, filesystem repository hoặc MCP client trực tiếp.
  • Infrastructure implement port từ domain/application; không import widget.
  • Chỉ composition root biết cả concrete UI lẫn concrete infrastructure.
  • Trong migration period, adapter tương thích có thể wrap module-level API cũ; dependency rule áp dụng trước cho code mới, sau đó siết dần.

10. Target Architecture

10.1 Boundary mục tiêu

Layer Responsibility Không nên chứa
Presentation Render state/event, collect input, show confirmation, navigation Provider calls, path resolution, JSON save, tool orchestration
Application Orchestrate one use case, transaction/lifecycle, map DTO, request policy decision Qt widget code, SDK-specific response, raw config dict mutation
Domain & Runtime Agent events/requests, provider/tool contracts, task/workflow/workspace types, deterministic policies Filesystem/network/UI/global state
Infrastructure Provider/MCP/REST clients, JSON repositories, config/secret stores, filesystem, sandbox, audit/usage sinks Product navigation or screen state
Platform/Composition QApplication, QThread/QTimer adapters, lifecycle, DI wiring Business rules và feature CRUD

10.2 Core contracts tối thiểu

Tránh tạo framework DI hoặc repository abstraction cho mọi file. Chỉ introduce contract tại seam đang có nhiều caller/concrete implementation:

  • ModelProvider, ProviderRegistry, ProviderDescriptor
  • RoutingService request/result
  • ConversationExecutionRequest, AgentEvent, AgentResult
  • ToolDescriptor, ToolCapability, ToolExecutor, ToolPolicy
  • WorkspaceSession, WorkspaceRepository, ConversationRepository
  • TaskRepository, TaskExecutionService, Clock
  • WorkflowDefinitionRepository, WorkflowRunner
  • ConfigRepository, typed setting sections, SecretStore
  • AuditSink, UsageSink
  • SandboxExecutor

10.3 Không over-engineer

  • Không dựng event bus toàn ứng dụng.
  • Không bắt mọi class có interface.
  • Không đổi PySide6 sang web framework.
  • Không rewrite đồng thời Cowork, Co4E, Folder và scheduler.
  • Không unify Flow/Co4E trước khi semantics được ghi rõ và có contract tests.
  • Không tạo microservice hoặc IPC chỉ để có “backend”.
  • Ưu tiên dataclass/Protocol nhỏ, constructor injection và adapter trực tiếp.

11. Target Folder Structure

Tên folder cuối cùng có thể điều chỉnh trong R01 ADR, nhưng dependency shape nên như sau:

cowork_local/
├── __main__.py
├── bootstrap.py
├── presentation/
│   ├── shell/
│   ├── dashboard/
│   ├── scheduling/
│   ├── workspace/
│   ├── chat/
│   ├── co4e/
│   ├── folder/
│   ├── graph/
│   ├── monitoring/
│   ├── settings/
│   └── shared/
├── application/
│   ├── conversations/
│   ├── model_routing/
│   ├── workspaces/
│   ├── scheduling/
│   ├── workflows/
│   ├── connectors/
│   ├── monitoring/
│   └── settings/
├── domain/
│   ├── agents/
│   ├── models/
│   ├── tools/
│   ├── workspaces/
│   ├── tasks/
│   ├── workflows/
│   └── security/
├── infrastructure/
│   ├── providers/
│   ├── mcp/
│   ├── connectors/
│   ├── persistence/
│   │   └── json/
│   ├── filesystem/
│   ├── config/
│   ├── secrets/
│   ├── sandbox/
│   ├── telemetry/
│   └── documents/
└── platform/
    └── qt/

Đây là target state, không phải instruction move tree ngay. Trình tự đúng là:

  1. Tạo contract/service tại vị trí ít disruptive.
  2. Wrap implementation hiện tại.
  3. Migrate caller.
  4. Khi import graph đã sạch mới move module trong PR mechanical riêng.

12. Refactor Strategy

12.1 Strategy A — theo từng screen

Ưu điểm:

  • Scope nhìn thấy rõ, dễ demo.
  • Team UI có thể ownership theo screen.
  • Giảm merge conflict giữa các file UI lớn nếu làm tuần tự.

Nhược điểm với repository này:

  • Chat, Co4E, Folder và Graph đều lặp routing/provider/usage; refactor riêng từng screen sẽ tạo nhiều service gần giống nhau.
  • Screen phụ thuộc trực tiếp vào mutable AppContext, config và repository; chưa có foundation thì chỉ “move code” chứ chưa đổi boundary.
  • Security/tool policy là cross-screen và scheduled runtime, không thể giải quyết screen-by-screen.

Kết luận: dùng cho phase UI migration, không dùng làm strategy tổng thể.

12.2 Strategy B — theo từng function/class

Ưu điểm:

  • PR nhỏ.
  • Review dễ nếu contract đã rõ.
  • Hữu ích để extract pure function và test.

Nhược điểm:

  • Dễ tối ưu cục bộ trong God class.
  • Không giải quyết direction/capability ownership.
  • Nhiều contributor có thể tạo abstraction không tương thích.

Kết luận: dùng làm kích thước task/PR bên trong EPIC, không dùng để định nghĩa roadmap.

12.3 Strategy C — theo subsystem/capability

Ưu điểm:

  • Khớp với coupling thực tế: provider/routing, workspace/history, tool/security, scheduling/workflow là cross-screen.
  • Có thể định nghĩa contract test một lần rồi migrate từng caller.
  • Ownership theo EPIC giảm conflict.
  • Cho phép parallel work sau khi R01 chốt boundary và contract names.

Nhược điểm:

  • Cần kỷ luật để không biến thành rewrite cả subsystem.
  • Một số EPIC có dependency, không thể mở tất cả cùng lúc.
  • Product progress ít “nhìn thấy” trong phase foundation.

Kết luận: đây là strategy chính.

EPIC / Subsystem
  → Module boundary
    → Class / Protocol / Adapter
      → Function-level migration task
        → One caller + tests per PR

Áp dụng hybrid:

  • subsystem là đơn vị kiến trúc và ownership;
  • class/function là đơn vị implement/review;
  • screen là đơn vị migrate UI sau khi application service tương ứng sẵn sàng.

Mỗi task phải có input, work, output và validation; không có task “refactor backend” hoặc “clean architecture”.

13. Refactor EPICs

EPIC Tên Boundary chính Giá trị kiến trúc
R01 Architecture Foundation & Characterization Dependency rules, baseline, contracts tối thiểu Tạo safety net và ngôn ngữ chung trước khi nhiều team sửa
R02 Configuration, Secrets & Persistence Typed settings, atomic storage, secret references Giảm global dict/direct write và bảo vệ credential
R03 Model Providers & Routing Provider catalog/factory/routing use case Một đường mở rộng provider và một routing flow
R04 Agent Runtime & Conversation Application Service Immutable request, typed events, runtime ports Tách turn lifecycle khỏi widget
R05 Tool, MCP & Connector Policy Tool registry, capability, policy gateway Một security/approval path cho mọi tool
R06 Workspace, Filesystem & History Isolation Workspace session/repository/path boundary Loại bỏ cross-project mutable path/state
R07 Scheduling & Workflow Runtime Task repository/clock/executor và workflow contracts Tách Qt timer, persistence và runtime dispatch
R08 UI/Application Separation Screen presenter/controller/use-case integration Thu nhỏ God widgets theo từng screen
R09 Security Runtime, Sandbox & Observability Deterministic policy, sandbox truth, audit/usage Policy rõ, event schema thống nhất, monitoring đáng tin
R10 Testing, Packaging & Contributor Experience Test pyramid, dependency manifest, CI, docs Contributor có thể thay đổi một capability mà không hiểu toàn repo

14. Tasks under each EPIC

R01 — Architecture Foundation & Characterization

Objective

Chốt dependency direction, tạo safety net cho hành vi hiện tại và cung cấp contract vocabulary tối thiểu trước khi migrate runtime hoặc UI.

Current Problems

  • Không có rule ngăn UI import concrete infrastructure.
  • Các module “core” không có ownership rõ.
  • Test hiện tại tập trung gần như toàn bộ vào routing.
  • Candidate dead/dormant code chưa có quy trình xác nhận.

Scope

Architecture Decision Record, import graph guardrail, fake provider/tool/repository test doubles, characterization tests cho các seam quan trọng.

Affected modules/files

docs/, tests/, package init mới cho contract nếu cần; đọc app.py, state.py, config.py, core/chat_agent.py, providers/*, core/tools.py nhưng chưa migrate production caller.

What will be changed

  • Ghi dependency rules và module ownership.
  • Tạo test fixtures dùng chung.
  • Characterize event ordering, provider construction, config/persistence shape và tool dispatch hiện tại.
  • Tạo allow-list tạm thời cho violation hiện có để không block mọi PR.

What will NOT be changed

  • Không move toàn bộ package.
  • Không thay runtime behavior.
  • Không xóa candidate dead code.
  • Không introduce DI framework.

Dependencies on other EPICs: Không.

Risk: Thấp. Rủi ro chính là test khóa nhầm bug; mỗi characterization phải ghi rõ “behavior to preserve” hay “known defect to replace”.

Expected outcome

Team có một baseline executable và biết dependency mới nào bị cấm.

How to verify completion

  • Baseline test chạy được không cần network/credential.
  • Architecture check báo violation mới, nhưng allow-list rõ violation cũ.
  • ADR được link từ START_CONTRIBUTING.md.
Task Input Work Output Validation
R01-T01 Current architecture ADR Source map trong tài liệu này Viết dependency rules, composition rule, naming và exception process docs/architecture/ ADR + module ownership table Review bởi Cowork Team và FSG AI Core Team
R01-T02 Runtime test doubles ModelProvider, ToolSpec, agent event callback Tạo deterministic fake provider/tool executor/event collector Fixtures không import PySide6/network Unit test chạy dưới 1 giây và mô phỏng text + tool-call turn
R01-T03 Cowork runtime characterization run_cowork() hiện tại Test text-only, one tool call, failure, context compaction signal và cleanup contract Event sequence baseline Test không chạm user config/home và pass ổn định
R01-T04 Provider/config/store characterization Provider factory, AppConfig, representative repositories Test registry mapping, config round-trip, missing/corrupt file và current serialization shape Contract tests quanh public behavior hiện tại Existing + new tests pass trên fresh temp dir
R01-T05 Import boundary guard Current CodeGraph/import graph Thêm static import rule với allow-list debt; cấm code mới presentation → concrete infrastructure CI architecture check Một fixture violation mới làm check fail; existing debt được report
R01-T06 Dormant-code inventory Login/account/legacy MCP/security validators Xác minh entrypoint, dynamic registration, config flag và caller; gắn status active/dormant/unknown docs/architecture/dormant-code.md Mỗi item có evidence và owner; chưa xóa source

R02 — Configuration, Secrets & Persistence

Objective

Thay global untyped config/direct JSON writes bằng typed settings facade, atomic persistence primitives và secret references, trong khi giữ tương thích file hiện tại.

Current Problems

  • AppConfig là nested dict được mutate từ nhiều UI/core module.
  • Save config và phần lớn repository không atomic.
  • API keys/tokens được lưu plaintext trong config.
  • Không có schema version/migration/locking policy dùng chung.
  • Dynamic attributes như _data/_agent_security có thể được gán nhưng không tạo hiệu lực rõ ràng.

Scope

Config repository, typed view/facade, atomic JSON/JSONL helpers, secret store contract/adapters, migration policy.

Affected modules/files

config.py, state.py, Settings/Jira/connector dialogs, core/projects.py, core/history.py, core/tasks.py, core/skills.py, agent/Co4E/flow repositories, routing store làm reference.

What will be changed

  • Common atomic writer với fsync/temp/replace và recovery policy.
  • Typed settings sections vẫn đọc được schema JSON hiện tại.
  • Secret values chuyển dần sang OS credential store; config lưu reference.
  • Repository có explicit path/schema/error behavior.

What will NOT be changed

  • Không đổi tất cả repository trong một PR.
  • Không đổi defaults hoặc product settings ngoài migration cần thiết.
  • Không yêu cầu database.

Dependencies on other EPICs: R01.

Risk: Trung bình; config migration có thể ảnh hưởng startup. Phải support rollback và preserve unknown keys.

Expected outcome

Config/persistence có behavior nhất quán, credential không còn mặc định nằm trong plaintext JSON, caller không cần biết file layout.

How to verify completion

  • Round-trip giữ unknown key và current user settings.
  • Simulated interrupted write không phá file cũ.
  • Upgrade/downgrade fixture có documented behavior.
  • Secret không xuất hiện trong config, log hoặc test snapshot.
Task Input Work Output Validation
R02-T01 Atomic JSON primitive Atomic pattern trong routing AssessmentStore Extract AtomicJsonFile/equivalent với temp, flush, replace, corrupt-file strategy Infrastructure persistence helper Fault-injection tests trước/giữa replace
R02-T02 Migrate AppConfig storage only Current AppConfig.load/save Dùng atomic primitive nhưng giữ public dict API/schema Safer config writes, không đổi caller Golden config round-trip + startup smoke test
R02-T03 Typed settings facade DEFAULT_CONFIG sections Tạo typed views cho provider, routing, workspace, security, sandbox, UI Validated accessors + legacy adapter Invalid value fallback/error tests; unknown key preserved
R02-T04 Config repository/composition Root construction trong app.run() Inject config repository và bỏ path resolution khỏi business caller mới Explicit config bootstrap seam Temp-config integration test
R02-T05 SecretStore contract Provider/Jira/connector/MS365 secrets Define secret reference API; implement OS keyring adapter + explicit fallback policy SecretStore port và adapter Store/get/delete tests; no plaintext assertion
R02-T06 Migrate one credential vertical slice Một provider API key Migrate read/write UI + factory qua secret reference; compatibility import một lần Proven migration pattern Existing credential upgrade, new save, missing key tests
R02-T07 Repository schema policy Existing JSON stores Chốt envelope/version/backups/locking conventions; migrate một low-risk store Repository template/reference implementation Concurrent/read-corrupt/version tests

R03 — Model Providers & Routing

Objective

Tạo một catalog duy nhất cho provider/model capabilities và một application flow duy nhất cho routing, để thêm provider không phải sửa nhiều screen/config branch.

Current Problems

  • Registry mapping, labels, defaults và UI metadata phân tán.
  • OpenAI-compatible variants được phân biệt bằng config convention.
  • Routing confirmation và fallback logic bị lặp ở ba UI lớn.
  • Provider implementation tự gắn usage side effect.

Scope

Provider descriptor/registry/factory, provider config validation, routing request/result coordinator, provider contract tests.

Affected modules/files

providers/*, core/routing/*, provider sections trong config.py, state.py, ui/settings_dialog.py, ui/chat_panel.py, ui/co4e_tab.py, ui/folder_tab.py, ui/structure_graph_view.py.

What will be changed

  • ProviderDescriptor là source of truth cho id, label, implementation kind, required settings và capabilities.
  • Factory nhận validated provider config.
  • Routing use case trả typed decision/fallback/confirmation request.
  • UI chỉ render confirmation và lựa chọn, không tự tái hiện policy.

What will NOT be changed

  • Không đổi API endpoint/model semantics của provider trong phase đầu.
  • Không thêm provider mới chỉ để chứng minh architecture.
  • Không gộp routing heuristic nếu test hiện tại chưa bảo vệ.

Dependencies on other EPICs: R01; dùng R02 typed settings/secret contract khi sẵn sàng.

Risk: Trung bình do mọi agent path cần provider. Giữ ProviderFactory.create() compatibility adapter tới khi caller cuối migrate.

Expected outcome

Thêm provider chủ yếu bằng một descriptor + implementation + contract tests; routing giống nhau giữa Cowork, Co4E, Folder và scheduled work.

How to verify completion

  • Tất cả provider chạy chung contract suite.
  • Registry không có duplicate id/model alias.
  • Ba UI không còn private copy của routing policy.
  • Offline fake routing tests cover Off/Auto/Manual/fallback.
Task Input Work Output Validation
R03-T01 Provider contract suite providers/base.py, current implementations Định nghĩa expected chat/tool/stream/error/cancel behavior Parametrized provider contract tests Fake transport, không network
R03-T02 Provider descriptor registry Factory registry, labels, defaults Co-locate metadata/capabilities/config requirements; giữ factory façade Single provider catalog Registry completeness/duplicate tests
R03-T03 Validated provider construction Raw config dict Map typed settings + secret reference vào implementation config Explicit factory request/error types Missing/invalid secret/URL/model tests
R03-T04 Migrate Settings provider catalog Provider/model UI listing Render từ registry; không hard-code provider label/requirements Settings adapter using registry Headless presenter/model tests
R03-T05 Routing application service Existing RoutingService + three UI copies Tạo request/result, policy cho Off/Auto/Manual/fallback; confirmation qua port/callback One orchestration path Existing routing tests + UI-free coordinator tests
R03-T06 Migrate routing callers incrementally Cowork, Folder, Co4E, Graph/task callers Mỗi PR migrate một caller và xóa copy tương ứng No duplicated routing branches Per-screen smoke/characterization tests
R03-T07 Decouple usage from provider Provider-side usage_tracker.record Inject usage sink/context hoặc emit usage event Provider không phụ thuộc global usage module Provider contract captures exactly one usage event

R04 — Agent Runtime & Conversation Application Service

Objective

Biến một conversation turn thành use case có request/result/event rõ, không phụ thuộc mutable widget/AppContext, và giữ agent loop có thể chạy từ UI, task hoặc workflow.

Current Problems

  • Turn setup/finish nằm trong ChatPanel/CoworkTab.
  • Worker đọc routed provider/model/project policy từ mutable state.
  • Event là dict convention, reducer/state transition ngầm trong UI.
  • Chat/code loops có concepts lặp nhưng policy không hoàn toàn giống nhau.

Scope

Execution snapshot, typed events, conversation service, runtime dependency ports, migration Cowork/scheduled/help paths.

Affected modules/files

ui/chat_panel.py, ui/cowork_tab.py, core/chat_agent.py, core/code_agent.py, core/worker.py, core/context_budget.py, core/plan.py, core/task_executors.py, ui/help_agent_widget.py.

What will be changed

  • Snapshot provider/model/workspace/history/output/security/tool profile trước khi worker chạy.
  • Runtime nhận explicit dependencies.
  • Application service quản lý start/cancel/result/persist transaction.
  • Event schema typed nhưng có compatibility adapter cho dict UI.

What will NOT be changed

  • Không viết lại loop hoặc prompt trong một lần.
  • Không đổi UX streaming/queue/confirmation.
  • Không bắt chat và code dùng chung toàn bộ behavior.

Dependencies on other EPICs: R01, R03, R05, R06; R02 cho persistence/config adapters.

Risk: Cao; đây là critical path. Migrate một entrypoint mỗi PR và dùng golden event tests.

Expected outcome

Cowork widget chỉ tạo request, render event và gửi user decision; cùng service có thể được gọi từ scheduler/workflow mà không import UI.

How to verify completion

  • Concurrent turns giữ đúng provider/project/history snapshot.
  • Cancel/error/tool/permission event parity với baseline.
  • Runtime unit tests không import PySide6.
  • No direct provider/MCP/history construction trong migrated widget.
Task Input Work Output Validation
R04-T01 Execution request snapshot Current _start_turn/build_job inputs Define immutable request gồm messages, provider route, workspace session, output, policy/tool profile ConversationExecutionRequest Mutation-after-start concurrency tests
R04-T02 Typed agent events Dict events từ chat/code runtime Define event union/value types + legacy dict adapter Stable event contract Golden sequence tests và exhaustive reducer test
R04-T03 Runtime ports Provider, tool executor, policy, usage/audit dependencies Thay global/concrete lookup từng dependency một bằng injected runtime environment AgentRuntimeEnvironment nhỏ Fake-only runtime tests
R04-T04 Conversation application service Runtime + repositories + output lifecycle Orchestrate execute/cancel/persist/promote; return events/result UI-independent service Success/failure/cancel transaction tests
R04-T05 Migrate Cowork turn ChatPanel + CoworkTab current path Migrate một full turn; giữ compatibility event rendering Cowork uses service Manual smoke + headless service tests
R04-T06 Migrate scheduled/help callers task_executors, HelpAgent Mỗi caller tạo request/profile thay vì duplicate job setup Shared runtime entrypoint Task/help characterization tests
R04-T07 Evaluate chat/code kernel extraction Characterized loops Chỉ extract truly identical loop mechanics; giữ prompt/policy strategy riêng Minimal shared kernel hoặc ADR “do not merge” Contract parity; line movement không phải success metric

R05 — Tool, MCP & Connector Policy

Objective

Đảm bảo mọi built-in, MCP, REST và MS365 action đi qua cùng capability classification, approval/security decision, audit và executor lifecycle.

Current Problems

  • execute_tool() và connector executors dùng giant dispatch.
  • Extra MCP/connector tool có thể bypass built-in command/write gate.
  • Generic REST connector cho phép method nguy hiểm mà không có capability model.
  • MCP client construction/cache/shutdown nằm trong AppContext.
  • Tool metadata không nói rõ read/write/execute/network/destructive.

Scope

Tool descriptors/registry, capability model, policy gateway, MCP lifecycle manager, connector descriptors and tests.

Affected modules/files

core/tools.py, core/chat_agent.py, core/code_agent.py, core/mcp_client.py, core/ext_connectors.py, core/ms365_tools.py, core/ms365_local.py, mcp_servers/ms365_server.py, state.py, Monitoring tool/MCP UI.

What will be changed

  • Tool schema, handler, source và effects/capabilities được đăng ký cùng nhau.
  • Một gateway quyết định allow/confirm/deny trước mọi executor.
  • MCP/connectors expose descriptors, không chỉ raw schema/callback.
  • Lifecycle tách khỏi service locator.

What will NOT be changed

  • Không thay protocol MCP.
  • Không redesign connector UX trước khi policy/API ổn định.
  • Không mặc định deny toàn bộ existing tools khi chưa có migration mapping.

Dependencies on other EPICs: R01, R02; phối hợp R09 về policy/audit semantics.

Risk: Cao vì sai classification có thể block workflow hoặc cho phép action nguy hiểm. Unknown capability phải có explicit migration policy.

Expected outcome

Tool mới phải khai báo effects và tự động nhận cùng permission/audit path; MCP/REST không còn là ngoại lệ.

How to verify completion

  • Contract test fail nếu tool thiếu capability.
  • Built-in/MCP/REST/MS365 read và write action có expected decision matrix.
  • Unknown/destructive action không execute silently.
  • MCP clients close deterministically.
Task Input Work Output Validation
R05-T01 Tool/action inventory Built-in, MCP, REST, MS365 schemas Lập matrix filesystem/network/process/read/write/delete/install Reviewed capability catalog Security/product sign-off
R05-T02 ToolDescriptor + registry ToolSpec và execute_tool branches Wrap từng handler với descriptor; compatibility dispatcher giữ API cũ Registry-based lookup Existing tool behavior + duplicate/missing handler tests
R05-T03 Unified policy gateway PermissionGate, command classifier, write sets Define decision input/output và gọi trước executor bất kể source One enforcement point Table-driven allow/confirm/deny tests
R05-T04 External tool adapter extra_tools callback path Convert MCP/connector schemas thành descriptors và route qua gateway No bypass branch in agent loop Fake destructive MCP tool cannot execute without decision
R05-T05 MCP lifecycle service AppContext.build_mcp_tools cache/start/close Extract source discovery, client ownership, health and shutdown McpToolSourceManager Start/failure/restart/close tests with fake process
R05-T06 REST connector hardening Generic method/path config Require action allow-list, capability, timeout, response limit và secret reference Descriptor-driven REST tools DELETE/write/host/timeout policy tests
R05-T07 MS365 migration Local/MCP MS365 executors Map actions to shared capabilities/policy/audit Same behavior across local/MCP modes Contract tests for representative read/write actions

R06 — Workspace, Filesystem & History Isolation

Objective

Biến project/workspace context thành immutable value truyền explicit theo use case, đồng thời tập trung path resolution, history và output lifecycle.

Current Problems

  • active_project_id và _project_history_dir là mutable global state.
  • Completion callback có thể save vào project khác sau context switch.
  • Filesystem access/path rules rải ở UI, runtime và repositories.
  • Repository trả mutable dict, không có typed identity/version.

Scope

Workspace session, project/history repositories, output/scratch manager, filesystem port và migration Workspace/Cowork callers.

Affected modules/files

state.py, config.py, core/projects.py, core/history.py, ui/workspace_tab.py, ui/chat_panel.py, ui/cowork_tab.py, ui/folder_tab.py, output/doc extraction helpers.

What will be changed

  • WorkspaceSession chứa project id/root/history/output/policy snapshot.
  • Repository nhận explicit project/session/path.
  • UI current selection chỉ là presentation state; background request giữ snapshot riêng.
  • Filesystem mutation dùng service với path containment/atomic save.

What will NOT be changed

  • Không đổi workspace layout trên disk trong phase đầu.
  • Không rewrite file editor.
  • Không đồng bộ cloud.

Dependencies on other EPICs: R01, R02; cung cấp input cho R04/R07/R08.

Risk: Trung bình-cao do path/data migration. Dùng fixtures với nhiều project và không chạm user home.

Expected outcome

Turn/task/workflow luôn đọc/ghi đúng project dù UI đổi selection; path/security rule có một nơi.

How to verify completion

  • Multi-project concurrency regression tests.
  • History/output path không resolve từ global config sau start.
  • Project switch không đổi running request.
  • Path traversal/atomic save tests.
Task Input Work Output Validation
R06-T01 WorkspaceSession value Project dict + config-derived paths/policies Define immutable typed snapshot và factory Explicit session object Equality/validation/snapshot tests
R06-T02 Explicit history repository core/history.py, dynamic history dir Repository methods nhận project/session hoặc bound repository No global history path mutation A/B project save/load regression
R06-T03 Project repository boundary core/projects.py Separate DTO/validation/storage; preserve disk schema ProjectRepository adapter CRUD/missing/corrupt/unknown-key tests
R06-T04 Output/scratch lifecycle Per-turn output/promotion/cleanup code Centralize allocate/promote/cleanup by execution id ExecutionWorkspace service Failure/cancel/duplicate-name tests
R06-T05 WorkspaceTab migration _load_current and child propagation Selection creates/binds session; remove config path mutation UI emits workspace session change Switch while fake turn runs
R06-T06 Cowork/history migration Turn start/finish path Bind repository/output to snapshot before worker start Correct project isolation Concurrent two-project integration test
R06-T07 Filesystem service for Folder Direct Path read/write/rename/delete Introduce bounded FS service and migrate one operation group per PR UI no longer resolves raw project paths Containment, encoding, atomic-write tests

R07 — Scheduling & Workflow Runtime

Objective

Tách task persistence, schedule calculation, Qt timing, task execution và workflow running thành các boundary có thể test độc lập.

Current Problems

  • core/tasks.py trộn repository và scheduling math.
  • TaskScheduler phụ thuộc QTimer/current clock/concrete repository.
  • core/task_executors.py là giant type dispatch + runtime/persistence/artifact orchestration.
  • Co4E và Flow là hai workflow concept không có shared execution contract.
  • Co4E UI sở hữu nhiều run lifecycle.

Scope

Task domain/repository, schedule calculator/clock, task execution service, workflow definitions/runners, Qt scheduler adapter.

Affected modules/files

core/tasks.py, core/task_scheduler.py, core/task_executors.py, core/co4e.py, core/co4e_runner.py, core/co4e_run_manager.py, core/flows.py, ui/schedule_task_tab.py, ui/task_editor_dialog.py, ui/co4e_tab.py.

What will be changed

  • Pure schedule calculation và injectable clock.
  • Typed task execution request/result.
  • Executor registry thay giant task type branch.
  • Workflow runners emit typed events và dùng application runtime service.
  • Document rõ khác biệt Flow/Co4E trước khi reuse abstraction.

What will NOT be changed

  • Không merge Flow và Co4E model một cách cưỡng ép.
  • Không thay schedule semantics/UX.
  • Không thay format task/workflow đồng thời với runtime migration.

Dependencies on other EPICs: R01, R04, R06; R02 repositories; R05 tool policy.

Risk: Cao vì background automation và artifact persistence. Cần fake clock và idempotency tests.

Expected outcome

Scheduler có thể test không Qt/wall clock; task type mới đăng ký qua executor; workflow run không cần UI class.

How to verify completion

  • Deterministic schedule tests quanh timezone/restart/missed run.
  • Duplicate tick không chạy cùng task hai lần.
  • Task result/artifact/history behavior parity.
  • Co4E run headless với fake provider.
Task Input Work Output Validation
R07-T01 Task model/repository split core/tasks.py Extract typed task + repository adapter, giữ serialization Domain model + repo Golden current task files
R07-T02 Schedule calculator + Clock Due-time logic Extract pure function/service, inject timezone-aware clock Deterministic scheduling core Boundary/timezone/restart test matrix
R07-T03 Task executor registry Branches trong task_executors Mỗi task kind có descriptor/executor; shared artifact/result wrapper Extensible registry Unknown/each kind/duplicate id tests
R07-T04 TaskExecutionService Scheduler → worker → executor flow Orchestrate claim/run/status/result/idempotency UI-free use case Crash/failure/retry/double-tick tests
R07-T05 Qt scheduler adapter QTimer scheduler Adapter chỉ poll service và emit presentation event Thin platform timer Fake clock + Qt smoke test
R07-T06 Workflow taxonomy/contract Flow và Co4E models Document semantics; define smallest common run request/event/result nếu thực sự chung Explicit workflow ports/ADR Both runners satisfy agreed contract or exceptions documented
R07-T07 Co4E runner migration Runner/run manager callbacks Dùng conversation service, typed event, execution snapshot Headless runner Multi-node/failure/cancel/usage tests
R07-T08 Flow runner migration core/flows.py scheduled path Implement shared task/workflow execution contract Consistent result/artifact handling Flow fixtures + scheduled integration

R08 — UI/Application Separation

Objective

Thu nhỏ PySide6 screen thành view/presenter/controller, migrate theo từng screen sau khi application services tương ứng sẵn sàng.

Current Problems

  • God widgets chứa orchestration/persistence/provider/filesystem.
  • UI state và domain state không phân biệt.
  • Modal confirmation, worker wiring và usage/provider helpers bị lặp.
  • Một số network test chạy sync trên UI thread.

Scope

Presentation state, controller/presenter, Qt worker adapters, từng screen migration, cuối cùng MainWindow composition.

Affected modules/files

Toàn bộ ui/, app.py, core/worker.py; application services từ R03–R07/R09.

What will be changed

  • Screen nhận narrow use-case interfaces.
  • View state/event reducer có unit test.
  • Blocking work luôn qua Qt execution adapter.
  • Shared visual widgets chỉ chứa presentation concern.

What will NOT be changed

  • Không redesign visual/UX toàn diện.
  • Không migrate nhiều God screen trong cùng PR.
  • Không tạo một “BaseViewModel” khổng lồ.

Dependencies on other EPICs: Progressive; mỗi screen chỉ bắt đầu khi service của nó sẵn sàng. MainWindow làm cuối.

Risk: Trung bình-cao do signal/lifecycle regression. Giữ screenshot/manual smoke checklist và headless presenter tests.

Expected outcome

Screen có responsibility rõ, không gọi concrete provider/MCP/repository/filesystem; contributor UI không cần hiểu agent loop.

How to verify completion

  • Import rule sạch cho migrated screen.
  • Presenter/controller test không tạo real window/network/files.
  • UI thread responsiveness smoke tests.
  • Signal connection/lifecycle không leak sau close/switch.
Task Input Work Output Validation
R08-T01 Presentation conventions Current signal/worker/event patterns Define view-state, command, effect và Qt adapter conventions; sample một small dialog UI contribution pattern ADR + sample tests, không base framework
R08-T02 Settings screen R02/R03/R05 settings services Migrate provider/config/connector save/test; async connection test Thin Settings/connector dialogs Save/cancel/test-connection presenter tests
R08-T03 Workspace/project/history shell R06 services Migrate project selection/history binding Session-driven WorkspaceTab A/B switch, empty/deleted project tests
R08-T04 Cowork/Chat R03–R06/R09 services Move turn lifecycle/event state/persistence khỏi widget Chat view + presenter/controller Baseline conversation/manual streaming checklist
R08-T05 Schedule/Task editor R07 services Move CRUD/validation/run/drafting orchestration Task list/editor presentation only Fake clock/repo + dialog validation tests
R08-T06 Co4E R04/R07 services Split editor, run monitor và chat controllers Smaller independent components Headless workflow and UI signal tests
R08-T07 Folder R03/R06 services Migrate FS and AI edit/image/terminal actions by operation group Folder UI renders file/diff/result Temp workspace + cancel/failure tests
R08-T08 GraphRAG Graph index/query application service Move scan/query/provider prompt/use tracking Thin graph view Fake graph/provider tests
R08-T09 Dashboard/Monitoring R09 query services Migrate telemetry/audit/agent/tool queries và suggestions Read models + views Empty/corrupt/large dataset tests
R08-T10 Help/admin/skills dialogs Shared conversation/CRUD services Migrate active small surfaces; mark dormant ones Consistent small controllers Reachability and CRUD tests
R08-T11 MainWindow/composition All migrated screens Move construction/lifecycle wiring to bootstrap; shell owns nav/tray only Thin MainWindow + composition root Startup/shutdown/lazy-tab/tray smoke tests

R09 — Security Runtime, Sandbox & Observability

Objective

Phân biệt hard deterministic enforcement với advisory AI checks, thống nhất sandbox/audit/usage semantics và làm Monitoring phản ánh đúng capability thực tế.

Current Problems

  • Security logic phân tán giữa core/ và security/.
  • AI security fail-open nhưng dễ bị hiểu như hard boundary.
  • Sandbox config có field/backend không khớp đường chạy thực tế.
  • Network blocking của direct backend không phải OS isolation mạnh.
  • Hai audit format/store và circular imports security/pricing.
  • Usage/audit dựa vào global/thread-local context.

Scope

Policy vocabulary/decision service, sandbox capability matrix, audit/usage event schema/sinks, monitoring queries, dead security cleanup.

Affected modules/files

core/agent_security*.py, core/security_rules.py, security/*, core/sandbox_manager.py, platform sandbox modules, core/audit_log.py, core/usage_tracker.py, core/model_pricing.py, telemetry and Monitoring UI.

What will be changed

  • Define enforced/advisory/unknown outcomes.
  • Deterministic checks fail according to explicit policy; advisory model failure được audit.
  • Sandbox reports actual backend/capabilities, không chỉ requested settings.
  • Canonical audit/usage events và query services.
  • Break module cycles.

What will NOT be changed

  • Không tuyên bố security guarantee chưa được platform test.
  • Không thay sandbox backend trên mọi OS trong một PR.
  • Không xóa legacy audit data; cần reader/migration.

Dependencies on other EPICs: R01, R02, R05; cung cấp query services cho R08.

Risk: Cao. Security behavior change cần threat-model review và negative tests.

Expected outcome

Mọi action có explainable decision/audit; Monitoring hiển thị requested và effective protection; telemetry có schema nhất quán.

How to verify completion

  • Threat-model checklist và policy decision matrix pass.
  • Platform-specific sandbox integration tests.
  • Legacy/current audit records đọc được.
  • No circular dependency giữa security alert/policy và pricing/usage.
Task Input Work Output Validation
R09-T01 Security model/ADR Current prompt/attachment/action/command paths Chốt asset, trust boundary, enforced vs advisory, fail behavior Threat model + decision vocabulary Security review
R09-T02 Security decision service Classifier, rules, AI evaluator Return typed decision/reasons/events; UI alert là adapter One policy API used by R05 gateway Table-driven negative/unknown/provider-down tests
R09-T03 Sandbox capability matrix Direct/integrity/AppContainer/VM code Detect/report effective fs/network/process isolation per platform SandboxCapabilities + honest config/UI mapping Platform smoke tests and unsupported-path tests
R09-T04 Sandbox config cleanup Unused/misleading settings Wire, deprecate hoặc remove từng field với migration; document fallback No inert security option Config-to-runtime behavior tests
R09-T05 Canonical audit event/store Two audit loggers/formats Define event schema, append sink, legacy readers, query API One audit pipeline Legacy fixture + concurrency/rotation tests
R09-T06 Usage/pricing separation Circular modules/global context Pure pricing module + explicit usage event sink/context Cycle removed, deterministic cost calculation Golden pricing/aggregation tests
R09-T07 Monitoring query services UI direct file/global queries Build bounded paginated/filterable read models UI-independent monitoring APIs Empty/corrupt/large log tests
R09-T08 Legacy security cleanup Dormant validators/loggers Deprecate/migrate/remove only after active path coverage Single authoritative namespace CodeGraph/import check + full tests

R10 — Testing, Packaging & Contributor Experience

Objective

Đưa repository tới trạng thái contributor có thể setup, tìm đúng boundary, chạy test phù hợp và mở PR nhỏ với CI feedback đáng tin.

Current Problems

  • Chưa có complete runtime dependency manifest/lock strategy.
  • CI chủ yếu syntax + pytest; không có architecture/lint/type/coverage budget.
  • Test thiếu runtime/tool/security/persistence/UI presenter/scheduler.
  • Không có module ownership/extension recipes.
  • i18n.py và một số central files dễ conflict.

Scope

Test taxonomy/fixtures, packaging, CI quality gates incremental, architecture and extension docs, cleanup workflow.

Affected modules/files

tests/, dependency/packaging files, CI workflows, README.md, START_CONTRIBUTING.md, CONTRIBUTING.md, new architecture docs, eventually i18n catalogs.

What will be changed

  • Add deterministic unit/contract/integration/headless-UI layers.
  • Declare runtime/dev/test dependencies và supported Python/OS.
  • CI checks theo debt budget, không bật strict toàn repo trong một lần.
  • Contributor recipes cho provider/tool/MCP/screen/agent behavior.

What will NOT be changed

  • Không theo đuổi coverage percentage như mục tiêu duy nhất.
  • Không format/rewrite toàn repo cùng architecture PR.
  • Không remove dormant code khi chưa có R01 evidence.

Dependencies on other EPICs: Bắt đầu cùng R01 và chạy xuyên suốt; final cleanup sau R02–R09.

Risk: Thấp-trung bình; strict gate bật quá sớm có thể làm chậm migration. Dùng baseline/debt ratchet.

Expected outcome

Fresh clone setup reproducible; contributor biết sửa đâu và có test suite cục bộ nhanh; CI ngăn violation mới.

How to verify completion

  • Setup từ fresh environment theo docs.
  • PR template map change → required tests.
  • CI time hợp lý và không cần external credential.
  • Architecture recipes được một contributor mới thực nghiệm.
Task Input Work Output Validation
R10-T01 Test taxonomy/fixtures R01 fixtures + subsystem needs Chia unit/contract/integration/headless-ui/platform; temp config/home helpers Test guide + reusable fixtures No test writes real user data
R10-T02 Agent/tool/security suites R03–R05/R09 contracts Thêm fake-provider event, tool capability, permission và negative security tests Critical-path safety net Deterministic offline CI
R10-T03 Persistence/scheduler suites R02/R06/R07 Fault injection, multi-project, fake-clock/idempotency tests Data/background safety net Parallel/repeat runs stable
R10-T04 Headless presentation tests R08 presenters/controllers Test view state/commands không cần display; Qt smoke subset riêng Fast UI logic suite CI headless pass
R10-T05 Packaging/dependencies README install list/current imports Tạo pyproject.toml hoặc equivalent runtime/dev extras + lock policy Reproducible install Fresh venv install + import/startup smoke
R10-T06 CI quality ratchet Existing workflows Add lint/type/architecture/coverage for changed code trước, expand dần Actionable CI Intentional violation fixture fails correct job
R10-T07 Contributor architecture recipes Current contribution docs “add provider/tool/MCP/screen/change agent behavior” step-by-step + ownership Contributor guide Dry run bởi developer không tham gia refactor
R10-T08 Translation/catalog split i18n.py sau UI migration Split catalogs by feature while preserving tr() API Lower-conflict localization files Key uniqueness/missing-language tests
R10-T09 Dormant-code removal PRs R01 inventory + replacements covered Mỗi PR xóa một isolated dormant feature/path Reduced maintenance surface Full tests, package/import smoke, release note

15. Dependency Between EPICs

flowchart TD
    R01["R01 Foundation"] --> R02["R02 Config / Persistence"]
    R01 --> R03["R03 Providers / Routing"]
    R01 --> R05["R05 Tools / MCP / Connectors"]
    R01 --> R06["R06 Workspace / History"]

    R02 --> R03
    R02 --> R05
    R02 --> R06
    R02 --> R09["R09 Security / Observability"]

    R03 --> R04["R04 Agent / Conversation"]
    R05 --> R04
    R06 --> R04
    R05 --> R09

    R04 --> R07["R07 Scheduling / Workflow"]
    R06 --> R07
    R05 --> R07

    R03 --> R08["R08 UI Separation"]
    R04 --> R08
    R05 --> R08
    R06 --> R08
    R07 --> R08
    R09 --> R08

    R01 --> R10["R10 Testing / Contributor"]
    R02 --> R10
    R03 --> R10
    R04 --> R10
    R05 --> R10
    R06 --> R10
    R07 --> R10
    R08 --> R10
    R09 --> R10

Dependency không có nghĩa toàn EPIC phải đóng mới được bắt đầu. Dùng milestone contract:

Consumer Milestone prerequisite
R03 R02 typed provider settings + secret reference API
R04 Provider registry/routing request; ToolPolicy API; WorkspaceSession/history repository
R07 Conversation service headless; WorkspaceSession; tool policy
R08 Settings R02 + R03 + connector config API
R08 Cowork R03 + R04 + R05 + R06 policy/snapshot services
R08 Co4E/Schedule R04 + R07
R08 Monitoring R09 query APIs

Phase 0 — Baseline and governance

  1. R01-T01…T05.
  2. Bổ sung R10 test guide/fixtures tối thiểu.
  3. Freeze rule: code mới không thêm direct UI → provider/repository import ngoài allow-list.

Phase 1 — Stable infrastructure seams

  1. R02 atomic config/typed settings/secret API.
  2. R03 provider descriptor/contract.
  3. R06 WorkspaceSession/history repository.

Ba stream có thể chạy song song sau khi typed config conventions được chốt, nhưng ownership file phải tách:

  • R02 owner config.py/persistence helpers.
  • R03 owner providers/core/routing.
  • R06 owner project/history/workspace modules.

Phase 2 — Actions and enforcement

  1. R05 tool descriptors/capability inventory/gateway.
  2. R09 security decision vocabulary/audit schema.
  3. Migrate external MCP/REST/MS365 action qua gateway.

Phase 3 — Runtime/application service

  1. R04 execution snapshot và typed events.
  2. Conversation application service.
  3. Migrate Cowork path đầu tiên.
  4. Sau parity mới migrate scheduled/help caller.

Phase 4 — Background and workflow

  1. R07 task repository/schedule calculator.
  2. Task execution service + Qt adapter.
  3. Co4E rồi Flow runner migration.

Phase 5 — UI screen migration

Theo thứ tự ở mục 17. Mỗi screen là một chuỗi PR nhỏ; không mở đồng thời PR lớn trên ChatPanel, Co4ETab và MainWindow.

Phase 6 — Consolidation

  1. Move module mechanical khi caller cũ đã hết.
  2. Xóa compatibility adapter/debt allow-list.
  3. Consolidate security/audit legacy.
  4. Split i18n catalogs.
  5. Remove dormant code đã xác nhận.
  6. Nâng CI ratchet và hoàn thiện contributor docs.

17. UI Refactor Order

Architecture foundation phải đi trước. Thứ tự UI sau đây tối ưu risk/dependency, không phải độ ưu tiên sản phẩm.

Order Screen UI responsibility nên giữ Business logic cần extract Shared dependencies Entry criteria
1 Settings + connector dialogs Form state, validation message, confirm/cancel Config/secret persistence, provider catalog, connection test R02 typed settings/secret, R03 registry, R05 connector service Services có contract tests; connection test async
2 Workspace + Project Settings + History Project selection, tab state, render history Project CRUD, session binding, path/history resolution R06 WorkspaceSession/repositories Không còn dynamic history dir
3 Cowork / Chat Compose/render message, tool/permission prompt, cancel Routing, execution request, runtime, persistence, output/usage R03–R06, R09 audit Golden event parity và fake-provider service
4 Schedule + Task Editor List/form/render status, run/cancel commands Task validation/CRUD, due calculation, execution, AI drafting R07, R03/R04 Fake clock/task service
5 Co4E Canvas interaction, node editor, run visualization Workflow CRUD/run, conversation nodes, usage/result aggregation R04/R07 Headless Co4E run passes
6 Folder Tree/editor/diff/terminal presentation FS operations, routing/provider prompts, image/terminal execution R03/R05/R06 Bounded filesystem + tool policy
7 GraphRAG Graph visualization, question input, streamed answer Scan/index/query, provider prompt, usage Graph application service, R03/R06 Temp-repo graph tests
8 Dashboard + Monitoring Render read models, filters, refresh command Usage/audit/pricing/security/tool queries, AI suggestions R09 query services, R04 suggestion use case Canonical audit/usage schema
9 Help/skills/agents/admin surfaces Presentation CRUD/chat Repository/provider/runtime calls R02/R04 and small CRUD services Active/dormant status known
10 MainWindow Navigation, tray, window lifecycle Service construction, scheduler ownership, feature coordination All relevant application services Screens accept narrow dependencies

Refactor một screen theo sequence:

Characterize screen behavior
  → introduce presenter/controller beside current widget
  → migrate one concern
  → run headless + manual smoke tests
  → remove direct dependency
  → repeat
  → mechanical file move only after import boundary is clean

18. Risks

Risk Probability / Impact Mitigation
Behavior drift trong chat streaming/tool loop Medium / High Golden event tests, fake provider, one caller per PR, manual cancel/tool/permission checklist
User config/history corrupt hoặc migration mất key Medium / High Golden real-shape fixtures, preserve unknown keys, atomic replace, backup and rollback
Cross-project data leak trong migration Existing High / High Immutable session, explicit repo binding, two-project concurrency regression
Security regression khi unify tools Medium / Critical Capability inventory, default treatment for unknown, negative tests, security review
Sandbox overclaim trên platform khác Existing Medium / High Effective capability detection, platform CI/smoke, honest UI text
MCP/connector compatibility break Medium / High Descriptor adapter around current schemas, fake server contract, migrate per connector
Scheduler duplicate/missed run Medium / High Fake clock, idempotency/claim model, restart/timezone test matrix
Merge conflict ở God files/config/i18n High / Medium File ownership window, short-lived PRs, service-first extraction, i18n split cuối phase
Abstraction over-engineering Medium / Medium Contract chỉ ở multi-implementation/cross-layer seam; ADR yêu cầu real caller; no DI framework
Compatibility adapters sống vĩnh viễn High / Medium Mỗi adapter có owner, removal condition và debt issue/CI allow-list
Test suite xanh nhưng không phản ánh GUI lifecycle Medium / High Presenter tests + targeted Qt smoke + manual release checklist
Dead code bị xóa nhầm dynamic path Low / High R01 reachability inventory, config/plugin check, removal PR riêng
Secrets migration khóa user khỏi provider Medium / High One provider slice, import-once, explicit fallback/recovery UI

19. Migration Strategy

19.1 Strangler pattern cho từng boundary

Old concrete path
  ↓
Introduce contract + adapter wrapping old implementation
  ↓
Characterize old behavior
  ↓
Migrate one caller
  ↓
Verify parity and production smoke
  ↓
Migrate remaining callers
  ↓
Block new imports to old path
  ↓
Remove adapter/old path in dedicated PR

19.2 Rules cho incremental migration

  1. Một PR chỉ nên thay một contract hoặc một caller; mechanical move không trộn behavior change.
  2. Public compatibility façade giữ tên cũ trong migration (ProviderFactory.create, repository function, event dict adapter).
  3. Mỗi façade có deprecation owner và removal condition ghi trong EPIC.
  4. Không đọc current project/provider/config từ worker sau khi request đã start.
  5. Persistence migration phải đọc được old shape trước khi ghi new shape; backup trước irreversible migration.
  6. Security gateway được đưa vào “observe/audit mode” để inventory unknown tool trước khi enforce, nhưng destructive unknown không được silently execute.
  7. Screen migration giữ current UX; visual redesign là roadmap khác.
  8. Feature flag chỉ dùng khi cần rollback production path; không dùng để duy trì hai architecture vô thời hạn.
  9. CodeGraph/import checks được chạy sau watcher/index ổn định và CI static rule là source of enforcement.

19.3 Compatibility windows

Boundary Temporary compatibility Removal condition
Config Typed facade delegates current nested dict All direct mutations migrated; unknown-key round-trip tested
Provider Old factory calls new registry All provider construction uses typed request
Agent events Typed event converts to current dict All active presenters consume typed events
Tools execute_tool() delegates registry All runtime/external paths call gateway/registry
History/project Module functions delegate repository All background work binds WorkspaceSession
Audit Reader accepts legacy + canonical Retention window passed or migration complete
UI worker Existing AgentWorker wraps application service Screens no longer construct provider/repo inside job

20. Contributor Experience Improvements

20.1 Hiện trạng từ góc nhìn developer mới

Họ có biết bắt đầu từ đâu không?

Chỉ một phần. README.md và START_CONTRIBUTING.md giúp chạy ứng dụng và mô tả contribution flow, nhưng chưa có map “feature → application/runtime/infrastructure owner”. core/ quá rộng và UI chứa cả business logic.

Muốn thêm model provider thì sửa đâu?

Hiện phải hiểu và có thể sửa:

  • provider base/implementation/factory;
  • config defaults/provider labels/settings;
  • routing metadata/probing assumptions;
  • UI model/provider listings;
  • usage/error behavior.

Target: một ProviderDescriptor, implementation và contract tests; Settings/routing tự đọc registry.

Muốn thêm MCP/tool/connector thì sửa đâu?

Hiện phải hiểu AppContext.build_mcp_tools, MCP client, tool schema/executor, config, Monitoring và security exceptions. Target: đăng ký một ToolSource/connector descriptor với capability metadata, secret references và shared contract tests.

Muốn thêm màn hình thì sửa đâu?

Hiện thêm widget rồi wiring/lazy lifecycle vào MainWindow/Workspace/Monitoring tùy loại, đồng thời thường phải tự gọi core. Target: screen package có view + presenter/controller, use-case dependency và một route descriptor được composition root đăng ký.

Muốn sửa agent behavior thì sửa đâu?

Hiện phải xác định behavior ở ChatPanel/CoworkTab, chat_agent, code_agent, Co4E runner hay task executor; cùng một behavior có thể khác nhau theo entrypoint. Target: agent runtime policy/profile và ConversationApplicationService là điểm bắt đầu; entrypoint chỉ chọn profile.

Có cần hiểu toàn repository mới contribute được không?

Với thay đổi provider/tool/chat hiện tại, gần như có. Sau refactor, contributor chỉ cần hiểu contract của capability, adapter đang sửa và contract tests.

20.2 Deliverables cho contributor experience

  • docs/architecture/overview.md: startup, dependency direction, subsystem owners.
  • docs/architecture/decisions/: ADR ngắn cho layer names, tool capability, workspace snapshot, Flow vs Co4E.
  • docs/contributing/add-provider.md.
  • docs/contributing/add-tool-or-mcp.md.
  • docs/contributing/add-screen.md.
  • docs/contributing/change-agent-behavior.md.
  • docs/contributing/persistence-migrations.md.
  • docs/testing.md: fast/local/platform/manual suites.
  • CODEOWNERS hoặc ownership matrix cho provider/runtime/security/UI screens.
  • PR template yêu cầu: affected boundary, compatibility path, tests, migration/removal condition.
  • Issue templates theo EPIC → module → class/function task.
  • Development dependency manifest và one-command setup/test.
  • Generated or CI-checked dependency report; không bắt contributor chạy CodeGraph để làm task đơn giản.
  • Translation catalogs theo feature để giảm conflict sau khi UI migration ổn định.

20.3 Definition of Ready cho contributor task

Một task chỉ sẵn sàng assign khi có:

  • current file/symbol và behavior cần preserve;
  • boundary/contract đích;
  • input/output cụ thể;
  • file ownership và out-of-scope;
  • test fixture không cần credential;
  • dependency EPIC đã đạt milestone;
  • migration/rollback note nếu có dữ liệu hoặc security behavior.

20.4 Definition of Done

  • Caller trong scope dùng boundary mới.
  • Contract/unit/integration test theo risk pass.
  • Không thêm import violation.
  • Compatibility/debt entry được cập nhật.
  • Docs/extension recipe cập nhật nếu public contributor path đổi.
  • Manual smoke checklist hoàn tất cho UI/runtime path.

Ba PR đầu nên tạo safety và seam, chưa đụng UI God class lớn.

PR 1 — Characterization Safety Net for Runtime and Boundaries

Scope

  • Thêm fake provider, fake tool executor, event collector và temp config/home fixtures.
  • Test run_cowork() cho text-only, one-tool-call, failure/cancel contract cơ bản.
  • Test provider factory mapping và AppConfig/một representative repository round-trip.
  • Thêm architecture ADR và import-debt report ở chế độ không cho violation mới.

Files dự kiến

tests/, docs/architecture/; production source chỉ có thể cần test seam tối thiểu, không đổi behavior.

Risk: Thấp.

Architecture value: Rất cao; tạo safety net và ngôn ngữ chung cho mọi PR sau.

Validation

  • Toàn bộ test offline, không đọc/ghi ~/.cowork_local.
  • Current 81 tests + new suite pass.
  • Intentional new import violation bị check bắt.

PR 2 — Atomic AppConfig Persistence

Scope

  • Extract atomic JSON write primitive từ pattern đã được routing store dùng.
  • Chỉ migrate AppConfig.load/save; giữ nguyên nested schema/public access.
  • Preserve unknown keys và thêm corrupt/interrupted-write tests.
  • Chưa migrate secrets hoặc các repository khác.

Files dự kiến

Một infrastructure persistence helper mới, config.py, focused tests.

Risk: Thấp nếu golden fixtures và rollback được giữ.

Architecture value: Cao; thiết lập persistence primitive dùng cho các store sau và giảm startup corruption risk.

Validation

  • Golden config round-trip byte/semantic compatible theo policy đã chọn.
  • Fault trước replace giữ file cũ hợp lệ.
  • Startup smoke với config hiện tại, missing file và corrupt file.

PR 3 — Provider Descriptor Registry behind Existing Factory

Scope

  • Introduce ProviderDescriptor registry làm source of truth cho id, label, implementation kind và required config.
  • ProviderFactory.create() vẫn là compatibility façade.
  • Migrate chỉ provider listing/labels trong Settings hoặc một read-only consumer.
  • Thêm registry completeness/duplicate/contract tests.
  • Không thay provider network behavior hoặc routing heuristic.

Files dự kiến

providers/, focused provider catalog consumer, tests.

Risk: Thấp.

Architecture value: Cao; tạo extension point đầu tiên và giảm hard-code trước khi migrate routing/Cowork.

Validation

  • Existing provider ids tạo đúng implementation như trước.
  • Duplicate/missing descriptor fail ở test.
  • Settings hiển thị cùng provider/model options hiện tại.

Sau ba PR này, PR tiếp theo nên là WorkspaceSession + explicit history repository regression cho cross-project isolation, rồi mới mở migration ConversationApplicationService/Cowork.