dsh-plugin-dev-kb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +56 -0
- package/cordis.patch.yml +12 -0
- package/kb/INDEX.md +210 -0
- package/kb/README.md +69 -0
- package/kb/extra/AGENTS.md +75 -0
- package/kb/extra/api-gateway.md +164 -0
- package/kb/extra/api-gateway.zh.md +164 -0
- package/kb/extra/cookbook/adding-a-vendored-package.md +59 -0
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +59 -0
- package/kb/extra/cookbook/maintaining-dsh-code-review.md +64 -0
- package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +64 -0
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
- package/kb/extra/defensive-patterns.md +33 -0
- package/kb/extra/defensive-patterns.zh.md +33 -0
- package/kb/extra/development.md +171 -0
- package/kb/extra/development.zh.md +171 -0
- package/kb/extra/event-producer-consumer.md +76 -0
- package/kb/extra/event-producer-consumer.zh.md +78 -0
- package/kb/extra/glossary.md +45 -0
- package/kb/extra/glossary.zh.md +45 -0
- package/kb/extra/graph-atlas.md +24 -0
- package/kb/extra/graph-atlas.zh.md +26 -0
- package/kb/extra/i18n/README.md +60 -0
- package/kb/extra/i18n/README.zh.md +60 -0
- package/kb/extra/i18n/style-samples.md +87 -0
- package/kb/extra/i18n/terminology.md +214 -0
- package/kb/extra/i18n/translation-prompt.md +263 -0
- package/kb/extra/i18n/translation-rules.md +69 -0
- package/kb/extra/i18n/translation-rules.zh.md +69 -0
- package/kb/extra/module-graph.md +1641 -0
- package/kb/extra/module-graph.zh.md +1643 -0
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +113 -0
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
- package/kb/extra/postmortem/README.md +18 -0
- package/kb/extra/postmortem/README.zh.md +18 -0
- package/kb/extra/rescope.md +53 -0
- package/kb/extra/rescope.zh.md +53 -0
- package/kb/extra/subsystems/attachment.md +125 -0
- package/kb/extra/subsystems/attachment.zh.md +125 -0
- package/kb/extra/subsystems/extensions.md +364 -0
- package/kb/extra/subsystems/extensions.zh.md +364 -0
- package/kb/extra/subsystems/feedback.md +266 -0
- package/kb/extra/subsystems/feedback.zh.md +266 -0
- package/kb/extra/testing.md +49 -0
- package/kb/extra/testing.zh.md +49 -0
- package/kb/extra/web-styling.md +25 -0
- package/kb/extra/web-styling.zh.md +25 -0
- package/kb/meta/search-index.json +1328 -0
- package/kb/meta/site-pages.txt +168 -0
- package/kb/meta/source.json +13 -0
- package/kb/meta/topics.md +75 -0
- package/kb/site/develop/basic/config.md +108 -0
- package/kb/site/develop/basic/index.md +146 -0
- package/kb/site/develop/basic/publish.md +185 -0
- package/kb/site/develop/basic/tool.md +54 -0
- package/kb/site/develop/cordis-tutorial/01-first-plugin.md +95 -0
- package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
- package/kb/site/develop/cordis-tutorial/03-services.md +98 -0
- package/kb/site/develop/cordis-tutorial/04-events.md +144 -0
- package/kb/site/develop/cordis-tutorial/05-config.md +84 -0
- package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +107 -0
- package/kb/site/develop/cordis-tutorial/index.md +62 -0
- package/kb/site/develop/framework/events.md +145 -0
- package/kb/site/develop/framework/index.md +139 -0
- package/kb/site/develop/framework/service.md +152 -0
- package/kb/site/develop/practice/index.md +157 -0
- package/kb/site/develop/practice/llm-adapter.md +190 -0
- package/kb/site/en/develop/basic/config.md +108 -0
- package/kb/site/en/develop/basic/index.md +146 -0
- package/kb/site/en/develop/basic/publish.md +185 -0
- package/kb/site/en/develop/basic/tool.md +54 -0
- package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +95 -0
- package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
- package/kb/site/en/develop/cordis-tutorial/03-services.md +98 -0
- package/kb/site/en/develop/cordis-tutorial/04-events.md +144 -0
- package/kb/site/en/develop/cordis-tutorial/05-config.md +84 -0
- package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +107 -0
- package/kb/site/en/develop/cordis-tutorial/index.md +60 -0
- package/kb/site/en/develop/framework/events.md +145 -0
- package/kb/site/en/develop/framework/index.md +139 -0
- package/kb/site/en/develop/framework/service.md +150 -0
- package/kb/site/en/develop/practice/index.md +157 -0
- package/kb/site/en/develop/practice/llm-adapter.md +190 -0
- package/kb/site/en/guide/providers-custom-form.png +0 -0
- package/kb/site/en/guide/providers-models-page.png +0 -0
- package/kb/site/en/guide/providers.md +100 -0
- package/kb/site/en/guide/python-sdk.md +106 -0
- package/kb/site/en/guide/quickstart.md +32 -0
- package/kb/site/en/index.md +8 -0
- package/kb/site/en/reference/agent-lifecycle.md +86 -0
- package/kb/site/en/reference/capability-seams.md +475 -0
- package/kb/site/en/reference/config-catalog.md +3155 -0
- package/kb/site/en/reference/cookbook/adding-a-conversation-node.md +235 -0
- package/kb/site/en/reference/cookbook/adding-a-package.md +120 -0
- package/kb/site/en/reference/cookbook/adding-a-settings-card.md +102 -0
- package/kb/site/en/reference/cookbook/adding-a-tool.md +96 -0
- package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +45 -0
- package/kb/site/en/reference/cookbook/extension-cookbook.md +131 -0
- package/kb/site/en/reference/cordis-api/context.md +368 -0
- package/kb/site/en/reference/cordis-api/events.md +211 -0
- package/kb/site/en/reference/cordis-api/fiber.md +379 -0
- package/kb/site/en/reference/cordis-api/inherited.md +43 -0
- package/kb/site/en/reference/cordis-api/registry.md +156 -0
- package/kb/site/en/reference/cordis-api/service.md +106 -0
- package/kb/site/en/reference/cordis-primer.md +46 -0
- package/kb/site/en/reference/index.md +131 -0
- package/kb/site/en/reference/persistence-catalog.md +949 -0
- package/kb/site/en/reference/subsystems/approval.md +173 -0
- package/kb/site/en/reference/subsystems/client-modules.md +121 -0
- package/kb/site/en/reference/subsystems/code-runtime.md +194 -0
- package/kb/site/en/reference/subsystems/commands.md +190 -0
- package/kb/site/en/reference/subsystems/compaction.md +241 -0
- package/kb/site/en/reference/subsystems/core.md +1073 -0
- package/kb/site/en/reference/subsystems/credentials.md +136 -0
- package/kb/site/en/reference/subsystems/filesystem.md +498 -0
- package/kb/site/en/reference/subsystems/goal.md +280 -0
- package/kb/site/en/reference/subsystems/index.md +58 -0
- package/kb/site/en/reference/subsystems/invariants.md +91 -0
- package/kb/site/en/reference/subsystems/jobs.md +293 -0
- package/kb/site/en/reference/subsystems/llm-streaming.md +920 -0
- package/kb/site/en/reference/subsystems/lsp.md +205 -0
- package/kb/site/en/reference/subsystems/permission-presets.md +134 -0
- package/kb/site/en/reference/subsystems/persistence.md +388 -0
- package/kb/site/en/reference/subsystems/plan.md +90 -0
- package/kb/site/en/reference/subsystems/sandbox.md +221 -0
- package/kb/site/en/reference/subsystems/schedule.md +189 -0
- package/kb/site/en/reference/subsystems/scope.md +62 -0
- package/kb/site/en/reference/subsystems/session-projection.md +265 -0
- package/kb/site/en/reference/subsystems/session-query.md +498 -0
- package/kb/site/en/reference/subsystems/session-reference.md +111 -0
- package/kb/site/en/reference/subsystems/session-telemetry.md +197 -0
- package/kb/site/en/reference/subsystems/session-title.md +207 -0
- package/kb/site/en/reference/subsystems/session.md +852 -0
- package/kb/site/en/reference/subsystems/settings.md +313 -0
- package/kb/site/en/reference/subsystems/shell.md +306 -0
- package/kb/site/en/reference/subsystems/skills.md +334 -0
- package/kb/site/en/reference/subsystems/spill.md +120 -0
- package/kb/site/en/reference/subsystems/storage.md +232 -0
- package/kb/site/en/reference/subsystems/subagent.md +737 -0
- package/kb/site/en/reference/subsystems/subprocess.md +327 -0
- package/kb/site/en/reference/subsystems/system-prompt.md +210 -0
- package/kb/site/en/reference/subsystems/terminal.md +187 -0
- package/kb/site/en/reference/subsystems/token-meter.md +93 -0
- package/kb/site/en/reference/subsystems/tools.md +723 -0
- package/kb/site/en/reference/subsystems/typert.md +339 -0
- package/kb/site/en/reference/subsystems/user-questions.md +181 -0
- package/kb/site/en/reference/subsystems/web-server.md +111 -0
- package/kb/site/en/reference/subsystems/web.md +202 -0
- package/kb/site/en/reference/subsystems/workflow.md +281 -0
- package/kb/site/en/reference/subsystems/workspace.md +231 -0
- package/kb/site/en/reference/tool-catalog.md +1877 -0
- package/kb/site/en/reference/tool-execution-pipeline.md +66 -0
- package/kb/site/guide/providers-custom-form.zh.png +0 -0
- package/kb/site/guide/providers-models-page.zh.png +0 -0
- package/kb/site/guide/providers.md +100 -0
- package/kb/site/guide/python-sdk.md +106 -0
- package/kb/site/guide/quickstart.md +32 -0
- package/kb/site/index.md +8 -0
- package/kb/site/reference/agent-lifecycle.md +86 -0
- package/kb/site/reference/capability-seams.md +475 -0
- package/kb/site/reference/config-catalog.md +3154 -0
- package/kb/site/reference/cookbook/adding-a-conversation-node.md +235 -0
- package/kb/site/reference/cookbook/adding-a-package.md +120 -0
- package/kb/site/reference/cookbook/adding-a-settings-card.md +102 -0
- package/kb/site/reference/cookbook/adding-a-tool.md +98 -0
- package/kb/site/reference/cookbook/adding-an-llm-adapter.md +45 -0
- package/kb/site/reference/cookbook/extension-cookbook.md +133 -0
- package/kb/site/reference/cordis-api/context.md +368 -0
- package/kb/site/reference/cordis-api/events.md +211 -0
- package/kb/site/reference/cordis-api/fiber.md +379 -0
- package/kb/site/reference/cordis-api/inherited.md +43 -0
- package/kb/site/reference/cordis-api/registry.md +156 -0
- package/kb/site/reference/cordis-api/service.md +106 -0
- package/kb/site/reference/cordis-primer.md +52 -0
- package/kb/site/reference/index.md +135 -0
- package/kb/site/reference/persistence-catalog.md +949 -0
- package/kb/site/reference/subsystems/approval.md +173 -0
- package/kb/site/reference/subsystems/client-modules.md +121 -0
- package/kb/site/reference/subsystems/code-runtime.md +194 -0
- package/kb/site/reference/subsystems/commands.md +190 -0
- package/kb/site/reference/subsystems/compaction.md +241 -0
- package/kb/site/reference/subsystems/core.md +1081 -0
- package/kb/site/reference/subsystems/credentials.md +136 -0
- package/kb/site/reference/subsystems/filesystem.md +498 -0
- package/kb/site/reference/subsystems/goal.md +280 -0
- package/kb/site/reference/subsystems/index.md +58 -0
- package/kb/site/reference/subsystems/invariants.md +91 -0
- package/kb/site/reference/subsystems/jobs.md +293 -0
- package/kb/site/reference/subsystems/llm-streaming.md +926 -0
- package/kb/site/reference/subsystems/lsp.md +205 -0
- package/kb/site/reference/subsystems/permission-presets.md +134 -0
- package/kb/site/reference/subsystems/persistence.md +388 -0
- package/kb/site/reference/subsystems/plan.md +90 -0
- package/kb/site/reference/subsystems/sandbox.md +221 -0
- package/kb/site/reference/subsystems/schedule.md +189 -0
- package/kb/site/reference/subsystems/scope.md +62 -0
- package/kb/site/reference/subsystems/session-projection.md +265 -0
- package/kb/site/reference/subsystems/session-query.md +498 -0
- package/kb/site/reference/subsystems/session-reference.md +111 -0
- package/kb/site/reference/subsystems/session-telemetry.md +197 -0
- package/kb/site/reference/subsystems/session-title.md +207 -0
- package/kb/site/reference/subsystems/session.md +854 -0
- package/kb/site/reference/subsystems/settings.md +313 -0
- package/kb/site/reference/subsystems/shell.md +306 -0
- package/kb/site/reference/subsystems/skills.md +334 -0
- package/kb/site/reference/subsystems/spill.md +120 -0
- package/kb/site/reference/subsystems/storage.md +232 -0
- package/kb/site/reference/subsystems/subagent.md +739 -0
- package/kb/site/reference/subsystems/subprocess.md +327 -0
- package/kb/site/reference/subsystems/system-prompt.md +210 -0
- package/kb/site/reference/subsystems/terminal.md +187 -0
- package/kb/site/reference/subsystems/token-meter.md +93 -0
- package/kb/site/reference/subsystems/tools.md +723 -0
- package/kb/site/reference/subsystems/typert.md +339 -0
- package/kb/site/reference/subsystems/user-questions.md +181 -0
- package/kb/site/reference/subsystems/web-server.md +111 -0
- package/kb/site/reference/subsystems/web.md +202 -0
- package/kb/site/reference/subsystems/workflow.md +281 -0
- package/kb/site/reference/subsystems/workspace.md +231 -0
- package/kb/site/reference/tool-catalog.md +1880 -0
- package/kb/site/reference/tool-execution-pipeline.md +66 -0
- package/package.json +40 -0
- package/scripts/rebuild-index.mjs +88 -0
- package/skills/dsh-plugin-dev-kb.md +66 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
editSource: "docs/subsystems/sandbox.zh.md"
|
|
3
|
+
outline: [2,3]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 进程沙箱
|
|
7
|
+
|
|
8
|
+
[dsh-sandbox](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox) 的进程沙箱 seam 将与宿主共享文件系统和内核的子进程 argv 包装在文件效果策略中,而不将消费方耦合到特定平台运行器。[dsh-sandbox-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox-local) 提供 Linux bwrap/Landlock、macOS Seatbelt 与 Windows ACL 受限令牌后端;[dsh-bash-sandbox](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/shell/bash-sandbox) 和 [dsh-pwsh-sandbox](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/shell/pwsh-sandbox) 是其消费方。容器、microVM 和远程执行是完整能力 seam 的同级实现,而非 `ctx.sandbox` 的提供方。
|
|
9
|
+
|
|
10
|
+
源码:[`packages/sandbox/sandbox/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox/src/index.ts)
|
|
11
|
+
|
|
12
|
+
## 模式与强制执行
|
|
13
|
+
|
|
14
|
+
`SandboxMode` 仅管控文件系统效果。`read-only` 要求后端拒绝写入——POSIX runner 还会授予其 shell 所需的 `/dev/null` 接收器,而 Windows ACL runner 不授予任何显式可写根目录,并因环境 ACL 缺口报告部分强制执行;`workspace-write` 允许在工作区根目录及后端承诺的临时区域下写入;`danger-full-access` 绕过隔离。网络与进程可见性不在此处的定义范围内。
|
|
15
|
+
|
|
16
|
+
```ts type-equiv
|
|
17
|
+
/**
|
|
18
|
+
* File-effect policy for confined processes. `read-only` permits only required
|
|
19
|
+
* sinks such as `/dev/null`; `workspace-write` also permits the workspace and a
|
|
20
|
+
* backend-defined temp area; `danger-full-access` bypasses confinement. Network
|
|
21
|
+
* and process visibility are outside this vocabulary.
|
|
22
|
+
*/
|
|
23
|
+
type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
只有前两种模式可以发送给提供方。`danger-full-access` 的消费方直接 spawn 原始 argv,不调用 `ctx.sandbox`。
|
|
27
|
+
|
|
28
|
+
```ts type-equiv
|
|
29
|
+
/** A confining (non-`danger-full-access`) mode — the modes a {@link SandboxPolicy} can carry. */
|
|
30
|
+
type ConfinedSandboxMode = Exclude<SandboxMode, 'danger-full-access'>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
强制执行完整性是后端报告的事实。`full` 表示后端管控了该模式承诺的所有文件效果;`partial` 表示活跃后端或较旧的内核 ABI 仅管控其中一个子集,因此要求绝对保证的消费方必须拒绝或向上暴露这一区别。当前的部分强制执行情形包括较旧的 Landlock ABI,以及 Windows ACL runner 的 Everyone 与硬链接边界。
|
|
34
|
+
|
|
35
|
+
```ts type-equiv
|
|
36
|
+
/**
|
|
37
|
+
* Enforcement completeness for this host. `partial` means an active backend or
|
|
38
|
+
* older kernel ABI cannot govern every promised file effect; callers requiring
|
|
39
|
+
* an absolute boundary must not treat it as `full`.
|
|
40
|
+
*/
|
|
41
|
+
type SandboxEnforcement = 'full' | 'partial'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 逐调用策略
|
|
45
|
+
|
|
46
|
+
完整执行策略会按每次能力调用解析并携带。它包括 `danger-full-access`,因此消费方可以只解析一次策略,再决定是否绕过约束。普通工具调用从调用会话的不可变 cwd 派生 `workspaceRoot`;部署配置是没有 agent(智能体)时的回退值。root 会先按文件系统语义规范化,再做词法规范化,因此包含 `symlink/..` 的 cwd 会标识 spawn 出的进程实际运行的目录。
|
|
47
|
+
|
|
48
|
+
```ts type-equiv
|
|
49
|
+
/**
|
|
50
|
+
* The complete file-effect policy resolved for one capability call. The root
|
|
51
|
+
* is carried even under modes that do not consume it so callers can resolve
|
|
52
|
+
* policy once before choosing the enforcement path.
|
|
53
|
+
*/
|
|
54
|
+
interface SandboxExecutionPolicy {
|
|
55
|
+
/** The file-effect mode this execution runs under. */
|
|
56
|
+
mode: SandboxMode
|
|
57
|
+
/** Absolute root directory `workspace-write` may write under. */
|
|
58
|
+
workspaceRoot: string
|
|
59
|
+
/**
|
|
60
|
+
* Opaque identity of the calling session (the branded `dsh-session`
|
|
61
|
+
* SessionId). Backends key per-session state off it (e.g. windows-acl gives
|
|
62
|
+
* each live session/workspace pair a random private temp directory and SID,
|
|
63
|
+
* while the workspace SID and standing grant remain per-workspace); absent
|
|
64
|
+
* for agentless calls, which fall back to per-call backend state.
|
|
65
|
+
*/
|
|
66
|
+
sessionId?: SessionId
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`ctx.sandboxPolicy.resolve()` 接收活跃会话;对于已批准的重试,还接收显式模式。该服务拥有优先级与 root 回退规则,使 bash 和 fs 不必重复实现。
|
|
71
|
+
|
|
72
|
+
```ts type-equiv
|
|
73
|
+
/** Inputs that select the sandbox policy for one capability call. */
|
|
74
|
+
interface SandboxPolicyRequest {
|
|
75
|
+
/** Calling session; its immutable cwd becomes the workspace boundary. */
|
|
76
|
+
session?: Session
|
|
77
|
+
/** Explicit approved mode override, which outranks session policy. */
|
|
78
|
+
mode?: SandboxMode
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
只有受约束的执行会到达 `ctx.sandbox`;传给提供方的策略在保留同一 root 的同时收窄模式。这使并发会话、消费方与一次性提权重试可以向同一提供方请求不同边界,而无需改变提供方状态。
|
|
83
|
+
|
|
84
|
+
```ts type-equiv
|
|
85
|
+
/**
|
|
86
|
+
* What one confined execution is allowed to touch — carried PER CALL, not
|
|
87
|
+
* fixed on the provider: two consumers may confine under different policies
|
|
88
|
+
* at the same instant (bash under `read-only` while a confined child agent
|
|
89
|
+
* needs its state directory writable), and an approved escalated retry is a
|
|
90
|
+
* new call with a wider policy. Defaulting/resolution is an explicit step at
|
|
91
|
+
* the consumer boundary; the provider treats the policy as fully specified.
|
|
92
|
+
*/
|
|
93
|
+
interface SandboxPolicy extends SandboxExecutionPolicy {
|
|
94
|
+
/** The file-effect mode this execution runs under. */
|
|
95
|
+
mode: ConfinedSandboxMode
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 包装后的 argv 与分类方言
|
|
100
|
+
|
|
101
|
+
`RunnerFailureRule` 汇集用于判定 runner 在执行命令前失败的证据。消费方要求进程以非零状态退出,并同时满足可选的允许退出码门控,以及余下某一 stderr 行中不区分大小写的致命签名。系统会先按不区分大小写的整行精确匹配移除信息性排除项,因此无害的 runner 通知本身不能证明失败。匹配到的行仍可用作错误详情;分类过程不会重写 stderr。
|
|
102
|
+
|
|
103
|
+
```ts type-equiv
|
|
104
|
+
/**
|
|
105
|
+
* Evidence that identifies a sandbox runner failing before it executes the
|
|
106
|
+
* wrapped command. A consumer first applies {@link allowedExitCodes} when
|
|
107
|
+
* present, removes {@link informationalLines} by case-insensitive exact line
|
|
108
|
+
* equality, then matches {@link fatalSignatures} case-insensitively within
|
|
109
|
+
* each remaining stderr line. Exit status alone never proves runner failure.
|
|
110
|
+
*/
|
|
111
|
+
interface RunnerFailureRule {
|
|
112
|
+
/** Nonzero process exit codes on which this rule may match; omitted permits any nonzero exit. */
|
|
113
|
+
allowedExitCodes?: readonly number[]
|
|
114
|
+
/** Non-empty substrings identifying a fatal runner diagnostic on one stderr line. */
|
|
115
|
+
fatalSignatures: readonly string[]
|
|
116
|
+
/** Benign stderr lines excluded by exact full-line equality before fatal matching. */
|
|
117
|
+
informationalLines?: readonly string[]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`ConfinedArgv` 是消费方实际 spawn 的内容。除了替换后的 argv,它还携带后端的强制执行事实和两种正交的 stderr 分类器。`denialSignatures` 用于识别沙箱正常工作时受限命令被阻止的情况。`runnerFailureRules` 用于识别沙箱 runner 在执行命令之前拒绝或失败的情况;消费方应先检查后者,将其作为沙箱基础设施故障上报,而非普通任务失败。
|
|
122
|
+
|
|
123
|
+
```ts type-equiv
|
|
124
|
+
/**
|
|
125
|
+
* A {@link SandboxProvider.confine} result: the argv to spawn in place of
|
|
126
|
+
* the caller's own, plus the enforcement completeness the selected backend
|
|
127
|
+
* achieves for it.
|
|
128
|
+
*/
|
|
129
|
+
interface ConfinedArgv {
|
|
130
|
+
/** The wrapped argv (runner, profile, separator, then the caller's argv). */
|
|
131
|
+
argv: string[]
|
|
132
|
+
/** How completely the selected backend enforces the policy's file effects. */
|
|
133
|
+
enforcement: SandboxEnforcement
|
|
134
|
+
/**
|
|
135
|
+
* The selected backend's denial DIALECT: the case-insensitive stderr
|
|
136
|
+
* substrings a file effect denied by THIS backend produces (EROFS text
|
|
137
|
+
* under bwrap's read-only binds, EACCES under Landlock, EPERM under
|
|
138
|
+
* Seatbelt). A consumer that infers denials from a failed run's stderr
|
|
139
|
+
* matches against exactly these rather than a cross-backend union — the
|
|
140
|
+
* union claims denials a given backend never produces.
|
|
141
|
+
*/
|
|
142
|
+
denialSignatures: readonly string[]
|
|
143
|
+
/**
|
|
144
|
+
* Structured runner-failure evidence rules. Consumers require a matching
|
|
145
|
+
* fatal stderr line (after informational exclusions) and any rule-specific
|
|
146
|
+
* exit-code gate before checking denial signatures: runner failure means the
|
|
147
|
+
* command never ran, while denial means confinement worked and blocked it.
|
|
148
|
+
*/
|
|
149
|
+
runnerFailureRules: readonly RunnerFailureRule[]
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
[本地提供方](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-local/README.md)拥有运维配置,并将其 runner 方言映射到这些规则。[沙箱化 bash 消费方](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/shell/bash-sandbox/README.md)拥有 spawn 与结果归因。
|
|
154
|
+
|
|
155
|
+
## 提供方与 fail-closed 错误
|
|
156
|
+
|
|
157
|
+
`ctx.sandbox.confine(argv, policy)` 返回一个 `ConfinedArgv`,或在没有可用后端时抛出 `SandboxUnavailableError`(错误码 `SANDBOX_UNAVAILABLE`)。消费方也可以在 spawn 或观察所返回的 argv 时对失败进行分类;该归因属于消费方约定。对于受限策略,静默的无隔离透传永远不合法。
|
|
158
|
+
|
|
159
|
+
提供方选择、探测、缓存和后端特定的强制执行报告归[本地提供方](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-local/README.md)所有。
|
|
160
|
+
|
|
161
|
+
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
162
|
+
|
|
163
|
+
<a id="cordis-surface"></a>
|
|
164
|
+
|
|
165
|
+
## Cordis API
|
|
166
|
+
|
|
167
|
+
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
|
168
|
+
|
|
169
|
+
<a id="ctxsandbox--sandboxprovider-abstract-seam"></a>
|
|
170
|
+
|
|
171
|
+
### `ctx.sandbox` — `SandboxProvider` (abstract seam)
|
|
172
|
+
|
|
173
|
+
Abstract process-sandbox service. confine must return enforcing argv or fail closed at wrap or runner-execution time; silent unconfined passthrough is forbidden. Functional probes arbitrate multi-runner chains and may be skipped for a sole candidate, whose own refusal remains the fail-closed end.
|
|
174
|
+
|
|
175
|
+
```ts cordis-catalog
|
|
176
|
+
/**
|
|
177
|
+
* Wrap `argv` so it executes confined under `policy` on this host; the
|
|
178
|
+
* caller spawns the returned argv in place of its own.
|
|
179
|
+
* @param argv - the exact argv the caller is about to spawn (program plus
|
|
180
|
+
* arguments), NOT a shell string — a shell-shaped consumer passes
|
|
181
|
+
* `['bash', '-c', command]`.
|
|
182
|
+
* @param policy - the file-effect policy this execution runs under,
|
|
183
|
+
* carried per call (see {@link SandboxPolicy}).
|
|
184
|
+
* @returns the argv to spawn instead, plus the enforcement completeness
|
|
185
|
+
* the selected backend achieves for it.
|
|
186
|
+
*/
|
|
187
|
+
abstract confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Source: [`packages/sandbox/sandbox/src/index.ts:158`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox/src/index.ts)
|
|
191
|
+
|
|
192
|
+
<a id="ctxsandboxpolicy--sandboxpolicyservice"></a>
|
|
193
|
+
|
|
194
|
+
### `ctx.sandboxPolicy` — `SandboxPolicyService`
|
|
195
|
+
|
|
196
|
+
The sandbox-policy service (`ctx.sandboxPolicy`). Owns the deployment default mode, fallback workspace root, and current request-time policy section. Tool layers call resolve for each execution so a session's mode log and immutable cwd travel together to every enforcing capability.
|
|
197
|
+
|
|
198
|
+
```ts cordis-catalog
|
|
199
|
+
/**
|
|
200
|
+
* Resolve the complete policy for one capability call. An approved explicit
|
|
201
|
+
* mode outranks the session's last `sandbox/mode` event, which outranks the
|
|
202
|
+
* deployment default. A session cwd is its workspace-write boundary; the
|
|
203
|
+
* configured root is the fallback for agentless calls and sessions without a
|
|
204
|
+
* cwd.
|
|
205
|
+
* @param request - optional session and approved mode override.
|
|
206
|
+
* @returns the fully resolved per-call mode and absolute workspace root.
|
|
207
|
+
*/
|
|
208
|
+
resolve(request: SandboxPolicyRequest = {}): SandboxExecutionPolicy
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Read the session override without applying the deployment default.
|
|
212
|
+
* @param session - session whose log supplies the override.
|
|
213
|
+
* @returns the last logged mode, or `undefined` without one.
|
|
214
|
+
*/
|
|
215
|
+
overrideOf(session: Session): SandboxMode | undefined
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Types: [Session](./session.md)
|
|
219
|
+
|
|
220
|
+
Source: [`packages/sandbox/sandbox-policy/src/index.ts:91`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-policy/src/index.ts)
|
|
221
|
+
<!-- END GENERATED cordis-surface -->
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
editSource: "docs/subsystems/schedule.zh.md"
|
|
3
|
+
outline: [2,3]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 仅限 Session 内的 Schedule
|
|
7
|
+
|
|
8
|
+
Schedule 拥有持久提醒;这些提醒会作为普通的后续对话轮次返回原 live Session。[持久 Schedule Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md) 负责持久化与生命周期决策,[对话式交付](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-08-09-conversational-schedule-delivery.md) 负责无回执边界,[显式时区边界](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.md) 负责浏览器本地解释,[有界固定速率 Schedule](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-08-09-bounded-fixed-rate-schedule.md) 负责重复调度。本页记录 [`packages/schedule/schedule/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/schedule/schedule/src/types.ts) 中的持久数据形状和面向模型的数据形状;[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/schedule/schedule/README.md) 负责组合、工具行为与确切的提醒 framing。
|
|
9
|
+
|
|
10
|
+
## 持久记录
|
|
11
|
+
|
|
12
|
+
`ScheduleId` 是[品牌化 id](./core.md#branded-ids),在单个 Session 内唯一且绝不复用。版本 1 支持正的安全整数 `after_seconds` 延时、显式的绝对 `at` 目标,或至少五分钟的安全整数 `every_seconds` 间隔。创建操作会将每个初始目标规范化为使用四位年份的 RFC 3339 UTC `scheduledAt`;`after` 记录会保留提交的延时,`at` 记录只存储结果时点,`every` 记录则保留固定间隔和下一个目标。
|
|
13
|
+
|
|
14
|
+
```ts type-equiv
|
|
15
|
+
/** Durable one-shot reminder created from a positive delay. */
|
|
16
|
+
interface AfterScheduleRecord {
|
|
17
|
+
/** Session-local stable identity. */
|
|
18
|
+
readonly id: ScheduleId
|
|
19
|
+
/** Rule discriminator for a delayed one-shot reminder. */
|
|
20
|
+
readonly kind: 'after'
|
|
21
|
+
/** Trimmed reminder content supplied at creation. */
|
|
22
|
+
readonly prompt: string
|
|
23
|
+
/** Positive safe-integer delay accepted at creation. */
|
|
24
|
+
readonly afterSeconds: number
|
|
25
|
+
/** Four-digit-year RFC 3339 UTC target. */
|
|
26
|
+
readonly scheduledAt: string
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```ts type-equiv
|
|
31
|
+
/** Durable one-shot reminder created from an absolute instant. */
|
|
32
|
+
interface AtScheduleRecord {
|
|
33
|
+
/** Session-local stable identity. */
|
|
34
|
+
readonly id: ScheduleId
|
|
35
|
+
/** Rule discriminator for an absolute one-shot reminder. */
|
|
36
|
+
readonly kind: 'at'
|
|
37
|
+
/** Trimmed reminder content supplied at creation. */
|
|
38
|
+
readonly prompt: string
|
|
39
|
+
/** Four-digit-year RFC 3339 UTC target. */
|
|
40
|
+
readonly scheduledAt: string
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```ts type-equiv
|
|
45
|
+
/** Durable fixed-rate reminder whose next target remains creation-anchor-aligned. */
|
|
46
|
+
interface EveryScheduleRecord {
|
|
47
|
+
/** Session-local stable identity. */
|
|
48
|
+
readonly id: ScheduleId
|
|
49
|
+
/** Rule discriminator for a fixed-rate recurring reminder. */
|
|
50
|
+
readonly kind: 'every'
|
|
51
|
+
/** Trimmed reminder content supplied at creation. */
|
|
52
|
+
readonly prompt: string
|
|
53
|
+
/** Fixed safe-integer interval, never below five minutes. */
|
|
54
|
+
readonly everySeconds: number
|
|
55
|
+
/** Earliest anchor-aligned occurrence not yet dispatched. */
|
|
56
|
+
readonly scheduledAt: string
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```ts type-equiv
|
|
61
|
+
/** One-shot record variants that terminate on an id-only dispatch. */
|
|
62
|
+
type OneShotScheduleRecord = AfterScheduleRecord | AtScheduleRecord
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ts type-equiv
|
|
66
|
+
/** The v1 durable reminder record union. */
|
|
67
|
+
type ScheduleRecord = OneShotScheduleRecord | EveryScheduleRecord
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 绝对时间输入
|
|
71
|
+
|
|
72
|
+
`at` 选择器可以是严格且带偏移量的 RFC 3339 字符串,也可以是精确的本地日历对象。本地形式让这种解释在工具边界保持显式:
|
|
73
|
+
|
|
74
|
+
```ts type-equiv
|
|
75
|
+
/** Structured local-calendar input accepted by `schedule_create`. */
|
|
76
|
+
interface LocalAtInput {
|
|
77
|
+
/** Four-digit ISO calendar date. */
|
|
78
|
+
readonly date: string
|
|
79
|
+
/** Local wall-clock time with optional one-to-three digit milliseconds. */
|
|
80
|
+
readonly time: string
|
|
81
|
+
/** Explicit UTC or IANA Area/Location zone. */
|
|
82
|
+
readonly time_zone: string
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```ts type-equiv
|
|
87
|
+
/** Absolute selector accepted by `schedule_create`. */
|
|
88
|
+
type AtInput = string | LocalAtInput
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
官方 Web overlay 会为每条提示词采样浏览器的 IANA 时区。当 open turn 只有一个无歧义的浏览器时区时,Time-context 会告诉模型按该请求本地时区解释未明确限定时区的自然语言日期和时间;provenance 混合或缺失时,则告诉模型询问用户。该指引不是持久 Session 默认值:模型仍必须在字符串形式中传入偏移量,或在本地形式中传入 `time_zone`;Schedule 绝不会读取浏览器、Session、进程或模型上下文。
|
|
92
|
+
|
|
93
|
+
Schedule 会拒绝无效偏移量与时区、不带偏移量的字符串、非未来目标,以及落在夏令时缺口内的本地时间。遇到夏令时重叠时,会选择第一次出现的较早时点。创建成功后只存储规范化后的 UTC `scheduledAt`,因此回放绝不依赖环境时区状态。
|
|
94
|
+
|
|
95
|
+
## 固定速率输入与补偿
|
|
96
|
+
|
|
97
|
+
`every_seconds` 是每条记录单独拥有且至少为 300 秒的间隔,以创建时间为锚点。它只提供固定速率重复调度:协议不包含日历规则或 Cron 表达式、重复调度时区、共享冷却时间或跨记录准入门禁。
|
|
98
|
+
|
|
99
|
+
如果一个 Session 在多个目标到期期间处于 cold 或 busy 状态,一条 Every 记录只会贡献其中最新的一次到期触发。dispatch 会直接将记录推进到 dispatch 判断时刻之后第一个与创建锚点对齐的目标,而不会枚举、持久化或回放错过的间隔。如果下一个目标无法落在四位数年份的 UTC 范围内,最后一次 dispatch 将终结该记录。
|
|
100
|
+
|
|
101
|
+
当多条彼此不同的 Every 记录均已到期,且没有一次性提醒到期时,每条记录都会向同一个 follow-up 批次贡献一次触发,并按目标时间和创建顺序排列。每条 Every 记录的状态互相独立,但该获准批次中的所有 dispatch 都使用同一个判断时刻。批处理限制模型轮次数量;五分钟下限限制每条记录的 timer 频率。
|
|
102
|
+
|
|
103
|
+
## 持久变更与回放
|
|
104
|
+
|
|
105
|
+
版本 1 的 `schedule/change` 会话事件是 Schedule 唯一的持久权威。create 保存完整记录,delete 是终结性且仅含 id 的转换。一次性提醒的 dispatch 同样是终结性且仅含 id。Every dispatch 携带用于选择最新到期触发的墙钟判断时刻,通常推进活动记录而不终结它。dispatch 表示 follow-up 已同步入队,而不表示模型答复成功或用户已读取答复。
|
|
106
|
+
|
|
107
|
+
```ts type-equiv
|
|
108
|
+
/** Creates one durable reminder record. */
|
|
109
|
+
interface ScheduleCreateChange {
|
|
110
|
+
readonly version: 1
|
|
111
|
+
readonly operation: 'create'
|
|
112
|
+
readonly schedule: ScheduleRecord
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```ts type-equiv
|
|
117
|
+
/** Deletes one currently active reminder. */
|
|
118
|
+
interface ScheduleDeleteChange {
|
|
119
|
+
readonly version: 1
|
|
120
|
+
readonly operation: 'delete'
|
|
121
|
+
readonly id: ScheduleId
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```ts type-equiv
|
|
126
|
+
/** Records that one active one-shot reminder entered the durable dispatch history. */
|
|
127
|
+
interface OneShotScheduleDispatchChange {
|
|
128
|
+
readonly version: 1
|
|
129
|
+
readonly operation: 'dispatch'
|
|
130
|
+
readonly id: ScheduleId
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```ts type-equiv
|
|
135
|
+
/** Records one fixed-rate decision and advances directly past missed occurrences. */
|
|
136
|
+
interface EveryScheduleDispatchChange {
|
|
137
|
+
readonly version: 1
|
|
138
|
+
readonly operation: 'dispatch'
|
|
139
|
+
readonly id: ScheduleId
|
|
140
|
+
/** Wall-clock decision time used to select the latest due occurrence. */
|
|
141
|
+
readonly acceptedAt: string
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```ts type-equiv
|
|
146
|
+
/** Durable dispatch shapes supported by the current rule set. */
|
|
147
|
+
type ScheduleDispatchChange = OneShotScheduleDispatchChange | EveryScheduleDispatchChange
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```ts type-equiv
|
|
151
|
+
/** Strict version-1 durable Schedule mutation union. */
|
|
152
|
+
type ScheduleChange = ScheduleCreateChange | ScheduleDeleteChange | ScheduleDispatchChange
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
严格 decoder 与 fold 会拒绝未知版本、额外字段、复用 id、不匹配的一次性提醒或 Every dispatch 形状,以及针对非活动记录的 delete 或 dispatch 转换。普通 Session 折叠完整事件流。fork 只折叠 `SessionHeader.seedLength` 位置及其后的事件,因此保留历史,但不会接管父 Session 的活动提醒。`schedule/change` 声明和源码位置也编入[持久化目录](../persistence-catalog.md#schedulechange--log-only)。
|
|
156
|
+
|
|
157
|
+
## 活动视图与管理
|
|
158
|
+
|
|
159
|
+
工具值将持久记录与根据当前墙钟派生的交付状态组合起来。`session-local` 表示原 Session 必须处于 live 状态:不存在外部通知渠道或 cold Session scheduler。
|
|
160
|
+
|
|
161
|
+
```ts type-equiv
|
|
162
|
+
/** Current delivery timing derived from the durable record and wall clock. */
|
|
163
|
+
type ScheduleState = 'scheduled' | 'overdue'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```ts type-equiv
|
|
167
|
+
/** Fixed v1 delivery boundary: the original session must be live. */
|
|
168
|
+
type ScheduleDeliveryMode = 'session-local'
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```ts type-equiv
|
|
172
|
+
/** Complete model-facing view of one active reminder. */
|
|
173
|
+
type ScheduleView = ScheduleRecord & {
|
|
174
|
+
/** Whether the target remains in the future. */
|
|
175
|
+
readonly state: ScheduleState
|
|
176
|
+
/** Reminder delivery never leaves the owning session. */
|
|
177
|
+
readonly deliveryMode: ScheduleDeliveryMode
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
生成的[工具目录](../tool-catalog.md#deepseek-aidsh-schedule)负责 `schedule_create`、`schedule_list` 和 `schedule_delete` 的参数与结果 schema。一条 Agent-scoped 队列将管理调用与到期工作串行化。每次读取或判断都会先等待共享的 Session 持久化 barrier;create 与实际执行的 delete 在追加后还会再次等待。barrier 失败会报告 `persistence_uncertain`,而不是猜测 eager write 是否已提交。其他稳定错误代码是 `invalid_prompt`、`invalid_selector`、`invalid_rule`、`invalid_time_zone`、`not_future`、`time_out_of_range`、`frequency_too_high`、`corrupt_schedule_log` 和 `internal_error`。
|
|
182
|
+
|
|
183
|
+
## Live 交付
|
|
184
|
+
|
|
185
|
+
进程内 owner 根据持久 fold 派生最早的 timer,并在每次有界等待后重新读取墙钟。cold Session 不执行任何工作;重新打开后会重建 timer,并使已经过去的目标进入 overdue 状态。到期的一次性提醒享有优先级,每次只进入一个后续轮次。当没有一次性提醒到期时,所有 overdue 的 Every 记录会组成上述单个批次。
|
|
186
|
+
|
|
187
|
+
到期工作会先等待 Agent 完全 idle 并认领 maintenance phase,再重新折叠状态、采样本次判断、将一个 `followup()` 排入队列,并追加对应的 dispatch 变更。它绝不会调用 `steer()`,也绝不会中断当前轮次。
|
|
188
|
+
|
|
189
|
+
获得准入的一次性提醒或固定速率批次会启动一个普通的后续轮次,且只通过普通对话 transcript(文本记录)出现;Schedule 不提供独立的持久 Web 回执或浏览器渲染器。如果 framing 构造或同步队列准入失败,则不会记录 dispatch,提醒仍保持活动。队列准入后、持久 dispatch 前的狭窄崩溃窗口可能使提醒内容在恢复后重复,因此该边界提供的是尽力而为的至少一次交付,而非恰好一次交付。
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
editSource: "docs/subsystems/scope.zh.md"
|
|
3
|
+
outline: [2,3]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 作用域注册
|
|
7
|
+
|
|
8
|
+
[scope 包](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/scope)提供身份、载体与作用域层词汇,使同一注册上下文同时表达每个 agent(智能体)的可见性和共享生命周期所有权。它是库原语,而不是 Cordis 服务;生命周期设计理由由 [agent-scope 运行时设计 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.md#scope-routing-one-opaque-key-selects-one-layer)规定,注册表层决策由[共享存储 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-12-scoped-layers-store.md)规定,可调用 API 与过滤语义则由包 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/scope/README.md)规定。
|
|
9
|
+
|
|
10
|
+
源码:[`packages/core/scope/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/scope/src/index.ts) 与 [`packages/core/scope/src/store.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/scope/src/store.ts)。
|
|
11
|
+
|
|
12
|
+
## 身份标识与分发载体
|
|
13
|
+
|
|
14
|
+
`ScopeKey` 是一个不透明的对象身份标识。已交付的 agent loop(智能体循环)使用活跃的 `Agent` 对象作为自身的 key,但该原语从不检视该对象。
|
|
15
|
+
|
|
16
|
+
```ts type-equiv
|
|
17
|
+
/** An opaque, identity-compared scope key. */
|
|
18
|
+
type ScopeKey = object
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`Scoped<T>` 是编译期品牌标记,标注在 `scopeTarget(base, key)` 返回的不透明路由接收器上。作用域过滤的事件声明要求以此载体作为 `this` 类型,而真正的事件主体仍作为显式参数传入。
|
|
22
|
+
|
|
23
|
+
```ts type-equiv
|
|
24
|
+
/**
|
|
25
|
+
* A routing-only event receiver built by {@link scopeTarget}. The type
|
|
26
|
+
* parameter records the subject type for dispatch checking; the carrier does
|
|
27
|
+
* not expose the subject's properties. Event payloads carry the real subject.
|
|
28
|
+
*/
|
|
29
|
+
type Scoped<T extends object> = object & { readonly [ScopedBrand]: T }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 拥有所有权的注册上下文
|
|
33
|
+
|
|
34
|
+
`Scope` 将带标签的注册上下文与两个拆卸接口配对。`rawDispose` 保留有序复合 effect 所需的 Cordis disposer 的确切身份;`dispose()` 是面向直接调用方和竞态调用方的公共完全停稳边界。
|
|
35
|
+
|
|
36
|
+
```ts type-equiv
|
|
37
|
+
/** A minted registration scope and its quiescent disposal boundaries. */
|
|
38
|
+
interface Scope {
|
|
39
|
+
/** Context through which scope-owned registrations are made. */
|
|
40
|
+
ctx: Context
|
|
41
|
+
/** Exact Cordis disposer, used when nesting this scope in an ordered composite effect. */
|
|
42
|
+
rawDispose: () => Promise<void> | void
|
|
43
|
+
/** Dispose every scope-owned registration; racing calls await the same completion. */
|
|
44
|
+
dispose(): Promise<void>
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 带作用域的注册表层
|
|
49
|
+
|
|
50
|
+
`ScopeLayer` 表示一个注册表在全局或确切作用域层级的完整贡献。具体 layer 可以聚合多个具名与匿名 table;整个 layer 为空时,`ScopedLayers` 可以回收带作用域状态,而不会丢弃兄弟 table。
|
|
51
|
+
|
|
52
|
+
```ts type-equiv
|
|
53
|
+
/** One scope's aggregate contribution to a registry. */
|
|
54
|
+
interface ScopeLayer {
|
|
55
|
+
/** Whether every table in this layer is empty. */
|
|
56
|
+
isEmpty(): boolean
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`ScopedLayers<L>` 拥有立即创建的全局 layer,以及惰性创建的确切作用域 layer。读取不会创建 layer:`peek(undefined)` 表示不存在作用域覆盖层,而 `merge()` 会依次物化按插入顺序排列的全局具名条目和带作用域的遮蔽项。注册使用同一个上下文表示可见性与 Cordis effect 所有权,在可选通知前取得一个同步撤销函数,返回 Cordis 的原始 disposer,并且只在带作用域 layer 的完整 `ScopeLayer` 为空时回收它。
|
|
61
|
+
|
|
62
|
+
`NamedEntries<V>` 提供按插入顺序的查找和动态迭代,重复项错误由调用方处理。`AnonymousEntries<V>` 为每次 append 分配唯一标识,因此值相等的条目仍彼此独立。在同一轮非空 table 生命周期内,迭代器可以观察后续变化;table 被清空后,现有迭代器不会再观察后续插入。两者都返回幂等、精确对应相应条目的撤销函数;共享实现接口 `EntryValues` 不对外公开。
|