# Orchestrator: bàn điều khiển giao việc

> Chat with the coordinator next to online devices and running tasks; a persistent task backend with leases, a side-effect ledger, a git broker and approvals.

# Orchestrator: bàn điều khiển giao việc / Orchestrator: the dispatch console

## Tiếng Việt

**Mục đích.** Một khung duy nhất để nói chuyện với **agent điều phối** (một agent-role đóng vai quản lý) và đồng thời thấy **thiết bị nào online** và **task nào đang chạy**. Trước đó phải mở ai-chat, tự nhớ chọn phiên đã gán role quản lý, rồi mở riêng Task Manager và Device Manager để theo dõi.

**Ghép từ các plugin có sẵn, không nhân bản code.** Widget gồm ba vùng dock kéo thả được: danh sách thiết bị (từ `device-manager`), danh sách task (từ `task-manager`) và khung chat (UI chat tái dùng của `ai-chat`, ghim vào agent điều phối đã chọn). Các vùng được "nhận nuôi" vào bố cục dock chứ không dựng lại, vì dựng lại khung chat đang sống nghĩa là mất phiên.

**Backend lưu task bền vững** (SQLite trong main process), xây dần theo từng lát cắt:

1. **Máy trạng thái + kho task**: task có vòng đời rõ ràng, mọi chuyển trạng thái ghi thành sự kiện kèm lý do; truy vết một việc bằng một lần đọc.
2. **Thuê tài nguyên (lease)**: môi trường nào đang bị task nào chiếm; khởi động lại thì **đối chiếu** (reconcile) với thực tế thay vì tin bảng; tắt plugin thì xả (drain) có thời hạn; luôn có đường bỏ việc.
3. **Sổ cái tác động ngoài**: commit, push, tin nhắn đã gửi được ghi lại trước khi làm, để khởi động lại không làm lại việc đã xảy ra.
4. **Chọn provider/model**: mặc định chung cộng ghi đè theo task; không có thì **từ chối** chứ không tự thay thế.
5. **Giao việc thật**: giao cho agent chạy trong môi trường đã thuê, thu kết quả, chuyển trạng thái.

**Những cơ chế đáng chú ý:**

- **Git broker**: mỗi task làm việc trong worktree riêng của từng repo trong môi trường, chỉ được dùng một danh sách lệnh git cho phép, có cổng kiểm chỉ-đọc trước khi tích hợp, merge phải được duyệt, không bao giờ push hộ. Hỗ trợ repo lồng nhau (repo thứ hai nằm trong repo ngoài và bị gitignore). Xoá worktree theo thứ tự lồng trước, ngoài sau vì làm ngược lại là phá hoại đo được.
- **Phê duyệt có ràng buộc nội dung**: ghi lại *cái gì* đã được duyệt, không chỉ *đã duyệt hay chưa*; nội dung đổi thì duyệt cũ vô hiệu. Kênh Telegram **khoá mặc định**; token bot được mã hoá bằng kho khoá của hệ điều hành, không nằm trong settings, giao diện chỉ thấy trạng thái.
- **Bước kiểm chứng thật**: điều phối viên tự chạy lệnh kiểm chứng của môi trường và quan sát mã thoát; trạng thái "đang kiểm chứng" thật sự kiểm chứng điều gì đó.
- **Xác minh môi trường (attest)**: lease chưa hết hạn không có nghĩa tiến trình vẫn đúng chỗ; hỏi lại hệ điều hành, fail closed.
- **Chỉ mục tài liệu chỉ giơ tay**: gắn cờ tài liệu trùng tên khác nội dung hoặc lâu không đổi; không bao giờ tự sửa.
- **Dọn output hết hạn là cách ly, không xoá**: chuyển vào vùng cách ly, chứng minh đã chuyển đúng tệp bằng danh tính tệp, không có lệnh xoá nào.
- **Kiểm tra tài nguyên trước khi khởi môi trường**: RAM, đĩa; thiếu thì từ chối tất cả môi trường được hỏi.
- **Vòng tự giao việc** (việc đã duyệt tự chạy khi môi trường rảnh): **mặc định tắt**, bật có chủ đích.
- **Công cụ MCP cho điều phối viên**: tạo/duyệt/giao/huỷ task, hỏi năng lực, xem kết quả kiểm chứng, tất cả qua một đường giao việc duy nhất.

**Giới hạn.** Cần `ai-chat`; thiếu `device-manager` hoặc `task-manager` thì hai pane hiện gợi ý bật plugin, phần chat vẫn dùng được. Các thông số ngưỡng (bao lâu tài liệu bị coi là cũ, output hết hạn sau bao lâu, RAM/đĩa tối thiểu) là giá trị khởi điểm để người dùng chỉnh.

## English

**Purpose.** One frame to talk to the **coordinating agent** (an agent-role acting as manager) while seeing **which devices are online** and **which tasks are running**. Before, you had to open ai-chat, remember which session carried the manager role, and open Task Manager and Device Manager separately.

**Composed from existing plugins, no duplicated code.** The widget has three dockable regions: the device list (from `device-manager`), the task list (from `task-manager`) and the chat (ai-chat's reusable chat UI pinned to the chosen coordinator). Regions are *adopted* into the dock layout rather than rebuilt, because rebuilding a live chat frame means losing the session.

**A persistent task backend** (SQLite in the main process), built in slices:

1. **State machine + task store**: tasks have an explicit lifecycle, every transition is an event with a reason; a task can be traced with one read.
2. **Resource leases**: which environment is held by which task; on restart the store is **reconciled** against reality instead of trusted; on plugin shutdown leases drain with a deadline; there is always a way to abandon work.
3. **Side-effect ledger**: commits, pushes and sent messages are recorded before they happen, so a restart never repeats what already happened.
4. **Provider/model selection**: a shared default plus per-task overrides; when nothing fits the task is **refused**, never silently substituted.
5. **Real dispatch**: hand the work to an agent inside the leased environment, collect the result, advance the state.

**Mechanisms worth knowing:**

- **Git broker**: each task works in its own worktree per repository of the environment, may only use an allow-list of git commands, passes a read-only integrability gate, merges require approval, and nothing is ever pushed on your behalf. Nested repositories (a second repo inside the outer one, gitignored) are supported. Worktrees are removed inner-first, because the opposite order is measurable damage.
- **Content-bound approvals**: record *what* was approved, not just *that* it was; if the content changes the old approval is void. The Telegram channel is **off by default**; the bot token is encrypted with the OS key store, never kept in settings, and the UI only shows status.
- **A real verification step**: the coordinator runs the environment's verification command and reads the exit code, so "validating" actually validates something.
- **Environment attestation**: an unexpired lease does not prove the process is still the right one; ask the OS, fail closed.
- **A document index that only raises its hand**: flags documents with the same name but different content, or untouched for too long; never edits anything.
- **Expired output is quarantined, never deleted**: files are moved to a quarantine area, the move is proven by file identity, and there is no delete command.
- **Capacity preflight** before starting an environment: RAM and disk; if short, every requested environment is refused.
- **Self-dispatch loop** (approved work runs when an environment is free): **off by default**, enabled deliberately.
- **MCP tools for the coordinator**: create/approve/dispatch/cancel tasks, query capacity, read verification results, all through a single dispatch path.

**Limits.** Requires `ai-chat`; without `device-manager` or `task-manager` the two panes show a hint and the chat still works. Threshold settings (when a document counts as stale, when output expires, minimum RAM/disk) are starting values for the user to tune.
