Skip to content

[Grok/dsh 16] 共享服务、多客户端与重连 #148

Closed

Description

@Blackman99

Parent

#132

Ticket: 16

Status: ready-for-agent

User Stories: 59, 60, 62(见父规格)

What to build

用户按需开启兼容服务,多个受认证客户端能观察同一会话,断线后重连而不重复执行工作。

Acceptance criteria

  • 兼容共享服务入口、连接认证和能力报告;默认本地启动不强制常驻服务,不意外监听公网。
  • 同一会话只有一个执行/写入者,选项变更与状态广播一致,竞争写入、失联与旧请求明确处理。
  • 保持沙箱与服务模式的已验证限制,不能通过另一个进程逃离权限;区分客户端断线与运行进程退出。
  • 真实多客户端完成回合、审批与重连场景,证明副作用不重复;文档及发布元数据同步。

Blocked by

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 24, 2026

    @Blackman99
    OwnerAuthor

    Ticket 16 / #148 已合入 rewrite/grok-dsh-20260920 的 6e717a4。这次是快进推送(091da92..6e717a4),没有强推。

    共享默认关闭:普通启动不起服务,也不开端口。执行仍由 dsh 完成,每个活跃会话对应一个 dsh 进程,各自有独立的权限策略文件。

    • codsh --rust agent serve:在带认证的 WebSocket 上提供 ACP(/ws,默认 127.0.0.1:2419,支持 --bind,端口可以是 0)。
      • 密钥来自 --secret、GROK_AGENT_SECRET,或自动生成的 12 位密钥,生成时打印一次。
      • 客户端可以用 Bearer 头或 ?server-key= 认证,比较是常数时间的。
      • 绑定非回环地址会打印警告。
    • codsh --rust agent leader:每个用户一个 leader,socket 是 $GROK_HOME/leader.sock(也可用 --leader-socket)。
      • socket 权限 0600,靠 flock 锁防止重复启动,只接受同 uid 的对端。
      • agent --leader stdio 或 [cli] use_leader = true 会自动启动或复用 leader;--no-leader 优先。
      • 启动时做版本检查。leader 断开时,等待中的请求会收到错误,并收到 _codsh/leader_disconnected,代理以 1 退出。
    • 多个客户端:对正在运行的会话做 session/load 或 resume 会直接附着,不会再起执行器。
      • 附着时会补发已保存的历史、正在运行的这一轮和待处理的审批。
      • 审批请求广播给所有客户端,第一个回答生效;其他客户端收到 _codsh/permission_resolved,迟到的回答收到 _codsh/stale_response。
      • 一轮进行中再发 prompt 会被拒绝,不排队。
      • 配置变更会广播为 config_option_update;一轮进行中只允许改 permission_mode。
      • 客户端断开不会取消正在进行的一轮。
    • dsh 意外退出时,发送 _codsh/runtime_exited,不重试;下次 load 会起新的 runtime。
    • codsh --rust leader list|info|kill(带 --json / --pid)用来查看和停止 leader。
    • 非 off 的沙箱配置会让会话留在编辑器自己的进程里,不进 leader(否决提示沿用参考文案)。leader 客户端不能自带模型或权限参数。
    • 收到 SIGINT、SIGTERM、SIGHUP 会先正常停止,再分别以 130、143、129 退出。

    验证(Linux x86_64,Node 22.19):

    • pnpm run typecheck:通过。
    • pnpm test:83 个文件,2300 通过、1 失败。失败的是 reference-evidence.spec.mjs 里的一个用例:它只解析录制好的证据,负载高时跑 5.9s,超过默认 5s 超时。单独用 --testTimeout=60000 跑,11/11 通过,和本改动无关。
    • 新增 scripts/rust-shared-server.spec.mjs,对真实 dsh 跑 3/3 通过,连续 3 次。覆盖:
      • WebSocket 认证 401/404/101
      • 两个客户端同时在一个会话里,忙时拒绝
      • 审批竞争,文件只被修改一次
      • 断线后重连补发审批
      • 杀掉 dsh 后服务仍存活
      • leader 自动启动、socket 0600、list/info/kill、闲置退出
      • leader 被杀后代理以 1 退出
      • 沙箱否决
    • scripts/rust-acp-protocol.spec.mjs:38/38 通过,含原有编辑器用例。
    • cargo fmt --check:通过。
    • cargo clippy -D warnings:失败,原因是 filesystem_sandbox.rs 里已有的两处问题(tail_marker 未使用、多余的 return,来自 ec9d6ae)。加 -A dead_code -A clippy::needless_return 后全部通过,本改动的代码没有警告。
    • cargo test --locked --workspace --no-fail-fast:456 + 498 + 42 + 61 + 2 + 379 通过,4 个失败,都不是本改动引入的:
      • filesystem_sandbox 的 2 个用例在 Linux 上被拒绝(需要 seccomp),是已有问题。
      • privacy::drafts_stay_local... 和 voice::substitute_route... 时好时坏。原因在测试里的假服务器:它只 read 一次,请求体分包到达时就会读丢。这两个文件没有改动。
      • 新增的 13 个 ws、shared_server 和解析相关单测全部通过。

    未验证:

    • macOS 和 Windows:leader 只支持 Unix,Windows 上会拒绝。
    • 所有 rust-*-pty-test.py:脚本要求 macOS 证据,在 Linux 上直接退出。
    • test:e2e。
    • 真实编辑器或图形界面。
    • 沙箱否决的端到端路径:这台机器上 workspace 配置本身无法生效,spec 只验证了启动时的拒绝,决策逻辑由单测覆盖。
    • 官方 relay、agent headless、--remote、--grok-ws-*、Cursor worker:依赖官方服务,已明确拒绝。
    • x.ai 命名的通知:改用 _codsh/* 命名空间,清单里已标注。
    • 付费模型。

    main、npm 发布和默认版本都没有改动,PR #213 也没有动。变更集是 .changeset/rust-dsh-shared-server.md(patch)。

    后续:#190(远程工作区连接与执行)现在不再被阻塞。

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions