From 8c71ca29d2ae23e1825ec747c6637f568e665e86 Mon Sep 17 00:00:00 2001 From: Wang Date: Wed, 9 Sep 2026 13:08:27 +0800 Subject: [PATCH 1/4] docs(blog): explain how Runtime Host shares work across clients Generated-by: OpenAI Codex --- docs/blogs/runtime-host.md | 167 +++++++++++++++++++++++++++++++ docs/blogs/runtime-host.zh-CN.md | 166 ++++++++++++++++++++++++++++++ 2 files changed, 333 insertions(+) create mode 100644 docs/blogs/runtime-host.md create mode 100644 docs/blogs/runtime-host.zh-CN.md diff --git a/docs/blogs/runtime-host.md b/docs/blogs/runtime-host.md new file mode 100644 index 0000000000..27f9e3ebd7 --- /dev/null +++ b/docs/blogs/runtime-host.md @@ -0,0 +1,167 @@ + + +[简体中文](./runtime-host.zh-CN.md) + +# Maka Runtime Host: How Multiple Clients Share the Same Work + +You ask Maka's desktop app to fix the failing tests in a project. The Agent starts reading code, editing files, and running tests. A little later, you open a terminal to check its progress. + +If each client runs its own Agent, sharing the conversation history won't solve the problem. The desktop app may know that tests are still running while the terminal thinks the previous turn has finished. Resending a message could start another task. + +Both clients need a common place responsible for execution. Maka calls it the **Runtime Host**. It manages when work starts and ends, saves execution facts, and lets clients participate through a protocol. + +## From an Execution Loop to Its Host + +The Runtime runs the Agent loop: assemble context, call a model, run tools, and feed the results back to the model. The Host handles the surrounding responsibilities: who may start work, who may write the data, what happens when a client disconnects, and how to recover and clean up when the process starts or stops. + +Desktop, terminal, and automation clients consequently share the same way in: + +```text +Desktop ─────┐ +Terminal ────┼── Protocol connection ── Runtime Host ── Runtime ── Models and tools +Automation ──┘ │ + └── Sessions, execution records, + background tasks +``` + +A Host can run locally or on a remote machine. Clients submit requests and read progress; the machine running the work resolves the working directory, accesses files, and runs commands. Opening a remote session in a terminal does not reinterpret the remote project path as a local path. + +There is a division of responsibilities inside the Host, too. The Kernel manages startup, connections, and shutdown. Domains such as sessions, Goals, and scheduled tasks are assembled through a **composition**. Each module declares its operations, recovery behavior, and cleanup. Two modules cannot claim the same protocol operation. + +This determines the recovery order: persistent state first, then resources and executions, followed by domain state and schedulers. Otherwise, a scheduled task could start new work before the previous execution has been reconciled. The Host enters Ready only after recovery finishes. Being able to connect before then does not mean business operations can already execute.[^composition] + +## Establish a Single Writer First + +The desktop and terminal clients may start at the same time. Both check for a Host, find none, and launch a process. This race sits between checking and starting; a PID file or the existence of a socket cannot settle it. + +Maka calls the directory holding its persistent state a **State Root**. Only one Host may write to a State Root at a time. A process must acquire an operating system lock before it can open storage, run migrations, and admit work as that Root's Host. Registration files and socket addresses help clients discover the Host. The lock determines who may write. + +Two identities matter here. A `rootId` identifies the persistent data; a `HostEpoch` identifies the current Host process instance. After a restart, the data is still the same, but the process identity has changed. Clients can therefore recognize old connections, observations, and upgrade requests instead of applying them to the new process. + +Graceful shutdown respects the same boundary: stop admitting work, wait for existing work to finish or hand over safely, close storage, and finally release write ownership. A successor must acquire ownership that the previous process has actually relinquished.[^ownership] + +## Give Every Task the Same Entry Point + +Having one Host is only the first step. Its internal entry points must also agree about execution. User messages, the next step of a Goal, scheduled tasks, and automation calls can all ask to start work. + +Maka centralizes root execution in `RootTurnCoordinator`. A root execution begins a turn of work. It can spawn subagents, but a session can have only one root execution active at a time. Different sessions can still run in parallel. + +New work first passes through **admission**. This stage serializes checks within a session, reserves an execution slot, and persists the request identity, message content, and associated execution record before handing work to the Runtime. The critical section protects admission; it is not held for the duration of the execution. + +```text +Task from any entry point + ↓ +Check the session and reserve a slot + ↓ +Persist which work was accepted + ↓ +Hand it to the Runtime +``` + +Saving admission first has a practical use. A client that sent a request but received no reply can return with the original identity to check. The Host compares identity and content to determine whether it already accepted that work. Reusing an identity with different content is rejected; retrying an accepted request cannot turn it into a new task. + +The record also gives recovery a starting point. The Host can distinguish work accepted but not yet started from work started but not finished. If admission itself is uncertain, it stops further execution rather than risking repeated side effects on an unverified basis.[^admission] + +## Let Clients Catch Up Without Owning Progress + +Once work belongs to the Host, clients see a view of its execution state. [Log Is the Runtime](./log-is-the-runtime.md) explains the underlying record: model and tool execution events are saved in `RuntimeEvents`. For regular runtime sessions, conversation history is derived from those events. A reopened interface can rebuild its view from persisted facts. + +Live updates introduce an easy-to-miss gap. If a client first queries a snapshot and then subscribes to events, a task could finish between those two steps, leaving the client without its completion notification. + +Maka establishes the snapshot and the starting sequence for subsequent events together when opening a subscription. The Host sends the subscription-open response before sending later events, so the client knows where to begin. If event sequences have a gap, or `HostEpoch` changes, the client opens a new subscription and reads the current state. + +Long histories load in pages, and live subscriptions have bounded buffers. Terminal output uses a separate subscription so a burst of logs cannot overwhelm conversation updates. Neither a slow history reader nor a fast tool producer becomes a reason to accumulate unlimited memory.[^observation] + +Reconnection must also distinguish reading from execution. Queries can be retried under the protocol's rules. A mutation that was sent but has no result may already have happened, with only its response lost. The general connection layer cannot simply resend it. Maka preserves the unknown outcome and lets the specific operation reconcile it against durable records. The desktop's outgoing queue likewise saves text and attachments before clearing the composer, so unconfirmed delivery is not mistaken for a message that was never sent.[^delivery] + +## One Connection Can Work in Both Directions + +Local connections use Unix sockets or Windows named pipes. Remote access can use WebSocket, SSH, or the peer network. Once inside the Host, these transports use the same operation protocol and permission checks. Domain modules do not need separate local and remote implementations. + +The protocol works in both directions. A task on a remote Host may need a native operation supplied by the desktop client or an MCP tool connected to the local computer. A client can offer a **Client Capability**: the Host calls it, and the client executes it and returns the result. + +This means the connection cannot finish handling one request before reading the next message. If the Host were waiting for a client tool result while its read loop remained blocked on the current request, both sides would wait for each other. Message reading and request execution therefore advance separately. Request concurrency is bounded, and health checks have reserved capacity so a busy connection can still establish whether its peer is alive.[^protocol] + +Reverse calls also have an explicit execution boundary. The client first confirms that it can accept the call. The Host checks permissions and sends `admitted`; only then may the client execute. A disconnect before that boundary means the call was not authorized to proceed. After it, the operation may already have happened, so a missing result must be treated as unknown rather than repeated automatically. + +Capabilities are bound to the appropriate client. For a session-bound tool, losing the original computer must not silently substitute another one: the tool name would stay the same while its execution environment changed. Session sharing follows the same attention to scope. Permission to view a session or submit requests for approval does not automatically grant access to the Host's files, settings, or tools.[^capabilities] + +Peer connections also handle network path changes. Within the same Host process, byte offsets, acknowledgments, and deduplication can preserve the logical connection across a brief path change. A Host restart still requires a new connection and session subscription. These recovery mechanisms address transport continuity and business state separately; neither requires executing a business command twice.[^peer] + +## A Host's Lifetime Is More Than a Window Count + +Closing an interface, losing a connection, finishing a task, and stopping the Host are different events. An independently deployed Host may be running a Goal or waiting for a scheduled task even when no client is connected. + +The Host therefore records reasons to stay alive as **residencies**, with two kinds: + +| Kind | Example | Effect on shutdown | +|---|---|---| +| `idle`: retain the process | A future scheduled task or a paused Goal | Prevents natural idle exit, but does not block graceful shutdown | +| `drain`: work in progress | Executing a task, saving results, or admitting a request | Must finish or be handed over safely before graceful shutdown | + +Conflating the two could make today's upgrade wait for a task scheduled for tomorrow. Counting only active model calls, on the other hand, could let the Host exit while saving results. + +An admission request must register as active work before its first asynchronous wait. Otherwise, a request could already be waiting for session admission while remaining invisible to shutdown. Natural idle detection must also count connections still handshaking, not just clients that have finished connecting.[^residency] + +Who decides to stop the process depends on deployment. An independent service belongs to its service manager. A Host launched and managed by the desktop app is closed by its launch-owner guard when the app exits. A connection can leave independently; whether the process continues has an explicit owner. + +Write ownership and installation ownership are also managed separately. The operating system lock answers which process may write the data. The deployment ownership record answers which of Desktop, CLI, or a service manager may take over or replace the Host, preventing independent entry points from competing to update the same installation.[^deployment] + +## Hand Over a Turn During an Upgrade + +Long tasks may make it impractical to wait for an idle moment to upgrade. For runs that support continuation, Maka provides a safe handoff. The old Host pauses new work, lets the run stop at a durable model or tool step boundary, and saves continuation information for the new Host to verify and take over. + +This requires a distinction between a **Turn** and a **Run**. A Turn is the logical round of work the user started; a Run is one physical execution carrying it out. An upgrade can end the old Run and create a new one while remaining within the same Turn. + +```text +One Turn: fix the failing tests + +Old Host / Run A ── Finish current step ── Save handoff record + │ +New Host / Run B ◀── Verify history and conditions ──┘ + │ + └── Continue with subsequent steps +``` + +The handoff record names the successor Run and includes information to verify the completed history. The new Host must validate that history and continuation relationship. Seeing unfinished work in a session is not enough to start executing it. + +The execution configuration must also be recorded. Maka uses `RunComposition` to capture versions and digests of the execution's ingredients, including prompts, tools, and model-call options. Handoff additionally compares the actual execution conditions. Missing tools, a changed context window, or mismatched configuration can make continuation unsafe. Permitted dynamic tool changes receive their own versions rather than silently rewriting the initial record. + +Finally, the Host must account for each piece of active work: it has either completed or been included in the handoff. There can be no asynchronous gap between the final check and the handoff commit, or unaccounted work could appear just after the Host decided it was safe to exit. + +This mechanism does not migrate arbitrary process memory, PTYs, or external requests in flight. A sudden crash also lacks a prepared handoff. Whether execution can continue depends on the evidence available in durable records; runs that cannot resume safely receive an explicit interrupted state.[^handoff] + +For the user, switching clients still means working on the original task. The Host makes that possible by connecting admission, durable records, observation, and lifecycle management. Each client can open and close independently, while every turn retains an identifiable executor and progress that can be checked. + +## Implementation References + +This article describes repository commit [`8d5c4612`](https://github.com/apache/maka/commit/8d5c4612c46b19270f00fe7aea33c39dff23dbe5). + +[^composition]: [Host Kernel](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/host-kernel.ts), [module composition and phased recovery](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/host-composition.ts), and [Host workspace resolution](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/workspace-resolver.ts). +[^ownership]: [State Root ownership](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/storage/src/root-authority.ts); [Host-owned storage migrations](https://github.com/apache/maka/pull/4770). +[^admission]: [Shared root execution entry point](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/root-turn-coordinator.ts), [session admission gate](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/session-admission-gate.ts), and [durable admission records](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/root-admission-owner.ts). +[^observation]: [Subscriptions and state continuity](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/session-continuity-coordinator.ts); [session transcripts from execution events](https://github.com/apache/maka/pull/4879). +[^delivery]: [Client connections and requests](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/client/connection.ts); [local message persistence and isolated terminal streams](https://github.com/apache/maka/pull/4956). +[^protocol]: [Connection read loop and request dispatch](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/connection-session.ts), [protocol operations](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/protocol/operations.ts). +[^capabilities]: [Client capability invocation](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/client-capability-invocation-broker.ts), [capability provider binding](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/client-capability-coordinator.ts); [session sharing and access lifecycle](https://github.com/apache/maka/pull/4907). +[^peer]: [Resumable peer byte streams](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/transport/resumable-peer-stream.ts); [connection recovery across path changes](https://github.com/apache/maka/pull/4830). +[^residency]: [Host residency](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/host-residency-registry.ts); [process retention versus active work](https://github.com/apache/maka/pull/5060). +[^deployment]: [Deployment ownership](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/operator/local-deployment-owner.ts), [managed deployments](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/operator/managed-deployment.ts); [Host lifetime when the desktop app quits](https://github.com/apache/maka/pull/4756). +[^handoff]: [Automatic Host handoff at safe boundaries](https://github.com/apache/maka/pull/4958); [execution composition records](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/core/src/run-composition.ts), [logical execution and continuation validation](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/core/src/runtime-logical-execution.ts). diff --git a/docs/blogs/runtime-host.zh-CN.md b/docs/blogs/runtime-host.zh-CN.md new file mode 100644 index 0000000000..cb04db4350 --- /dev/null +++ b/docs/blogs/runtime-host.zh-CN.md @@ -0,0 +1,166 @@ + + +[ENGLISH](./runtime-host.md) + +# Maka Runtime Host:多个客户端,如何共享同一份工作 + +你在 Maka 桌面端发起了一项任务:“修复这个项目里失败的测试。”Agent 开始读代码、修改文件、运行测试。过了一会儿,你打开终端,想接着查看进度。 + +如果两个入口各自运行一份 Agent,共享聊天记录并不能解决问题。桌面端知道测试还在跑,终端却可能认为上一轮已经结束;同一条消息重发一次,也可能又启动一份任务。 + +要让它们接上同一份工作,需要有一个共同负责执行的地方。Maka 把它叫作 **Runtime Host**。它管理任务的开始与结束,保存执行事实,并让不同客户端通过协议参与其中。 + +## 从执行循环,到执行的宿主 + +Runtime 负责 Agent 的执行循环:组装上下文、调用模型、运行工具,再把结果交回模型。Host 则负责这个循环之外的事情:谁能发起任务、数据由谁写入、客户端断线后怎么办,以及进程启动和退出时如何收拾现场。 + +这让桌面端、终端和自动化程序有了相同的接入方式: + +```text +桌面端 ─────┐ +终端 ───────┼── 协议连接 ── Runtime Host ── Runtime ── 模型与工具 +自动化程序 ─┘ │ + └── 会话、执行记录、后台任务 +``` + +Host 可以在本机运行,也可以部署在远程机器上。客户端提交请求和读取进度,执行所在的机器负责解释工作目录、访问文件和运行命令。终端打开远程会话时,不会把远程项目路径重新解释成本机路径。 + +Host 内部也有分工。Kernel 管启动、连接和退出;会话、Goal、定时任务等业务通过 **composition** 组装进来。每个模块声明自己的操作、恢复和关闭行为。同一个协议操作不能被两个模块同时认领。 + +这个分工直接影响启动顺序:先恢复持久状态,再恢复资源和执行,最后恢复各项业务及其调度器。否则,定时任务可能在上一次执行还没核对清楚时,就发起下一次工作。只有恢复完成,Host 才进入 Ready;在此之前即使已经能连上,也不代表业务可以开始执行。[^composition] + +## 先保证只有一个 Host 能写 + +桌面端和终端可能同时启动。两边都检查了一遍,发现“似乎没有 Host”,然后各自拉起一个进程。这是检查与启动之间的竞争,单靠 PID 文件或 socket 是否存在无法解决。 + +Maka 把保存持久状态的数据根目录称为 **State Root**。一个 State Root 在同一时刻只允许一个 Host 写入。进程必须先取得操作系统锁,才能作为这个 Root 的 Host 打开存储、执行迁移和接纳工作。注册文件和 socket 地址用于发现 Host,实际写权限由锁决定。 + +这里需要区分两个身份:`rootId` 表示哪一份持久数据,`HostEpoch` 表示当前是哪一次 Host 进程。重启后,数据还是原来的数据,进程身份却已经改变。客户端因此能识别旧连接、旧观察和旧升级请求,避免把它们套在新进程上。 + +正常关闭也遵循这个边界:先停止接纳新工作,等待已有工作结束或完成交接,关闭存储,最后释放写权限。接任者取得的必须是一份已经交还的权限。[^ownership] + +## 所有任务,都从同一个入口开始 + +有了唯一的 Host,还要保证 Host 内部的多个入口不会各自作主。用户消息、Goal 的下一轮推进、定时任务、自动化调用,都可能要求开始一次执行。 + +Maka 将根执行集中到 `RootTurnCoordinator`。所谓根执行,就是一轮工作的起点;它内部可以派生子 Agent,但同一个会话同一时刻只能有一项根执行,不同会话仍然可以并行。 + +新任务先经过 **admission(接纳)**。这个阶段按会话串行检查,预留执行位置,并持久保存请求身份、消息内容和对应的执行记录,之后才把工作交给 Runtime。串行保护的是接纳阶段,执行开始后不再占着这段临界区。 + +```text +来自任一入口的任务 + ↓ +检查会话并预留位置 + ↓ +保存“接受了哪项工作” + ↓ +交给 Runtime 执行 +``` + +先保存接纳记录有一个实际用途:客户端发出请求后没有收到回复,可以带着原请求身份回来核对。Host 比较身份与内容,确认它是否已经接受过这项工作。同一个身份对应不同内容,会被拒绝;已经接受的请求,也不能因为重试就变成新任务。 + +这份记录还让恢复有了起点:Host 能区分“接受了但尚未开始”和“已经开始但没有结束”。如果接纳状态本身无法确认,就停止继续执行,避免沿着不确定的状态重复产生副作用。[^admission] + +## 让客户端追上进度,而不拥有进度 + +任务交给 Host 之后,客户端看到的是执行状态的视图。[《Log Is the Runtime》](./log-is-the-runtime.zh-CN.md) 解释了底层依据:模型与工具的执行事件保存在 `RuntimeEvents` 中,正常执行会话的聊天记录从这些事件生成。重开界面时,可以从已保存的事实重建画面。 + +实时更新还有一个容易漏掉的细节。假如客户端先查询快照,再订阅事件,任务恰好在两步之间完成,结束通知就可能丢失。 + +Maka 把快照和后续事件的起始序号放在同一次订阅建立过程中确定。Host 先发送打开订阅的响应,再发送后续事件;客户端知道自己从哪里开始接。如果事件序号出现缺口,或者 `HostEpoch` 改变,就重新建立订阅、读取当前状态。 + +长会话则按需分页读取,实时订阅设置缓冲上限。终端输出另走独立的订阅,避免一次大量日志把聊天更新挤掉。这样,客户端读取旧历史的速度和工具输出的速度,都不会变成无限堆积内存的理由。[^observation] + +重连还要区分读取和执行。查询可以按规则重试;修改操作如果已经发出,却没有收到结果,就可能处于“做过了,只是回复丢了”的状态。通用连接层不能直接重发。Maka 保留结果未知的事实,由具体操作根据持久记录核对;桌面端的待发送队列也先保存文本和附件,再清空输入框,避免把未确认送达误当成没有发送过。[^delivery] + +## 一条连接,可以双向工作 + +本地连接使用 Unix socket 或 Windows named pipe,远程可以通过 WebSocket、SSH 或 peer 网络接入。传输方式不同,进入 Host 后使用相同的操作协议和权限检查,业务模块不必各写一套本地版和远程版。 + +这条协议是双向的。例如,远程 Host 运行任务时,可能需要桌面端提供的一项原生操作或本机 MCP 工具。客户端可以作为 **Client Capability** 的提供者,由 Host 发起调用,客户端执行后返回结果。 + +这也决定了连接不能“处理完一个请求,再读下一个请求”。如果 Host 正在等客户端工具的结果,却把收消息的循环堵在当前请求上,双方就会互相等待。因此,读消息和执行请求分开推进;请求并发有上限,健康探测保留通道,避免业务满载后连连接是否存活也无法确认。[^protocol] + +反向调用还有一个明确的执行分界:客户端先确认能接受调用,Host 再检查权限并发送 `admitted`,客户端收到后才能执行。这个分界之前断线,调用尚未获准;之后断线,操作可能已经发生,缺失的结果就要按“未知”处理,不能擅自再做一次。 + +能力还会绑定到相应的客户端。对于会话绑定的工具,原电脑断线后不能悄悄换另一台电脑执行,否则工具名称没变,实际操作的环境却变了。共享会话同样按资源授权:查看某个会话、提交待批准的请求,不会自动获得整个 Host 的文件、设置或工具权限。[^capabilities] + +Peer 连接进一步处理网络路径变化:在同一 Host 进程内,可以用字节位置、确认和去重,在短暂换路后接续原来的逻辑连接。Host 重启后仍要重新建立连接与会话订阅。这两种恢复分别处理传输连续性和业务状态,也都不需要把业务命令执行两遍。[^peer] + +## Host 活多久,不能只看还有几个窗口 + +关闭界面、断开连接、完成任务和停止 Host,是不同的事件。一个独立部署的 Host,即使没有客户端连接,也可能正在运行 Goal,或者等着下一次定时任务。 + +因此 Host 用 **residency** 记录保留进程的理由,并区分两类: + +| 类型 | 例子 | 对退出的影响 | +|---|---|---| +| `idle`:保留进程 | 等待未来触发的定时任务、暂停中的 Goal | 阻止因自然空闲而退出,但不阻挡正常关闭 | +| `drain`:正在工作 | 执行任务、保存结果、接纳请求 | 正常关闭前要等待完成或安全交接 | + +如果把两类混在一起,一个明天才触发的任务就可能让今天的升级一直等下去;如果只统计正在运行的模型调用,又可能在保存结果时提前退出。 + +接纳请求也要从第一次异步等待之前就登记为活动工作。否则,请求已经进来了、还在等会话检查,退出流程却看不见它。自然空闲判断还要考虑正在握手的连接,不能只数已经连上的客户端。[^residency] + +至于谁决定进程应该停止,则取决于部署方式。独立服务由服务管理器负责;桌面应用启动并管理的 Host,会由启动方的生命周期守卫在应用退出后关闭。连接本身可以随时离开,进程是否继续则有明确的管理者。 + +写数据的权限与更新安装的权限也分别管理。操作系统锁解决“哪个进程能写这份数据”,部署所有权记录解决“Desktop、CLI、服务管理器中谁能接管或替换这个 Host”,避免多个入口各自尝试更新同一份安装。[^deployment] + +## 升级时,交接的是一轮工作 + +长任务不一定能等到空闲时再升级。Maka 为支持接续的运行提供安全交接:旧 Host 暂停新工作,让运行停在模型或工具步骤的持久化边界,保存接续所需的信息,再由新 Host 验证并接手。 + +这需要区分 **Turn** 和 **Run**:Turn 是用户发起的那一轮逻辑工作,Run 是承载它的一次物理执行。升级可以结束旧 Run,再创建新 Run,但仍属于同一个 Turn。 + +```text +同一个 Turn:修复失败的测试 + +旧 Host / Run A ── 完成当前步骤 ── 保存交接记录 + │ +新 Host / Run B ◀── 校验记录与执行条件 ───┘ + │ + └── 继续后续步骤 +``` + +交接记录明确指定由哪个后续 Run 接手,并带上已完成历史的校验信息。新 Host 必须验证这份历史和接续关系,不能仅凭“这个会话还有任务”就自行开始。 + +运行采用的配置也要有据可查。Maka 用 `RunComposition` 记录执行组成的版本和摘要,涵盖提示、工具和模型调用选项等。交接时还会比较实际执行条件;缺少工具、上下文窗口变化或配置不匹配,都可能使接续不再安全。允许发生的动态工具变化会另记版本,不会悄悄改写最初的记录。 + +最后,Host 必须核对每一项活动工作:它已经完成,还是已经纳入交接。最终检查与提交交接决定之间不能再留下异步空隙,否则可能刚判断“可以退出”,就又出现尚未处理的工作。 + +这套机制不迁移任意进程内存、PTY 或正在进行的外部请求。突然崩溃也没有事先准备好的交接条件:能否继续取决于持久记录提供了什么证明,无法安全恢复的运行会留下明确的中断状态。[^handoff] + +从用户的角度,换个入口仍然是在处理原来的任务。为此,Host 把执行接纳、持久记录、观察协议和生命周期接在了一起:每个入口可以独立打开和关闭,每一轮工作却始终有明确的执行者和可核对的进度。 + +## 实现参考 + +本文对应仓库提交 [`8d5c4612`](https://github.com/apache/maka/commit/8d5c4612c46b19270f00fe7aea33c39dff23dbe5)。 + +[^composition]: [Host Kernel](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/host-kernel.ts)、[模块组装与分阶段恢复](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/host-composition.ts)、[Host 工作目录解析](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/workspace-resolver.ts)。 +[^ownership]: [State Root 所有权](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/storage/src/root-authority.ts);[存储迁移归属 Host](https://github.com/apache/maka/pull/4770)。 +[^admission]: [统一根执行入口](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/root-turn-coordinator.ts)、[会话接纳门](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/session-admission-gate.ts)、[持久接纳记录](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/root-admission-owner.ts)。 +[^observation]: [订阅与状态衔接](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/session-continuity-coordinator.ts);[从执行事件生成会话记录](https://github.com/apache/maka/pull/4879)。 +[^delivery]: [客户端连接与请求处理](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/client/connection.ts);[本地消息保存与独立终端流](https://github.com/apache/maka/pull/4956)。 +[^protocol]: [连接读循环与请求分发](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/connection-session.ts)、[协议操作](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/protocol/operations.ts)。 +[^capabilities]: [客户端能力调用](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/client-capability-invocation-broker.ts)、[能力提供者绑定](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/client-capability-coordinator.ts);[会话共享与权限生命周期](https://github.com/apache/maka/pull/4907)。 +[^peer]: [可恢复的 peer 字节流](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/transport/resumable-peer-stream.ts);[网络路径变化后的连接恢复](https://github.com/apache/maka/pull/4830)。 +[^residency]: [Host residency](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/host-residency-registry.ts);[区分保留进程与活动工作](https://github.com/apache/maka/pull/5060)。 +[^deployment]: [部署所有权](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/operator/local-deployment-owner.ts)、[受管理的部署](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/operator/managed-deployment.ts);[桌面应用退出时的 Host 生命周期](https://github.com/apache/maka/pull/4756)。 +[^handoff]: [在安全边界自动交接 Host](https://github.com/apache/maka/pull/4958);[执行组成记录](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/core/src/run-composition.ts)、[逻辑执行与接续校验](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/core/src/runtime-logical-execution.ts)。 From 328aad8ed6b2af8b770626c68d24e4611ff30422 Mon Sep 17 00:00:00 2001 From: Wang Date: Wed, 9 Sep 2026 13:14:33 +0800 Subject: [PATCH 2/4] docs(blog): render Runtime Host diagrams with Mermaid Generated-by: OpenAI Codex --- docs/blogs/runtime-host.md | 48 +++++++++++++++++--------------- docs/blogs/runtime-host.zh-CN.md | 47 +++++++++++++++++-------------- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/docs/blogs/runtime-host.md b/docs/blogs/runtime-host.md index 27f9e3ebd7..c4a4f09a70 100644 --- a/docs/blogs/runtime-host.md +++ b/docs/blogs/runtime-host.md @@ -33,12 +33,15 @@ The Runtime runs the Agent loop: assemble context, call a model, run tools, and Desktop, terminal, and automation clients consequently share the same way in: -```text -Desktop ─────┐ -Terminal ────┼── Protocol connection ── Runtime Host ── Runtime ── Models and tools -Automation ──┘ │ - └── Sessions, execution records, - background tasks +```mermaid +flowchart TD + desktop["Desktop"] --> connection["Protocol connection"] + terminal["Terminal"] --> connection + automation["Automation"] --> connection + connection --> host["Runtime Host"] + host --> runtime["Runtime"] + runtime --> tools["Models and tools"] + host --> state["Sessions, execution records
and background tasks"] ``` A Host can run locally or on a remote machine. Clients submit requests and read progress; the machine running the work resolves the working directory, accesses files, and runs commands. Opening a remote session in a terminal does not reinterpret the remote project path as a local path. @@ -65,14 +68,11 @@ Maka centralizes root execution in `RootTurnCoordinator`. A root execution begin New work first passes through **admission**. This stage serializes checks within a session, reserves an execution slot, and persists the request identity, message content, and associated execution record before handing work to the Runtime. The critical section protects admission; it is not held for the duration of the execution. -```text -Task from any entry point - ↓ -Check the session and reserve a slot - ↓ -Persist which work was accepted - ↓ -Hand it to the Runtime +```mermaid +flowchart TD + request["Task from any entry point"] --> reserve["Check the session and reserve a slot"] + reserve --> persist["Persist which work was accepted"] + persist --> execute["Hand it to the Runtime"] ``` Saving admission first has a practical use. A client that sent a request but received no reply can return with the original identity to check. The Host compares identity and content to determine whether it already accepted that work. Reusing an identity with different content is rejected; retrying an accepted request cannot turn it into a new task. @@ -130,14 +130,18 @@ Long tasks may make it impractical to wait for an idle moment to upgrade. For ru This requires a distinction between a **Turn** and a **Run**. A Turn is the logical round of work the user started; a Run is one physical execution carrying it out. An upgrade can end the old Run and create a new one while remaining within the same Turn. -```text -One Turn: fix the failing tests - -Old Host / Run A ── Finish current step ── Save handoff record - │ -New Host / Run B ◀── Verify history and conditions ──┘ - │ - └── Continue with subsequent steps +```mermaid +sequenceDiagram + participant old as Old Host / Run A + participant records as Durable handoff record + participant successor as New Host / Run B + Note over old,successor: One Turn: fix the failing tests + old->>old: Finish current step + old->>records: Save handoff record + successor->>records: Read handoff record + records-->>successor: Return record + successor->>successor: Verify record and conditions + successor->>successor: Continue subsequent steps ``` The handoff record names the successor Run and includes information to verify the completed history. The new Host must validate that history and continuation relationship. Seeing unfinished work in a session is not enough to start executing it. diff --git a/docs/blogs/runtime-host.zh-CN.md b/docs/blogs/runtime-host.zh-CN.md index cb04db4350..1c71e4b2e6 100644 --- a/docs/blogs/runtime-host.zh-CN.md +++ b/docs/blogs/runtime-host.zh-CN.md @@ -33,11 +33,15 @@ Runtime 负责 Agent 的执行循环:组装上下文、调用模型、运行 这让桌面端、终端和自动化程序有了相同的接入方式: -```text -桌面端 ─────┐ -终端 ───────┼── 协议连接 ── Runtime Host ── Runtime ── 模型与工具 -自动化程序 ─┘ │ - └── 会话、执行记录、后台任务 +```mermaid +flowchart TD + desktop["桌面端"] --> connection["协议连接"] + terminal["终端"] --> connection + automation["自动化程序"] --> connection + connection --> host["Runtime Host"] + host --> runtime["Runtime"] + runtime --> tools["模型与工具"] + host --> state["会话、执行记录、后台任务"] ``` Host 可以在本机运行,也可以部署在远程机器上。客户端提交请求和读取进度,执行所在的机器负责解释工作目录、访问文件和运行命令。终端打开远程会话时,不会把远程项目路径重新解释成本机路径。 @@ -64,14 +68,11 @@ Maka 将根执行集中到 `RootTurnCoordinator`。所谓根执行,就是一 新任务先经过 **admission(接纳)**。这个阶段按会话串行检查,预留执行位置,并持久保存请求身份、消息内容和对应的执行记录,之后才把工作交给 Runtime。串行保护的是接纳阶段,执行开始后不再占着这段临界区。 -```text -来自任一入口的任务 - ↓ -检查会话并预留位置 - ↓ -保存“接受了哪项工作” - ↓ -交给 Runtime 执行 +```mermaid +flowchart TD + request["来自任一入口的任务"] --> reserve["检查会话并预留位置"] + reserve --> persist["保存接受了哪项工作"] + persist --> execute["交给 Runtime 执行"] ``` 先保存接纳记录有一个实际用途:客户端发出请求后没有收到回复,可以带着原请求身份回来核对。Host 比较身份与内容,确认它是否已经接受过这项工作。同一个身份对应不同内容,会被拒绝;已经接受的请求,也不能因为重试就变成新任务。 @@ -129,14 +130,18 @@ Peer 连接进一步处理网络路径变化:在同一 Host 进程内,可以 这需要区分 **Turn** 和 **Run**:Turn 是用户发起的那一轮逻辑工作,Run 是承载它的一次物理执行。升级可以结束旧 Run,再创建新 Run,但仍属于同一个 Turn。 -```text -同一个 Turn:修复失败的测试 - -旧 Host / Run A ── 完成当前步骤 ── 保存交接记录 - │ -新 Host / Run B ◀── 校验记录与执行条件 ───┘ - │ - └── 继续后续步骤 +```mermaid +sequenceDiagram + participant old as 旧 Host / Run A + participant records as 持久化交接记录 + participant successor as 新 Host / Run B + Note over old,successor: 同一个 Turn:修复失败的测试 + old->>old: 完成当前步骤 + old->>records: 保存交接记录 + successor->>records: 读取交接记录 + records-->>successor: 返回记录 + successor->>successor: 校验记录与执行条件 + successor->>successor: 继续后续步骤 ``` 交接记录明确指定由哪个后续 Run 接手,并带上已完成历史的校验信息。新 Host 必须验证这份历史和接续关系,不能仅凭“这个会话还有任务”就自行开始。 From b76c558a639a7dabecae377b7b819deb228e9a76 Mon Sep 17 00:00:00 2001 From: Wang Date: Wed, 9 Sep 2026 15:03:13 +0800 Subject: [PATCH 3/4] docs(blog): explain Peer Mesh and cross-device collaboration Generated-by: OpenAI Codex --- docs/blogs/peer-mesh.md | 167 ++++++++++++++++++++++++++++++++++ docs/blogs/peer-mesh.zh-CN.md | 167 ++++++++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+) create mode 100644 docs/blogs/peer-mesh.md create mode 100644 docs/blogs/peer-mesh.zh-CN.md diff --git a/docs/blogs/peer-mesh.md b/docs/blogs/peer-mesh.md new file mode 100644 index 0000000000..834061eae9 --- /dev/null +++ b/docs/blogs/peer-mesh.md @@ -0,0 +1,167 @@ + + +[简体中文](./peer-mesh.zh-CN.md) + +# Maka Peer Mesh: From Remote Access to Work Across Devices + +An Agent task may not belong entirely on the computer in front of you. A laptop is convenient for interaction, a machine at home can stay running, and another workstation may have the environment a task needs. Teammates also have their own tools, data, and permissions. + +[Runtime Host](./runtime-host.md) lets execution exist independently of the client. The next question is how these distributed endpoints find one another and keep cooperating as their networks change. + +Maka's Peer Mesh provides an application-level networking foundation. It starts with identity, membership, connectivity, and recovery. On that foundation, Maka can explore workflows that combine execution capabilities across devices. + +Private meshes, direct connections, and controlled transit are implemented today, though Peer Mesh remains experimental. This article explains those mechanisms before exploring the product directions they enable. Automatic capability discovery and cross-Host scheduling in the latter part are future possibilities.[^scope] + +## Connecting Maka Endpoints + +A Peer Mesh node is a Maka client or Runtime Host. A client and Host on the same computer can have different identities and lifetimes. One client can also use its peer endpoint to connect to multiple Hosts. + +This network carries Maka protocol traffic. It does not assign virtual IP addresses to machines or expose arbitrary ports. Joining a Mesh does not give other members a path to databases, file shares, or unrelated local services. + +That scope allows networking to fit directly into Maka's interaction model: invitations, joining, member management, and the choice to help relay traffic all belong to the application. SSH, TLS, and external network overlays remain available; Peer Mesh adds a native path for Maka.[^scope] + +## Recognize the Peer Before Looking for Its Address + +An IP address describes where to try connecting now. It is a poor answer to who is on the other end. A laptop changes address when it changes networks, and a restarted machine should not become a new member. + +Maka identifies an endpoint with a key-based **PeerId**. Connections must authenticate the expected PeerId rather than accept whoever responds at an address. Addresses can change while the target identity remains stable. + +Membership lives in a separate **Mesh roster**. The Mesh authority signs a versioned member list. Other nodes verify the signature and reject updates from the wrong authority or outdated versions. Joining requires an explicit invitation; removing a member or closing the Mesh also updates that record. + +Data can therefore flow directly between members while membership changes retain an explicit signer. Changing the roster requires the authority's participation; ordinary communication does not route every message through it. The current implementation targets small private networks, with at most 64 members per Mesh.[^membership] + +Several related questions have different answers: + +| Question | Evidence | +|---|---| +| Who is this peer? | PeerId and connection authentication | +| Does it belong to this Mesh? | The authority-signed roster | +| Where can it be reached now? | The peer's signed reachability record | +| What may it do after connecting? | The target Host's credentials and resource grants | + +Connectivity, recovery, and collaboration all depend on keeping these facts separate. + +## Addresses Expire Without Ending Membership + +Saving the address from one successful connection is not enough. A home network can reconnect with a new address, a laptop can sleep, and a relay reservation can expire. An address book that never changes soon stops being useful. + +Maka lets each peer publish a signed **reachability lease**. It contains its PeerId, revision, expiry, and current direct and coordination-relay routes. A recipient checks identity, revision, and validity before accepting it as a new connection hint. Receiving the same record again does not extend its lifetime. + +Members exchange new records through incremental point-to-point reconciliation: compare known revisions and fill in missing or newer information. Address changes and restored connections trigger synchronization, while periodic checks catch missed events. This keeps a small Mesh up to date without broadcasting every business message across the network.[^reachability] + +Being temporarily unreachable is therefore different from no longer belonging to the Mesh. When old routes expire, Maka retains membership and looks for new hints through other members or previously successful relays. It remembers relay addresses; it does not assume yesterday's reservation is still valid. + +Recovery has a physical limit. If both peers have changed addresses, no old route works, and nobody else knows their new locations, a PeerId alone cannot send the first packet. Maka enters `needs_repair`, allowing a fresh invitation or another bootstrap path to supply new hints while preserving the original identity and membership. + +Guaranteeing that peers can always find each other after prolonged downtime would require choosing a stable rendezvous service and an operating model for it. Someone has to provide the availability of address discovery; cryptographic identity cannot supply it by itself.[^recovery] + +## Members Can Help When Direct Connections Fail + +Home and mobile networks commonly sit behind NAT. Being able to initiate an outbound connection does not mean an outside peer can connect back. The endpoints first need to exchange hints and try to establish a usable path. + +Maka's native peer endpoint uses Rust/libp2p. It supports paths including QUIC and TCP, with DCUtR coordinating hole punching. WebRTC ICE offers another opportunity for a direct connection by trying different candidates in networks where the original path cannot connect. These paths share the business endpoint's PeerId and carry the same Runtime Host protocol once established.[^transport] + +Two kinds of relay serve different purposes: + +- **Coordination relays** help peers meet, exchange control information, and negotiate direct connections. External public relays have this role; they do not carry Runtime Host application traffic. +- **Member transit** is explicitly enabled by a node inside the Mesh. It can carry application traffic for permitted members when a direct path is unavailable. + +The diagram shows alternative paths. Dotted lines carry coordination information; solid lines carry application traffic. An actual connection uses only an eligible path. + +```mermaid +flowchart TD + coordination["External coordination relay"] -.->|"Negotiate connection"| client["Client A"] + coordination -.->|"Negotiate connection"| host["Host B"] + client <-->|"Direct"| host + client <-->|"Encrypted traffic"| transit["Member C with transit enabled"] + transit <-->|"Encrypted traffic"| host +``` + +Member transit is off by default and enabled by the operator for a selected Mesh. It is currently limited to one hop, with limits on connection count, duration, and traffic. The client and target Host retain end-to-end authentication and encryption. The transit peer gains neither application plaintext nor permission to operate the target Host.[^transit] + +Connection attempts can dial known addresses immediately while incorporating newly discovered candidates. Candidates share the target identity, deadline, and cancellation signal; late results are discarded after a winner is selected. The race is between ways to establish a connection, not between copies of the same business command sent down several paths.[^dialing] + +If neither a direct path nor approved member transit works, the connection fails. Peer Mesh adds possible routes; it does not eliminate every network topology constraint. + +## A Path Change Does Not Redefine a Task or Its Permissions + +A brief path change need not restart the application session. Maka tracks sent and acknowledged byte positions in its peer stream and retains a bounded amount of unacknowledged data. After attaching a new path, it can retransmit those bytes and deduplicate them at the receiver, preserving the logical connection. + +This transport recovery operates within the same process and has time and memory limits. A reattached stream must still match the original peer and authenticated identity. A Host restart requires fresh authentication and session subscriptions. Business operations with unknown outcomes cannot be replayed automatically by the network layer.[^continuity] + +After connecting, the target Host still validates credentials, the expected State Root identity, and permission for each operation. A Mesh invitation grants network membership; sharing a Session uses that Session's own authorization flow. + +Revoking Session access does not remove someone from the entire Mesh. Removing them from the Mesh does not automatically revoke Host credentials they might use through SSH or another path. Network membership and resource authorization can change independently, allowing the application to scope collaboration to a task.[^authorization] + +## What This Foundation Opens Up for Maka + +Today, Peer Mesh primarily provides recognizable identities, discoverable routes, connections, and recovery under defined conditions. Once nodes can communicate, the larger opportunity is this: **people can choose capabilities around the work, instead of always arranging work around one machine.** + +Three directions are worth building on this foundation. + +### From Separate Installations to a Personal Work Network + +A person might interact on a laptop, leave a long task running on a Host at home, and return from another device to check progress or handle an approval. Remote Hosts, session protocols, and Peer Mesh already provide foundations for this workflow. + +Future clients could become lighter entry points: discover the Hosts a user is authorized to access, remember where each task belongs, and use whichever connection path is currently available. Cross-device task discovery, identity continuity, and offline experience still need work. A cached row in a task list cannot establish that the task is still running. + +A concrete first test would be one task surviving client sleep, a network change, and access from another client: find the correct Host, recover progress, and pick up pending interactions without pairing again or submitting the task again. + +### From Choosing a Machine to Combining Capabilities + +One machine may be suited to builds, another may have local applications attached, and another may offer model inference. A future Maka could route requests to suitable nodes according to the capabilities a task needs. + +Client Capability already lets a Host use tools offered by a client. The next opportunity is to extend explicitly authorized calls into a discoverable capability network. Today's Mesh advertisements describe identity, endpoint kind, and transit availability; they are not a tool or compute catalog. Capability discovery, versions, availability, quotas, and authorization need their own design. + +The following diagram is a possible future workflow. Dotted lines represent cross-node orchestration that still needs to be developed: + +```mermaid +flowchart TD + task["Task: complete and verify a change"] --> owner["Host responsible for this turn"] + owner -.->|"Delegate a build"| build["Build Host with the right environment"] + owner -.->|"Request a local operation"| client["User's client"] + owner -.->|"Request collaboration"| collaborator["Authorized collaborator"] +``` + +A capability can be called remotely while its provider retains permission to decide what it will execute. One concrete capability is enough for a first step: return a verifiable result from a remote build, then establish that disconnection, cancellation, and repeated requests do not leave that build without an accountable executor. The network delivers messages; the capability protocol defines the execution commitment. + +### From Shared Sessions to Tasks Across Hosts + +Session sharing currently lets another person participate in work on a particular Host. A further step would let several Hosts take responsibility for subtasks: one builds and tests, another validates a specific environment, and both return results to the Host responsible for the overall turn. + +This has different failure modes from spawning several subagents within one Host. Nodes can go offline independently, results can arrive late, and a remote task can still be running after cancellation. Cross-Host collaboration needs durable delegation records, explicit executors, result provenance, and cancellation rules. Peer Mesh supplies connectivity; it does not create those scheduling semantics or replicate different Hosts' State Roots into one shared state. + +A useful first proof is a small, complete collaboration cycle: delegate and finish one subtask across two Hosts, interrupt the network, then establish that execution is not duplicated, results can be verified, and permissions remain within the grant. Once that cycle works, the same contract has a basis for extending to more nodes. + +The long-term value of Peer Mesh lies in these workflows. Devices retain their data and permissions while tasks use capabilities distributed across them. Maka's scope of collaboration can then grow from one client and one Host into a network of participants able to contribute to the work. + +## Implementation References + +Current mechanisms correspond to repository commit [`8d5c4612`](https://github.com/apache/maka/commit/8d5c4612c46b19270f00fe7aea33c39dff23dbe5). The future directions are design inferences from these mechanisms, not completed product features. + +[^scope]: [Peer Mesh scope, milestones, and boundaries](https://github.com/apache/maka/issues/3842); [Mesh components for clients and Hosts](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/owner.ts). +[^membership]: [Signed rosters and member advertisements](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/model.ts), [invitations and membership management](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/node.ts), and [current scale limits](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/limits.ts). +[^reachability]: [Reachability leases and duplicate-record expiry](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-reachability/model.ts), [durable revision publishing](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-reachability/publisher.ts), and [incremental member reconciliation](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/node.ts). +[^recovery]: [Reachability recovery conditions and design](https://github.com/apache/maka/issues/4554), [rediscovering existing members](https://github.com/apache/maka/pull/4893), and [relay anchor storage](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/native/runtime-host-peer/src/engine/relay_anchor_store.rs). +[^transport]: [Native connection implementation](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/native/runtime-host-peer/src/engine.rs), [WebRTC upgrades and target identity validation](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/native/runtime-host-peer/src/webrtc_direct/upgrade.rs); [WebRTC evidence and coverage boundaries](https://github.com/apache/maka/issues/4382). +[^transit]: [Bounded one-hop transit](https://github.com/apache/maka/pull/4142), [transit policy reconciliation](https://github.com/apache/maka/pull/4144), and [controls and diagnostics](https://github.com/apache/maka/pull/4147). +[^dialing]: [Recovering live routes within one connection attempt](https://github.com/apache/maka/pull/4580), [peer client](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/client/peer-client.ts). +[^continuity]: [Resumable byte stream](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/transport/resumable-peer-stream.ts), [credential and identity checks on recovery](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/peer-listener.ts); [path changes and logical connections](https://github.com/apache/maka/pull/4830). +[^authorization]: [Separate Mesh and resource-sharing scopes](https://github.com/apache/maka/issues/3842), [shared-session access lifecycle](https://github.com/apache/maka/pull/4907), and [client capability invocation](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/client-capability-invocation-broker.ts). diff --git a/docs/blogs/peer-mesh.zh-CN.md b/docs/blogs/peer-mesh.zh-CN.md new file mode 100644 index 0000000000..49b5217133 --- /dev/null +++ b/docs/blogs/peer-mesh.zh-CN.md @@ -0,0 +1,167 @@ + + +[ENGLISH](./peer-mesh.md) + +# Maka Peer Mesh:从远程访问,到跨设备协作 + +一项 Agent 任务,未必适合全部放在眼前这台电脑上。笔记本方便交互,家里的机器可以长期运行,另一台工作站可能有任务需要的环境。团队成员也各自拥有工具、数据和权限。 + +[Runtime Host](./runtime-host.zh-CN.md) 让执行可以独立于客户端存在。接下来的问题是:这些分散的节点,怎样找到彼此,并在网络变化后继续合作? + +Maka 的 Peer Mesh 为此提供一层应用内的网络基础。它先解决身份、成员关系、连接和恢复;在这之上,Maka 才有机会把不同设备上的执行能力组织成更完整的工作流。 + +目前 Peer Mesh 已实现私有 Mesh、直连和受控转发,仍处于实验阶段。本文先解释这些机制,再讨论它们打开的产品方向。后半部分的自动发现能力和跨 Host 调度属于未来设想。[^scope] + +## 连接的是 Maka 端点 + +Peer Mesh 的节点是一个 Maka 客户端或 Runtime Host。同一台电脑上的客户端与 Host 可以有不同的身份和生命周期;一个客户端也可以通过自己的 peer 端点连接多个 Host。 + +这层网络承载 Maka 的协议流量,不为整台机器分配虚拟 IP,也不开放任意端口。加入 Mesh 之后,其他成员不会因此获得访问数据库、文件共享或本机服务的通道。 + +这个范围让连接可以直接进入 Maka 的交互流程:邀请、加入、查看成员、选择是否帮助转发,都由应用管理。已有的 SSH、TLS 或外部组网方式仍然可用,Peer Mesh 为 Maka 增加了一条原生路径。[^scope] + +## 先认出节点,再寻找地址 + +IP 地址适合描述“目前到哪里连接”,却不适合回答“对方是谁”。笔记本换了网络,地址会变;机器重启后,也不应该被当作新成员。 + +Maka 使用基于密钥的 **PeerId** 识别端点。建立连接时要验证预期的 PeerId,而不是只要某个地址响应就接受它。地址可以更新,目标身份保持不变。 + +成员关系则由另一份记录管理:**Mesh roster(成员名册)**。Mesh 的管理端签署名册,记录成员和版本;其他节点可以验证签名,并拒绝错误来源或过时的更新。加入通过显式邀请完成,移除成员或关闭 Mesh 也需要更新这份记录。 + +这意味着数据可以在成员之间直接流动,成员管理仍有明确的签署者。修改名册需要管理端参与,普通通信不要求每条消息都经过它。当前实现面向小规模私有网络,每个 Mesh 最多 64 个成员。[^membership] + +几个看似相近的问题,由不同事实回答: + +| 问题 | 依据 | +|---|---| +| 对方是谁? | PeerId 与连接认证 | +| 对方是否属于这个 Mesh? | 管理端签名的成员名册 | +| 现在从哪里能找到它? | 节点签名的可达性记录 | +| 连上之后能做什么? | 目标 Host 的凭据和资源授权 | + +后面的连接、恢复和协作,都建立在这四件事分开管理的基础上。 + +## 地址会过期,成员关系不会因此消失 + +保存一次连接成功时的地址还不够。家中网络可能重新拨号,笔记本可能休眠,中继上的预约也会到期。一张永不更新的地址簿,很快就会失效。 + +Maka 让节点发布带签名的 **reachability lease(可达性租约)**:它包含 PeerId、版本、有效期,以及当前可尝试的直连地址和协调中继地址。接收方验证身份、版本和期限后,才把它当作新的连接线索。重复收到同一份记录,不会重新延长它的有效期。 + +成员会相互交换新记录。实现采用点对点的增量核对:比较已知版本,补齐缺失或更新的信息;地址变化、连接恢复等事件会唤醒同步,周期性检查负责补漏。它服务于小规模 Mesh 的状态收敛,无需让每条业务消息都参与全网广播。[^reachability] + +因此,“暂时找不到这个节点”和“它已经不属于 Mesh”是两种状态。旧地址失效后,Maka 仍保留成员关系,并尝试从其他成员或曾经成功使用的中继取得新线索。记住的是中继地址,不是把上次的预约当作仍然有效。 + +恢复也有物理边界:如果两端的地址都变了,没有任何旧路径可用,也没有第三方知道新位置,仅凭 PeerId 无法发出第一包数据。此时会进入 `needs_repair`,通过新邀请等方式补充连接线索,保留原来的身份和成员关系。 + +若未来要保证长时间离线后仍能随时找回彼此,就需要选择稳定的会合服务及其运维方式。地址发现的可用性,需要有人提供;密码学身份本身不能代替它。[^recovery] + +## 直连之外,成员可以帮彼此接通 + +普通家庭和移动网络通常隔着 NAT。设备能主动访问外部,不代表外部可以直接连进来。两端需要先交换连接线索,再尝试建立可用路径。 + +Maka 的原生 peer 端点基于 Rust/libp2p,支持 QUIC、TCP 等连接路径,并使用 DCUtR 协调打洞。WebRTC ICE 提供另一种直连机会:在一些原路径无法打通的网络中尝试不同的候选地址。它们共用业务端点的 PeerId,建立路径后仍承载同一套 Runtime Host 协议。[^transport] + +这里有两种用途不同的中继: + +- **协调中继**帮助节点相遇、交换控制信息和协商直连。外部公共中继属于这一类,不承载 Runtime Host 的应用流量。 +- **成员转发**由 Mesh 内的节点明确开启。在直连不可用时,它可以为获准成员承载应用流量。 + +下面展示的是可选路径。虚线表示协调信息,实线表示应用流量;实际连接只使用符合条件的路径。 + +```mermaid +flowchart TD + coordination["外部协调中继"] -.->|"协商连接"| client["客户端 A"] + coordination -.->|"协商连接"| host["Host B"] + client <-->|"直连"| host + client <-->|"加密流量"| transit["开启转发的成员 C"] + transit <-->|"加密流量"| host +``` + +成员转发默认关闭,由操作者为选定的 Mesh 开启。当前限制为一跳,并约束连接数量、持续时间和流量。客户端与目标 Host 之间保持端到端认证和加密,转发方不取得应用明文或操作目标 Host 的权限。[^transit] + +建立连接时,已有地址可以立即尝试,新发现的地址继续加入同一次连接尝试。候选路径共用目标身份、截止时间和取消信号,胜出后丢弃迟到结果。竞争的是建立连接的方式,不会把同一条业务命令分别发到多条路径上执行。[^dialing] + +直连与成员转发都不可用时,连接会失败。Peer Mesh 增加可用的路径,并没有消除所有网络拓扑的限制。 + +## 换了路径,任务和权限仍有自己的边界 + +一次短暂换路不一定要让上层会话重新开始。Maka 在 peer 字节流上记录发送位置和确认位置,保留有界的待确认数据。接上新路径后,可以补发尚未确认的字节,并在接收端去重,让原来的逻辑连接继续工作。 + +这是同一进程内、有时间和内存边界的传输恢复。接回来的流还必须匹配原来的 peer 与认证身份。Host 重启后,需要重新认证和建立会话订阅;结果未知的业务操作不能靠网络层自动重放。[^continuity] + +网络接通后,目标 Host 仍要验证凭据、目标数据根身份,并检查每项操作的权限。Mesh 邀请授予的是网络成员资格;共享某个 Session,要走该 Session 自己的授权流程。 + +撤销 Session 共享,不会把对方逐出整个 Mesh。移出 Mesh,也不会自动撤销对方可能通过 SSH 等其他路径使用的 Host 凭据。网络成员管理和资源授权可以各自变化,应用才能把协作范围精确到一项任务。[^authorization] + +## 这层基础,能让 Maka 走向哪里 + +Peer Mesh 当前提供的主要是“认得出、找得到、连得上,并能在一定条件下恢复”。节点之间能够通信之后,更大的设计空间在于:**用户可以围绕工作选择能力,而不必始终围绕一台机器安排工作。** + +以下是这层基础值得继续支撑的三个方向。 + +### 从多个安装实例,到个人工作网络 + +一个人可能在笔记本上交互,让家中的 Host 执行长任务,再从另一台设备回来查看和处理审批。已有的远程 Host、会话协议和 Peer Mesh,已经为这种使用方式提供了基础。 + +未来的客户端可以进一步成为轻入口:知道用户有哪些获准访问的 Host,记住任务归属,自动使用当前可用的连接路径。需要改进的是跨设备的任务发现、身份衔接和离线体验;不能把任务列表里的一行缓存,当作任务仍在运行的证明。 + +这个方向可以先用一个具体场景验证:同一任务经历客户端休眠、网络切换和另一端接入后,仍能找到正确的 Host、恢复进度并接上待处理的交互,而不用重新配对或重新发起任务。 + +### 从选择机器,到组合不同节点的能力 + +有的机器适合构建,有的接着本机应用,有的可以提供模型推理服务。一项工作需要这些能力时,未来的 Maka 可以根据能力把请求送到合适的节点。 + +Client Capability 已经允许 Host 使用客户端提供的工具。下一步的空间,是把这种明确授权的调用扩展成可发现、可选择的能力网络。当前 Mesh 的成员信息描述身份、端点类型和是否提供转发,还不是工具或算力目录;能力发现、版本、可用性、配额和授权需要另外设计。 + +下面描绘的是未来可能的工作流,虚线表示尚需完善的跨节点编排: + +```mermaid +flowchart TD + task["任务:完成并验证一个修改"] --> owner["负责这轮工作的 Host"] + owner -.->|"委派构建"| build["有合适环境的构建 Host"] + owner -.->|"请求本机操作"| client["用户的客户端"] + owner -.->|"请求协作"| collaborator["获准参与的协作者"] +``` + +关键是,能力可以被远程调用,权限仍由提供方决定。扩展的第一步可以是一种具体能力:让远端构建完成后带回可核对的结果,并验证断线、取消和重复请求都不会让同一次构建失去归属。网络负责送达,能力协议负责定义执行承诺。 + +### 从共享会话,到跨 Host 的任务协作 + +目前的 Session 共享让别人参与某个 Host 上的任务。更进一步,团队中的多个 Host 可以各自承担子任务:一个构建和测试,一个处理特定环境中的验证,再把结果交回负责整轮工作的 Host。 + +这与在一台 Host 内启动多个子 Agent 有不同的难点。节点可能独立离线,结果可能延迟到达,任务可能已经取消而远端还在执行。跨 Host 协作需要持久的委派记录、明确的执行者、结果来源和取消规则。Peer Mesh 提供连接,但不会自动生成这套调度语义,也不会把不同 Host 的 State Root 复制成同一份状态。 + +值得先跑通的是一个小而完整的协作闭环:两台 Host 委派和完成一项子任务,中途切断网络,再确认执行不会重复、结果能够核对、权限仍限制在获准范围内。这个闭环成立后,才有依据把同样的约定扩展到更多节点。 + +Peer Mesh 的长期价值,会体现在这些工作流里:设备保留自己的数据与权限,任务却可以使用分散在不同节点上的能力。Maka 的协作边界,也就有机会从一个客户端、一台 Host,扩展到一张可参与工作的网络。 + +## 实现参考 + +当前机制对应仓库提交 [`8d5c4612`](https://github.com/apache/maka/commit/8d5c4612c46b19270f00fe7aea33c39dff23dbe5)。未来方向是基于这些机制的设计推演,不代表已完成的产品功能。 + +[^scope]: [Peer Mesh 的范围、阶段与边界](https://github.com/apache/maka/issues/3842);[客户端与 Host 的 Mesh 组件](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/owner.ts)。 +[^membership]: [签名成员名册与成员声明](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/model.ts)、[邀请、加入和成员管理](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/node.ts)、[当前规模限制](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/limits.ts)。 +[^reachability]: [可达性租约及重复记录的时效处理](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-reachability/model.ts)、[持久发布版本](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-reachability/publisher.ts)、[成员间的增量同步](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/peer-mesh/node.ts)。 +[^recovery]: [可达性恢复的条件与设计](https://github.com/apache/maka/issues/4554)、[恢复已有成员的连接](https://github.com/apache/maka/pull/4893)、[中继锚点存储](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/native/runtime-host-peer/src/engine/relay_anchor_store.rs)。 +[^transport]: [原生连接实现](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/native/runtime-host-peer/src/engine.rs)、[WebRTC 接入与目标身份校验](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/native/runtime-host-peer/src/webrtc_direct/upgrade.rs);[WebRTC 的实验依据与覆盖边界](https://github.com/apache/maka/issues/4382)。 +[^transit]: [受控单跳转发](https://github.com/apache/maka/pull/4142)、[转发策略收敛](https://github.com/apache/maka/pull/4144)、[操作与诊断](https://github.com/apache/maka/pull/4147)。 +[^dialing]: [在同一次连接尝试中恢复可用路由](https://github.com/apache/maka/pull/4580)、[peer 客户端](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/client/peer-client.ts)。 +[^continuity]: [可恢复字节流](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/transport/resumable-peer-stream.ts)、[恢复时的凭据与身份校验](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/peer-listener.ts);[路径切换与逻辑连接](https://github.com/apache/maka/pull/4830)。 +[^authorization]: [Mesh 与资源共享的独立范围](https://github.com/apache/maka/issues/3842)、[共享会话访问的生命周期](https://github.com/apache/maka/pull/4907)、[客户端能力调用](https://github.com/apache/maka/blob/8d5c4612c46b19270f00fe7aea33c39dff23dbe5/packages/runtime-host/src/server/client-capability-invocation-broker.ts)。 From d651051fc478f7cfb728cb9a211dcdd2c53fa9af Mon Sep 17 00:00:00 2001 From: Wang Date: Wed, 9 Sep 2026 15:23:48 +0800 Subject: [PATCH 4/4] docs(blog): remove validation proposals from Peer Mesh outlook Generated-by: OpenAI Codex --- docs/blogs/peer-mesh.md | 6 +----- docs/blogs/peer-mesh.zh-CN.md | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/docs/blogs/peer-mesh.md b/docs/blogs/peer-mesh.md index 834061eae9..fefa8044d8 100644 --- a/docs/blogs/peer-mesh.md +++ b/docs/blogs/peer-mesh.md @@ -122,8 +122,6 @@ A person might interact on a laptop, leave a long task running on a Host at home Future clients could become lighter entry points: discover the Hosts a user is authorized to access, remember where each task belongs, and use whichever connection path is currently available. Cross-device task discovery, identity continuity, and offline experience still need work. A cached row in a task list cannot establish that the task is still running. -A concrete first test would be one task surviving client sleep, a network change, and access from another client: find the correct Host, recover progress, and pick up pending interactions without pairing again or submitting the task again. - ### From Choosing a Machine to Combining Capabilities One machine may be suited to builds, another may have local applications attached, and another may offer model inference. A future Maka could route requests to suitable nodes according to the capabilities a task needs. @@ -140,7 +138,7 @@ flowchart TD owner -.->|"Request collaboration"| collaborator["Authorized collaborator"] ``` -A capability can be called remotely while its provider retains permission to decide what it will execute. One concrete capability is enough for a first step: return a verifiable result from a remote build, then establish that disconnection, cancellation, and repeated requests do not leave that build without an accountable executor. The network delivers messages; the capability protocol defines the execution commitment. +A capability can be called remotely while its provider retains permission to decide what it will execute. The network delivers messages; the capability protocol defines the execution commitment. ### From Shared Sessions to Tasks Across Hosts @@ -148,8 +146,6 @@ Session sharing currently lets another person participate in work on a particula This has different failure modes from spawning several subagents within one Host. Nodes can go offline independently, results can arrive late, and a remote task can still be running after cancellation. Cross-Host collaboration needs durable delegation records, explicit executors, result provenance, and cancellation rules. Peer Mesh supplies connectivity; it does not create those scheduling semantics or replicate different Hosts' State Roots into one shared state. -A useful first proof is a small, complete collaboration cycle: delegate and finish one subtask across two Hosts, interrupt the network, then establish that execution is not duplicated, results can be verified, and permissions remain within the grant. Once that cycle works, the same contract has a basis for extending to more nodes. - The long-term value of Peer Mesh lies in these workflows. Devices retain their data and permissions while tasks use capabilities distributed across them. Maka's scope of collaboration can then grow from one client and one Host into a network of participants able to contribute to the work. ## Implementation References diff --git a/docs/blogs/peer-mesh.zh-CN.md b/docs/blogs/peer-mesh.zh-CN.md index 49b5217133..0b20855e48 100644 --- a/docs/blogs/peer-mesh.zh-CN.md +++ b/docs/blogs/peer-mesh.zh-CN.md @@ -122,8 +122,6 @@ Peer Mesh 当前提供的主要是“认得出、找得到、连得上,并能 未来的客户端可以进一步成为轻入口:知道用户有哪些获准访问的 Host,记住任务归属,自动使用当前可用的连接路径。需要改进的是跨设备的任务发现、身份衔接和离线体验;不能把任务列表里的一行缓存,当作任务仍在运行的证明。 -这个方向可以先用一个具体场景验证:同一任务经历客户端休眠、网络切换和另一端接入后,仍能找到正确的 Host、恢复进度并接上待处理的交互,而不用重新配对或重新发起任务。 - ### 从选择机器,到组合不同节点的能力 有的机器适合构建,有的接着本机应用,有的可以提供模型推理服务。一项工作需要这些能力时,未来的 Maka 可以根据能力把请求送到合适的节点。 @@ -140,7 +138,7 @@ flowchart TD owner -.->|"请求协作"| collaborator["获准参与的协作者"] ``` -关键是,能力可以被远程调用,权限仍由提供方决定。扩展的第一步可以是一种具体能力:让远端构建完成后带回可核对的结果,并验证断线、取消和重复请求都不会让同一次构建失去归属。网络负责送达,能力协议负责定义执行承诺。 +关键是,能力可以被远程调用,权限仍由提供方决定。网络负责送达,能力协议负责定义执行承诺。 ### 从共享会话,到跨 Host 的任务协作 @@ -148,8 +146,6 @@ flowchart TD 这与在一台 Host 内启动多个子 Agent 有不同的难点。节点可能独立离线,结果可能延迟到达,任务可能已经取消而远端还在执行。跨 Host 协作需要持久的委派记录、明确的执行者、结果来源和取消规则。Peer Mesh 提供连接,但不会自动生成这套调度语义,也不会把不同 Host 的 State Root 复制成同一份状态。 -值得先跑通的是一个小而完整的协作闭环:两台 Host 委派和完成一项子任务,中途切断网络,再确认执行不会重复、结果能够核对、权限仍限制在获准范围内。这个闭环成立后,才有依据把同样的约定扩展到更多节点。 - Peer Mesh 的长期价值,会体现在这些工作流里:设备保留自己的数据与权限,任务却可以使用分散在不同节点上的能力。Maka 的协作边界,也就有机会从一个客户端、一台 Host,扩展到一张可参与工作的网络。 ## 实现参考