mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-11-09 20:07:43 +08:00
Merge pull request #7856 from deepseek-harness/docs/liveshare-surface-accuracy
docs(liveshare): state the viewer tool surface the code enforces
This commit is contained in:
@@ -9,11 +9,11 @@
|
||||
en: f6144f8e81359a9c
|
||||
zh: 1924869ac7475b59
|
||||
/liveshare/share-modes:
|
||||
en: 08ce9269b4556bdd
|
||||
zh: 7b0e6e74e2f60865
|
||||
en: 17b6227cb7294e69
|
||||
zh: cea4a9064b3d5655
|
||||
/liveshare/forks-and-their-ceiling:
|
||||
en: 357a2147f48f5bac
|
||||
zh: a8a297603f984ede
|
||||
en: 7174fa32aa611279
|
||||
zh: e85e8142a0e9e650
|
||||
/liveshare/retries-recovery-and-revocation:
|
||||
en: 6b1346e73ab6eab9
|
||||
zh: 888cfc08c6bc8522
|
||||
|
||||
@@ -16,11 +16,11 @@ The plugin manager lists the card under **Experimental plugins** only while at l
|
||||
|
||||
## Share modes
|
||||
|
||||
`ViewerSessionMode` has two tiers, and both name a sandbox: `view` reads the shared Session and drives its loop inside a read-only sandbox in the granted workspace, so it never writes a file; it may use the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`) and the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), with every declared path checked against the grant. Both tiers also admit the PTC transport `run_code`: the program runs under the owner's standing file policy rather than the share tier, so it can read and write outside the grant, while its nested tool calls still pass the same guard and path checks. `write` runs in a bounded writable sandbox that also modifies files inside that workspace by adding bounded `edit` and `write`, under the Host's write ceiling. Forking is not a tier: the share carries its own `allowsFork` switch, independent of the tier. Attachment upload is not a tier either: every Session a share serves the reader accepts files, whatever the tier and the fork switch. The withdrawn `fork-readonly` name is not read back as `view`: a persisted owner record that names it is rejected when the owner state loads. Nothing infers `write`, and a share whose mode the host cannot establish stays readable but is never driven.
|
||||
`ViewerSessionMode` has two tiers, and both name a sandbox: `view` reads the shared Session and drives its loop inside a read-only sandbox in the granted workspace, so its file tools never write; it may use the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`) and the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), with every declared path checked against the grant. Both tiers also admit the PTC transport `run_code`: the program runs under the owner's standing file policy rather than the share tier, so it can read and write outside the grant, while its nested tool calls still pass the same guard and path checks. `write` runs in a bounded writable sandbox that also modifies files inside that workspace by adding bounded `edit` and `write`, under the Host's write ceiling. Forking is not a tier: the share carries its own `allowsFork` switch, independent of the tier. Attachment upload is not a tier either: every Session a share serves the reader accepts files, whatever the tier and the fork switch. The withdrawn `fork-readonly` name is not read back as `view`: a persisted owner record that names it is rejected when the owner state loads. Nothing infers `write`, and a share whose mode the host cannot establish stays readable but is never driven.
|
||||
|
||||
## Forks and their ceiling
|
||||
|
||||
A fork creates a new Session the viewer owns and leaves the source untouched. Fork authorization checks the share, its fork switch, expiry, viewer admission, source identity, and the requested boundary. `READ_ONLY_FORK_CEILING` permits the view surface — `read`, `read_image`, `glob`, `grep`, `present`, `todo_write`, `skill`, `web_search`, `web_fetch` — and `WRITE_FORK_CEILING` adds the Host’s bounded `edit` and `write`. Each path-bearing tool gets a confined replacement that resolves every declared path against the granted root and delegates with its canonical form; `bash`, `pwsh`, `cua`, `plugin_manager`, the `schedule_*` tools, and every name the surface does not list are refused.
|
||||
A fork creates a new Session the viewer owns and leaves the source untouched. Fork authorization checks the share, its fork switch, expiry, viewer admission, source identity, and the requested boundary. `READ_ONLY_FORK_CEILING` permits the view surface — `read`, `read_image`, `glob`, `grep`, `present`, `todo_write`, `skill`, `web_search`, `web_fetch` — admits the PTC transport `run_code`, and `WRITE_FORK_CEILING` adds the Host’s bounded `edit` and `write`. Each path-bearing tool gets a confined replacement that resolves every declared path against the granted root and delegates with its canonical form; `bash`, `pwsh`, `cua`, `plugin_manager`, the `schedule_*` tools, and every other name is refused.
|
||||
|
||||
Each child is recorded with the share that authorized it, the trusted viewer the Liveshare server asserted, and the boundary it started from, so a viewer's list shows only its own children and a removed share stops them. A child is driven only after its ceiling is installed on its own scope: `ForkRegistry` refuses every prompt for a child whose guard is not installed (`fork-ceiling-uninstalled`), and installation is verified per child rather than per host. A child whose scope refuses the confined replacement or the limit is refused instead of being published with the deployment's own tools.
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
## 分享模式
|
||||
|
||||
`ViewerSessionMode` 只有两档,两档都对应一个沙箱:`view` 读取共享会话,并在授予工作区的只读沙箱里驱动它的 loop,绝不写文件;它可以使用读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)和无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`),每个声明路径都按授予范围检查。`write` 在受宿主写入上限约束的可写沙箱里运行,通过有界 `edit` 与 `write` 修改该工作区内的文件。fork 不是一档:分享自带独立的 `allowsFork` 开关,与档位无关。附件上传也不是一档:分享向读者提供的每条会话都接受文件,与档位和分叉开关无关。已退场的 `fork-readonly` 名称不会读回为 `view`:持久化的 owner 记录若写有该值,owner 状态加载时会直接拒绝。任何环节都不会推断出 `write`,而宿主机无法确定模式的分享仍可读取,但绝不会被驱动。两档也都准入 PTC 传输工具 `run_code`:程序运行在所有者自己的常驻文件策略下而不是分享档位下,因此可以读写授权范围之外的文件;它发起的嵌套工具调用仍走同样的守卫与路径检查。
|
||||
`ViewerSessionMode` 只有两档,两档都对应一个沙箱:`view` 读取共享会话,并在授予工作区的只读沙箱里驱动它的 loop,其文件工具绝不写入;它可以使用读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)和无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`),每个声明路径都按授予范围检查。`write` 在受宿主写入上限约束的可写沙箱里运行,通过有界 `edit` 与 `write` 修改该工作区内的文件。fork 不是一档:分享自带独立的 `allowsFork` 开关,与档位无关。附件上传也不是一档:分享向读者提供的每条会话都接受文件,与档位和分叉开关无关。已退场的 `fork-readonly` 名称不会读回为 `view`:持久化的 owner 记录若写有该值,owner 状态加载时会直接拒绝。任何环节都不会推断出 `write`,而宿主机无法确定模式的分享仍可读取,但绝不会被驱动。两档也都准入 PTC 传输工具 `run_code`:程序运行在所有者自己的常驻文件策略下而不是分享档位下,因此可以读写授权范围之外的文件;它发起的嵌套工具调用仍走同样的守卫与路径检查。
|
||||
|
||||
## fork 与其上限
|
||||
|
||||
fork 创建查看者拥有的新会话,源会话保持不变。Fork 授权检查分享、其 fork 开关、有效期、查看者准入、源身份与请求的边界。`READ_ONLY_FORK_CEILING` 允许读取与检索面——`read`、`read_image`、`glob`、`grep`、`present`、`todo_write`、`skill`、`web_search`、`web_fetch`——,`WRITE_FORK_CEILING` 增加 Host 的有界 `edit` 与 `write`。每个带路径的工具都有受限替代定义:解析它声明的所有路径并按授予根目录检查,再以规范路径委托;`bash`、`pwsh`、`cua`、`plugin_manager`、`schedule_*` 及工具面未列出的名字一律拒绝。
|
||||
fork 创建查看者拥有的新会话,源会话保持不变。Fork 授权检查分享、其 fork 开关、有效期、查看者准入、源身份与请求的边界。`READ_ONLY_FORK_CEILING` 允许读取与检索面——`read`、`read_image`、`glob`、`grep`、`present`、`todo_write`、`skill`、`web_search`、`web_fetch`——并放行 PTC 传输工具 `run_code`,`WRITE_FORK_CEILING` 增加 Host 的有界 `edit` 与 `write`。每个带路径的工具都有受限替代定义:解析它声明的所有路径并按授予根目录检查,再以规范路径委托;`bash`、`pwsh`、`cua`、`plugin_manager`、`schedule_*` 及其他任何未列出的名字一律拒绝。
|
||||
|
||||
每个分叉会话都会记录授权它的分享、Liveshare 服务端断言的可信 viewer,以及它起始的边界,因此 viewer 的列表只显示它自己的分叉会话,被移除的分享会终止它们。只有在分叉会话自身作用域上安装好上限之后它才会被驱动:`ForkRegistry` 会拒绝每个上限未安装的分叉会话的 prompt(`fork-ceiling-uninstalled`),且安装是按分叉会话逐个验证,而非按宿主机验证。若分叉会话作用域拒绝注册受限替换或上限,就拒绝该分叉会话,而不是让它带着部署自身的工具发布。
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
en: a23d0162e0efa6a4
|
||||
zh: 0d01659cfeb94640
|
||||
/deepseek-ai-dsh-experimental-liveshare/use-this-package/session-tiers:
|
||||
en: 62d37a34f9fc1e21
|
||||
zh: 28425dcde15fbcdc
|
||||
en: 77301142e621a96a
|
||||
zh: 2afe3fc6d274675e
|
||||
/deepseek-ai-dsh-experimental-liveshare/understand-the-implementation:
|
||||
en: ba036437349dcd6a
|
||||
zh: 12c2176aa91c3427
|
||||
en: 74c336962ca47ab5
|
||||
zh: ae3628a038bd4791
|
||||
/deepseek-ai-dsh-experimental-liveshare/further-exploration:
|
||||
en: 0570170704bbe5b6
|
||||
zh: 832f86024b26e5b3
|
||||
@@ -45,8 +45,8 @@
|
||||
en: 22a9da7d4b23a015
|
||||
zh: 5700901ba5f655c8
|
||||
/deepseek-ai-dsh-experimental-liveshare/known-limitations-and-deferred-work:
|
||||
en: 0c3f37a37d262898
|
||||
zh: 3eb4d3ccf73ff267
|
||||
en: f869e5ce246876e7
|
||||
zh: 3a2464f5a292e837
|
||||
/deepseek-ai-dsh-experimental-liveshare/known-limitations-and-deferred-work/dev-note:
|
||||
en: e67f633dc6fe7773
|
||||
zh: 8ec3e73528ddb1a6
|
||||
|
||||
@@ -79,6 +79,8 @@ The owner admits viewers by organization link; the deployment's `LIVESHARE_ALLOW
|
||||
|
||||
### Session tiers
|
||||
|
||||
<a id="session-tiers"></a>
|
||||
|
||||
| Tier | Viewer actions | Execution limit |
|
||||
|---|---|---|
|
||||
| `view` | Prompt the source Session and stop its running turn | Read-only sandbox mounted on the Session, applied to every turn a share viewer starts: that turn may use the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), and the PTC transport `run_code`; every path a call declares is checked against the granted workspace |
|
||||
@@ -91,7 +93,7 @@ Both tiers drive the shared Session; what separates them is writing. The sandbox
|
||||
Attachment uploads are neither a tier nor part of the fork switch: they follow visibility. An admitted viewer may attach uploaded files to the shared Session and to the forks it created through this share, whichever tier the share carries and whether or not it allows forking. The owner has no separate attachment switch.
|
||||
|
||||
|
||||
Shareable viewer methods come from installed plugins' live Remote methods, enumerated from the Host's Typert registry in [`shareable-catalog.ts`](src/host/shareable-catalog.ts). DSH core namespaces (Session, Workspace, terminal, settings, credentials, plugin management, LiveShare management) are excluded; user-installed plugins and DSH experimental plugins remain. The owner may open every installed plugin at once, or set each plugin to none, all its methods, or a subset. There is no read/write distinction: a method is callable only where the live catalog and that share's own policy name it, on the resources the reader can see.
|
||||
Shareable viewer methods come from installed plugins' live Remote methods, enumerated from the Host's Typert registry in [`shareable-catalog.ts`](src/host/shareable-catalog.ts). DSH core service namespaces are excluded ([`EXCLUDED_SHARE_NAMESPACES`](src/host/shareable-catalog.ts) lists them), and so are components of a core profile bundle as the plugin manager reports them; other user-installed and DSH experimental plugins remain. The owner may open every installed plugin at once, or set each plugin to none, all its methods, or a subset. There is no read/write distinction: a method is callable only where the live catalog and that share's own policy name it, on the resources the reader can see.
|
||||
|
||||
The Owner Gateway decides each call on the Session and Workspace it names and refuses a call whose target is missing or invalid. The viewer's Session list and workspace membership are trimmed to the source and the children that viewer owns. The page reads each Session's own answer from the reader's access snapshot, so a selection change never carries the previous Session's permission across. Unknown or unreadable modes fail closed. The Owner rechecks admission for source and child calls; revocation cancels the affected calls and streams, and a share whose admission narrows stops the shared Session's running turn. The page distinguishes authentication, access, expiry, stopped shares, offline owners, and transport failures, and retries only the failures classified as repeatable.
|
||||
|
||||
@@ -107,7 +109,7 @@ The viewer page is the Owner's own Web shell. The Liveshare server fetches the O
|
||||
|
||||
Fork requests bind the actor, share, source, operation identity, and completed prefix. A durable reservation and the recorded child let a retry of a recorded operation replay the same child; the owner's `SessionForkRequest` mints the child id, so a request interrupted after the child was created but before it was recorded forks again. Registry mutations are asynchronous and resolve only after locked read-modify-write and atomic publication; callers must await reservation, recording, and revocation. Cold activation uses the Host’s ordinary Agent lookup, with serial `agent/created` enforcement before queued input can run, not a Remote `session/prepare` endpoint. The child scope retains one fail-closed guard; reconnection replaces its enforcement installation, and releasing an old installation cannot remove its successor.
|
||||
|
||||
A reader's prompt reaches the Session as a `user-rpc` message whose `source.principal` names that reader, and the pre-step re-checks every entering message's viewer against the Relay's admission before it reaches the model. Execution is confined per turn: while any share over the Session is active, a turn whose admitted input names a share viewer runs the Host's confined replacements for the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), for the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), and, when some share may write, its bounded `edit` and `write`. Every other tool is refused to that turn, and every path a permitted call declares is resolved and checked against the granted root. An owner-started turn keeps the Session's native tools until the last share stops or expires. The turn decision is Host memory only, recomputed for each turn and never appended to the Session log. Each operation re-reads the shares' current Relay grants and checks the resolved target against the granted root. A reader's stop is dispatched through the Gateway like a prompt: the `share-viewer` policy admits it while the share's tier is established and the Session is confined, and the owner's own Session controller stops whatever turn the Session is running, including one the owner started. Reads and writes preserve the normal write-observation policy. See the [LiveShare subsystem](../../../docs/subsystems/liveshare.md) for the execution rules.
|
||||
A reader's prompt reaches the Session as a `user-rpc` message whose `source.principal` names that reader, and the pre-step re-checks every entering message's viewer against the Relay's admission before it reaches the model. Execution is confined per turn: while any share over the Session is active, a turn whose admitted input names a share viewer runs the Host's confined replacements for the read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), keeps the deployment's own definitions of the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), admits the PTC transport `run_code` from the selected executor, and, when some share may write, its bounded `edit` and `write`. Every other tool is refused to that turn, and every path a permitted call declares is resolved and checked against the granted root. An owner-started turn keeps the Session's native tools until the last share stops or expires. The turn decision is Host memory only, recomputed for each turn and never appended to the Session log. Each operation re-reads the shares' current Relay grants and checks the resolved target against the granted root. A reader's stop is dispatched through the Gateway like a prompt: the `share-viewer` policy admits it while the share's tier is established and the Session is confined, and the owner's own Session controller stops whatever turn the Session is running, including one the owner started. Reads and writes preserve the normal write-observation policy. See the [LiveShare subsystem](../../../docs/subsystems/liveshare.md) for the execution rules.
|
||||
|
||||
| Owner | Source |
|
||||
|---|---|
|
||||
@@ -154,8 +156,8 @@ Viewer prompts enter the shared Session as ordinary user input, so they extend t
|
||||
|
||||
- Owner, viewer, and the Liveshare server require matching versions; cross-version compatibility is not established.
|
||||
- The owner cannot refuse attachment uploads for an admitted viewer: a viewer that may read a Session may also attach files to it, independent of the tier and of the fork switch. This is an accepted risk.
|
||||
- Viewer file operations are confined by a path check against the granted root, so a local process that swaps a directory inside the grant for a symlink between the check and the open can redirect them; directory-handle anchoring is deferred to a separate change. Viewer tools are limited to the confined read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), and, at the write tier, bounded `edit` and `write`; `bash`, `pwsh`, `cua`, `plugin_manager`, the `schedule_*` tools, and every tool that surface does not name are not granted.
|
||||
- The viewer has no separate workspace-file editing interface and no management authority.
|
||||
- Viewer file operations are confined by a path check against the granted root, so a local process that swaps a directory inside the grant for a symlink between the check and the open can redirect them; directory-handle anchoring is deferred to a separate change. Viewer tools are limited to the confined read and search surface (`read`, `read_image`, `glob`, `grep`, `present`), the tools with no local file effect (`todo_write`, `skill`, `web_search`, `web_fetch`), the PTC transport `run_code`, and, at the write tier, bounded `edit` and `write`; `bash`, `pwsh`, `cua`, `plugin_manager`, the `schedule_*` tools, and no other name is granted. A `run_code` program is not bounded by the share: [Session tiers](#session-tiers) states what its program may reach.
|
||||
- The viewer has no separate workspace-file editing interface and no DSH core management authority; an installed plugin the owner opens can still change what that plugin owns.
|
||||
- Endpoint capabilities enumerate installed plugins' Remote methods from the live Typert registry in [`shareable-catalog.ts`](src/host/shareable-catalog.ts); DSH core service namespaces are excluded. There is no sandbox around a method call and no read/write classification: granting a method trusts that installed plugin's code, which runs in the Host process. A selected method is callable by every authenticated share viewer on the resources the policy binds, across the `global`, `session`, and `workspace` resource kinds.
|
||||
- The owner selects installed-plugin methods in the share panel through a global switch and per-plugin rows. The global switch is `none` (open nothing), `custom` (follow the per-plugin list), or `all` (open every method the live catalog offers). Each plugin is then off, all its methods, or a subset; a partial selection stores an explicit method list, so methods the catalog adds later stay closed until the owner saves again. Plugin rows use the package's localized title when one exists and otherwise fall back to the package segment or namespace; search and bounded scrolling keep a large catalog usable. The selection is share-wide: every admitted viewer may call a selected method on the resources the policy binds, and per-viewer method levels are not established. Method authorization is independent of the session tier; the core share roles still decide Session and Workspace calls. A selection naming a method the catalog no longer offers exposes nothing but stays stored until the owner saves again.
|
||||
- A Workspace that stops holding a Session the reader can see leaves the reader's Workspace feed only at that Workspace's or the Workspace order's next change ([remote access limitation](../../api/remote-access/README.md#known-limitations-and-deferred-work)).
|
||||
|
||||
@@ -79,6 +79,8 @@ Liveshare 服务端地址在首次使用时设置:在分享弹窗的地址输
|
||||
|
||||
### 会话档位
|
||||
|
||||
<a id="session-tiers"></a>
|
||||
|
||||
| 档位 | 查看者操作 | 执行限制 |
|
||||
|---|---|---|
|
||||
| `view` | 向源会话发送提示词,并停止其正在运行的轮次 | 挂在会话上的只读沙箱,只约束分享查看者发起的轮次:该轮次只能使用读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)、无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`),以及 PTC 传输工具 `run_code`;每次调用声明的每个路径都按获授工作区检查 |
|
||||
@@ -91,7 +93,7 @@ Liveshare 服务端地址在首次使用时设置:在分享弹窗的地址输
|
||||
附件上传既不是档位,也不属于分叉开关:它跟随可见性。无论分享处于哪个档位、是否允许分叉,已准入的查看者都可以向共享会话以及自己通过本分享分叉出的会话上传附件。所有者没有单独的附件开关。
|
||||
|
||||
|
||||
可分享给 viewer 的方法是已安装插件注册的 Remote 方法,由 Host 的 Typert registry 在 [`shareable-catalog.ts`](src/host/shareable-catalog.ts) 动态枚举。DSH 核心命名空间(Session、Workspace、terminal、settings、credentials、插件管理、LiveShare 管理)被排除;用户安装的插件和 DSH 实验性插件保留。所有者可以一次性开放全部已安装插件,也可以按插件设为不可用、全部方法或部分方法。这里没有读写之分:只有当前目录与该 share 的策略同时点名某个方法、且资源对读者可见时,该方法才可被调用。
|
||||
可分享给 viewer 的方法是已安装插件注册的 Remote 方法,由 Host 的 Typert registry 在 [`shareable-catalog.ts`](src/host/shareable-catalog.ts) 动态枚举。DSH 核心服务命名空间被排除([`EXCLUDED_SHARE_NAMESPACES`](src/host/shareable-catalog.ts) 列出这些命名空间),插件管理器报告为核心 profile bundle 组件的插件也被排除;其他用户安装的插件和 DSH 实验性插件保留。所有者可以一次性开放全部已安装插件,也可以按插件设为不可用、全部方法或部分方法。这里没有读写之分:只有当前目录与该 share 的策略同时点名某个方法、且资源对读者可见时,该方法才可被调用。
|
||||
|
||||
Owner Gateway 按调用指明的 Session 与工作区判定每次调用,并拒绝目标缺失或无效的调用。查看页的会话列表和工作区成员裁剪为源会话及该查看者自己的分叉会话。页面从读者的访问快照读取每个会话自己的答案,因此切换选择不会把前一会话的权限带过去。未知或无法读取的模式默认拒绝。Owner 为源会话与分叉会话调用重新检查准入;撤权会取消受影响的调用和流,分享准入收窄时还会停止共享会话正在运行的轮次。页面区分认证、访问、过期、停止分享、所有者离线和传输失败,仅重试明确分类为可重试的失败。
|
||||
|
||||
@@ -107,7 +109,7 @@ Owner Gateway 按调用指明的 Session 与工作区判定每次调用,并拒
|
||||
|
||||
Fork 请求绑定主体、分享、源会话、操作身份和已完成前缀。持久化预留记录与已记录的分叉会话使重试已记录的操作时重放同一分叉会话;owner 的 `SessionForkRequest` 自己生成分叉会话 id,因此在分叉会话已创建、但尚未记录时中断的请求会再次 fork。注册表变更为异步操作,仅在加锁的读取、修改与原子发布后完成;调用方必须等待预留、记录与撤销。冷态激活使用 Host 常规 Agent lookup,由串行 `agent/created` 在排队输入运行前安装限制,不使用 Remote `session/prepare` 端点。分叉会话作用域保留单个默认拒绝的 guard;重连替换其限制安装,释放旧安装不会移除继任。
|
||||
|
||||
读者的提示词以 `user-rpc` 消息进入会话,其 `source.principal` 指明该读者;pre-step 在每条进入消息到达模型前,按 Relay 的准入重新检查其查看者。执行按轮次受限:只要有分享处于活跃状态,已准入输入中带有 share-viewer principal 的轮次就运行 Host 挂载的读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)受限替代、无本地文件副作用工具(`todo_write`、`skill`、`web_search`、`web_fetch`)的替代,以及(当某个分享允许写入时)有界 `edit` 与 `write`。其余所有工具对该轮次一律拒绝,且每次允许的调用声明的每个路径都会解析并按获授根目录检查。所有者自己发起的轮次保留会话原生工具,直到最后一个分享停止或过期。该轮次判定只存在于 Host 内存,按轮次重算,不写入会话日志。每次操作都会重新读取分享当前的 Relay 授权,并按获授根目录检查解析后的目标。读者的停止与提示词一样经 Gateway 分派:`share-viewer` 策略在分享档位确立且会话受沙箱限制时放行,随后由所有者自己的会话控制器停止该会话当前运行的轮次,包括所有者发起的轮次。读写保留正常写入观察策略。执行规则见 [LiveShare 子系统](../../../docs/subsystems/liveshare.zh.md)。
|
||||
读者的提示词以 `user-rpc` 消息进入会话,其 `source.principal` 指明该读者;pre-step 在每条进入消息到达模型前,按 Relay 的准入重新检查其查看者。执行按轮次受限:只要有分享处于活跃状态,已准入输入中带有 share-viewer principal 的轮次就运行 Host 挂载的读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)受限替代、保留无本地文件副作用工具(`todo_write`、`skill`、`web_search`、`web_fetch`)的原生定义、放行选定执行器提供的 PTC 传输工具 `run_code`,以及(当某个分享允许写入时)有界 `edit` 与 `write`。其余所有工具对该轮次一律拒绝,且每次允许的调用声明的每个路径都会解析并按获授根目录检查。所有者自己发起的轮次保留会话原生工具,直到最后一个分享停止或过期。该轮次判定只存在于 Host 内存,按轮次重算,不写入会话日志。每次操作都会重新读取分享当前的 Relay 授权,并按获授根目录检查解析后的目标。读者的停止与提示词一样经 Gateway 分派:`share-viewer` 策略在分享档位确立且会话受沙箱限制时放行,随后由所有者自己的会话控制器停止该会话当前运行的轮次,包括所有者发起的轮次。读写保留正常写入观察策略。执行规则见 [LiveShare 子系统](../../../docs/subsystems/liveshare.zh.md)。
|
||||
|
||||
| 职责 | 源码 |
|
||||
|---|---|
|
||||
@@ -154,8 +156,8 @@ viewer 的 prompt 以普通用户输入进入共享会话,因此扩展的是
|
||||
|
||||
- Owner、查看页和 Liveshare 服务端需要匹配版本;尚未建立跨版本兼容保证。
|
||||
- 所有者无法拒绝已准入查看者的附件上传:能读取某条会话的查看者也可以向它附加文件,与档位和分叉开关无关。这是已接受的风险。
|
||||
- 查看者的文件操作按获授根目录做路径检查,若本地进程在检查与打开之间把获授范围内的目录换成符号链接,读写可能被改指别处;目录句柄锚定留待单独变更引入。查看者工具仅限受限的读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)、无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`),以及 write 档下的有界 `edit` 与 `write`;不授予 `bash`、`pwsh`、`cua`、`plugin_manager`、`schedule_*` 及该工具面未列出的任何工具。
|
||||
- 查看页没有独立工作区文件编辑界面,也没有管理权限。
|
||||
- 查看者的文件操作按获授根目录做路径检查,若本地进程在检查与打开之间把获授范围内的目录换成符号链接,读写可能被改指别处;目录句柄锚定留待单独变更引入。查看者工具仅限受限的读取与检索面(`read`、`read_image`、`glob`、`grep`、`present`)、无本地文件副作用的工具(`todo_write`、`skill`、`web_search`、`web_fetch`)、PTC 传输工具 `run_code`,以及 write 档下的有界 `edit` 与 `write`;不授予 `bash`、`pwsh`、`cua`、`plugin_manager`、`schedule_*` 及其他任何未列出的工具。`run_code` 程序不受分享范围约束,[会话档位](#session-tiers) 一节说明其程序可以触及什么。
|
||||
- 查看页没有独立工作区文件编辑界面,也没有 DSH 核心管理权限;所有者开放的已安装插件方法仍可改变该插件自己拥有的状态。
|
||||
- 端点能力从 Typert registry 枚举已安装插件的 Remote 方法(见 [`shareable-catalog.ts`](src/host/shareable-catalog.ts)),DSH 核心服务命名空间被排除。方法调用不经过沙箱,也没有读写分类:开放一个方法即信任该已安装插件的代码,它在 Host 进程中执行。被选中的方法会在 policy 绑定的资源上被任意已认证分享读者调用,覆盖 `global`、`session`、`workspace` 三种资源种类。
|
||||
- owner 在分享面板里通过全局开关和按插件行选择已安装插件的方法。全局开关为“不可用”(全部关闭)、“自定义”(按插件列表)或“全部允许”(开放当前目录全部方法)。每个插件再设为不可用、全部方法或部分方法;部分选择保存显式方法列表,因此目录之后新增的方法不会自动开放,直到 owner 再次保存。插件行优先显示包内本地化名称,取不到时回退到包名末段或 namespace;搜索与限高滚动让大目录仍可操作。选择是分享级的:每位已准入查看者都可以在 policy 绑定的资源上调用被选中的方法,尚未建立逐查看者方法级别。方法授权独立于会话档位,Session 与 Workspace 调用仍由核心分享角色决定。目录不再提供的方法即使留在记录里也不暴露。
|
||||
- 工作区不再包含读者可见的会话后,要到该工作区或工作区顺序下次变化时才离开读者的工作区订阅([remote access 限制](../../api/remote-access/README.zh.md#known-limitations-and-deferred-work))。
|
||||
|
||||
Reference in New Issue
Block a user