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.
Files changed (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/cordis.patch.yml +12 -0
  4. package/kb/INDEX.md +210 -0
  5. package/kb/README.md +69 -0
  6. package/kb/extra/AGENTS.md +75 -0
  7. package/kb/extra/api-gateway.md +164 -0
  8. package/kb/extra/api-gateway.zh.md +164 -0
  9. package/kb/extra/cookbook/adding-a-vendored-package.md +59 -0
  10. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +59 -0
  11. package/kb/extra/cookbook/maintaining-dsh-code-review.md +64 -0
  12. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +64 -0
  13. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
  14. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
  15. package/kb/extra/defensive-patterns.md +33 -0
  16. package/kb/extra/defensive-patterns.zh.md +33 -0
  17. package/kb/extra/development.md +171 -0
  18. package/kb/extra/development.zh.md +171 -0
  19. package/kb/extra/event-producer-consumer.md +76 -0
  20. package/kb/extra/event-producer-consumer.zh.md +78 -0
  21. package/kb/extra/glossary.md +45 -0
  22. package/kb/extra/glossary.zh.md +45 -0
  23. package/kb/extra/graph-atlas.md +24 -0
  24. package/kb/extra/graph-atlas.zh.md +26 -0
  25. package/kb/extra/i18n/README.md +60 -0
  26. package/kb/extra/i18n/README.zh.md +60 -0
  27. package/kb/extra/i18n/style-samples.md +87 -0
  28. package/kb/extra/i18n/terminology.md +214 -0
  29. package/kb/extra/i18n/translation-prompt.md +263 -0
  30. package/kb/extra/i18n/translation-rules.md +69 -0
  31. package/kb/extra/i18n/translation-rules.zh.md +69 -0
  32. package/kb/extra/module-graph.md +1641 -0
  33. package/kb/extra/module-graph.zh.md +1643 -0
  34. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +113 -0
  35. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
  36. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
  37. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
  38. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
  39. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
  40. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
  41. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
  42. package/kb/extra/postmortem/README.md +18 -0
  43. package/kb/extra/postmortem/README.zh.md +18 -0
  44. package/kb/extra/rescope.md +53 -0
  45. package/kb/extra/rescope.zh.md +53 -0
  46. package/kb/extra/subsystems/attachment.md +125 -0
  47. package/kb/extra/subsystems/attachment.zh.md +125 -0
  48. package/kb/extra/subsystems/extensions.md +364 -0
  49. package/kb/extra/subsystems/extensions.zh.md +364 -0
  50. package/kb/extra/subsystems/feedback.md +266 -0
  51. package/kb/extra/subsystems/feedback.zh.md +266 -0
  52. package/kb/extra/testing.md +49 -0
  53. package/kb/extra/testing.zh.md +49 -0
  54. package/kb/extra/web-styling.md +25 -0
  55. package/kb/extra/web-styling.zh.md +25 -0
  56. package/kb/meta/search-index.json +1328 -0
  57. package/kb/meta/site-pages.txt +168 -0
  58. package/kb/meta/source.json +13 -0
  59. package/kb/meta/topics.md +75 -0
  60. package/kb/site/develop/basic/config.md +108 -0
  61. package/kb/site/develop/basic/index.md +146 -0
  62. package/kb/site/develop/basic/publish.md +185 -0
  63. package/kb/site/develop/basic/tool.md +54 -0
  64. package/kb/site/develop/cordis-tutorial/01-first-plugin.md +95 -0
  65. package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  66. package/kb/site/develop/cordis-tutorial/03-services.md +98 -0
  67. package/kb/site/develop/cordis-tutorial/04-events.md +144 -0
  68. package/kb/site/develop/cordis-tutorial/05-config.md +84 -0
  69. package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  70. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  71. package/kb/site/develop/cordis-tutorial/index.md +62 -0
  72. package/kb/site/develop/framework/events.md +145 -0
  73. package/kb/site/develop/framework/index.md +139 -0
  74. package/kb/site/develop/framework/service.md +152 -0
  75. package/kb/site/develop/practice/index.md +157 -0
  76. package/kb/site/develop/practice/llm-adapter.md +190 -0
  77. package/kb/site/en/develop/basic/config.md +108 -0
  78. package/kb/site/en/develop/basic/index.md +146 -0
  79. package/kb/site/en/develop/basic/publish.md +185 -0
  80. package/kb/site/en/develop/basic/tool.md +54 -0
  81. package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +95 -0
  82. package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  83. package/kb/site/en/develop/cordis-tutorial/03-services.md +98 -0
  84. package/kb/site/en/develop/cordis-tutorial/04-events.md +144 -0
  85. package/kb/site/en/develop/cordis-tutorial/05-config.md +84 -0
  86. package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  87. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  88. package/kb/site/en/develop/cordis-tutorial/index.md +60 -0
  89. package/kb/site/en/develop/framework/events.md +145 -0
  90. package/kb/site/en/develop/framework/index.md +139 -0
  91. package/kb/site/en/develop/framework/service.md +150 -0
  92. package/kb/site/en/develop/practice/index.md +157 -0
  93. package/kb/site/en/develop/practice/llm-adapter.md +190 -0
  94. package/kb/site/en/guide/providers-custom-form.png +0 -0
  95. package/kb/site/en/guide/providers-models-page.png +0 -0
  96. package/kb/site/en/guide/providers.md +100 -0
  97. package/kb/site/en/guide/python-sdk.md +106 -0
  98. package/kb/site/en/guide/quickstart.md +32 -0
  99. package/kb/site/en/index.md +8 -0
  100. package/kb/site/en/reference/agent-lifecycle.md +86 -0
  101. package/kb/site/en/reference/capability-seams.md +475 -0
  102. package/kb/site/en/reference/config-catalog.md +3155 -0
  103. package/kb/site/en/reference/cookbook/adding-a-conversation-node.md +235 -0
  104. package/kb/site/en/reference/cookbook/adding-a-package.md +120 -0
  105. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +102 -0
  106. package/kb/site/en/reference/cookbook/adding-a-tool.md +96 -0
  107. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +45 -0
  108. package/kb/site/en/reference/cookbook/extension-cookbook.md +131 -0
  109. package/kb/site/en/reference/cordis-api/context.md +368 -0
  110. package/kb/site/en/reference/cordis-api/events.md +211 -0
  111. package/kb/site/en/reference/cordis-api/fiber.md +379 -0
  112. package/kb/site/en/reference/cordis-api/inherited.md +43 -0
  113. package/kb/site/en/reference/cordis-api/registry.md +156 -0
  114. package/kb/site/en/reference/cordis-api/service.md +106 -0
  115. package/kb/site/en/reference/cordis-primer.md +46 -0
  116. package/kb/site/en/reference/index.md +131 -0
  117. package/kb/site/en/reference/persistence-catalog.md +949 -0
  118. package/kb/site/en/reference/subsystems/approval.md +173 -0
  119. package/kb/site/en/reference/subsystems/client-modules.md +121 -0
  120. package/kb/site/en/reference/subsystems/code-runtime.md +194 -0
  121. package/kb/site/en/reference/subsystems/commands.md +190 -0
  122. package/kb/site/en/reference/subsystems/compaction.md +241 -0
  123. package/kb/site/en/reference/subsystems/core.md +1073 -0
  124. package/kb/site/en/reference/subsystems/credentials.md +136 -0
  125. package/kb/site/en/reference/subsystems/filesystem.md +498 -0
  126. package/kb/site/en/reference/subsystems/goal.md +280 -0
  127. package/kb/site/en/reference/subsystems/index.md +58 -0
  128. package/kb/site/en/reference/subsystems/invariants.md +91 -0
  129. package/kb/site/en/reference/subsystems/jobs.md +293 -0
  130. package/kb/site/en/reference/subsystems/llm-streaming.md +920 -0
  131. package/kb/site/en/reference/subsystems/lsp.md +205 -0
  132. package/kb/site/en/reference/subsystems/permission-presets.md +134 -0
  133. package/kb/site/en/reference/subsystems/persistence.md +388 -0
  134. package/kb/site/en/reference/subsystems/plan.md +90 -0
  135. package/kb/site/en/reference/subsystems/sandbox.md +221 -0
  136. package/kb/site/en/reference/subsystems/schedule.md +189 -0
  137. package/kb/site/en/reference/subsystems/scope.md +62 -0
  138. package/kb/site/en/reference/subsystems/session-projection.md +265 -0
  139. package/kb/site/en/reference/subsystems/session-query.md +498 -0
  140. package/kb/site/en/reference/subsystems/session-reference.md +111 -0
  141. package/kb/site/en/reference/subsystems/session-telemetry.md +197 -0
  142. package/kb/site/en/reference/subsystems/session-title.md +207 -0
  143. package/kb/site/en/reference/subsystems/session.md +852 -0
  144. package/kb/site/en/reference/subsystems/settings.md +313 -0
  145. package/kb/site/en/reference/subsystems/shell.md +306 -0
  146. package/kb/site/en/reference/subsystems/skills.md +334 -0
  147. package/kb/site/en/reference/subsystems/spill.md +120 -0
  148. package/kb/site/en/reference/subsystems/storage.md +232 -0
  149. package/kb/site/en/reference/subsystems/subagent.md +737 -0
  150. package/kb/site/en/reference/subsystems/subprocess.md +327 -0
  151. package/kb/site/en/reference/subsystems/system-prompt.md +210 -0
  152. package/kb/site/en/reference/subsystems/terminal.md +187 -0
  153. package/kb/site/en/reference/subsystems/token-meter.md +93 -0
  154. package/kb/site/en/reference/subsystems/tools.md +723 -0
  155. package/kb/site/en/reference/subsystems/typert.md +339 -0
  156. package/kb/site/en/reference/subsystems/user-questions.md +181 -0
  157. package/kb/site/en/reference/subsystems/web-server.md +111 -0
  158. package/kb/site/en/reference/subsystems/web.md +202 -0
  159. package/kb/site/en/reference/subsystems/workflow.md +281 -0
  160. package/kb/site/en/reference/subsystems/workspace.md +231 -0
  161. package/kb/site/en/reference/tool-catalog.md +1877 -0
  162. package/kb/site/en/reference/tool-execution-pipeline.md +66 -0
  163. package/kb/site/guide/providers-custom-form.zh.png +0 -0
  164. package/kb/site/guide/providers-models-page.zh.png +0 -0
  165. package/kb/site/guide/providers.md +100 -0
  166. package/kb/site/guide/python-sdk.md +106 -0
  167. package/kb/site/guide/quickstart.md +32 -0
  168. package/kb/site/index.md +8 -0
  169. package/kb/site/reference/agent-lifecycle.md +86 -0
  170. package/kb/site/reference/capability-seams.md +475 -0
  171. package/kb/site/reference/config-catalog.md +3154 -0
  172. package/kb/site/reference/cookbook/adding-a-conversation-node.md +235 -0
  173. package/kb/site/reference/cookbook/adding-a-package.md +120 -0
  174. package/kb/site/reference/cookbook/adding-a-settings-card.md +102 -0
  175. package/kb/site/reference/cookbook/adding-a-tool.md +98 -0
  176. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +45 -0
  177. package/kb/site/reference/cookbook/extension-cookbook.md +133 -0
  178. package/kb/site/reference/cordis-api/context.md +368 -0
  179. package/kb/site/reference/cordis-api/events.md +211 -0
  180. package/kb/site/reference/cordis-api/fiber.md +379 -0
  181. package/kb/site/reference/cordis-api/inherited.md +43 -0
  182. package/kb/site/reference/cordis-api/registry.md +156 -0
  183. package/kb/site/reference/cordis-api/service.md +106 -0
  184. package/kb/site/reference/cordis-primer.md +52 -0
  185. package/kb/site/reference/index.md +135 -0
  186. package/kb/site/reference/persistence-catalog.md +949 -0
  187. package/kb/site/reference/subsystems/approval.md +173 -0
  188. package/kb/site/reference/subsystems/client-modules.md +121 -0
  189. package/kb/site/reference/subsystems/code-runtime.md +194 -0
  190. package/kb/site/reference/subsystems/commands.md +190 -0
  191. package/kb/site/reference/subsystems/compaction.md +241 -0
  192. package/kb/site/reference/subsystems/core.md +1081 -0
  193. package/kb/site/reference/subsystems/credentials.md +136 -0
  194. package/kb/site/reference/subsystems/filesystem.md +498 -0
  195. package/kb/site/reference/subsystems/goal.md +280 -0
  196. package/kb/site/reference/subsystems/index.md +58 -0
  197. package/kb/site/reference/subsystems/invariants.md +91 -0
  198. package/kb/site/reference/subsystems/jobs.md +293 -0
  199. package/kb/site/reference/subsystems/llm-streaming.md +926 -0
  200. package/kb/site/reference/subsystems/lsp.md +205 -0
  201. package/kb/site/reference/subsystems/permission-presets.md +134 -0
  202. package/kb/site/reference/subsystems/persistence.md +388 -0
  203. package/kb/site/reference/subsystems/plan.md +90 -0
  204. package/kb/site/reference/subsystems/sandbox.md +221 -0
  205. package/kb/site/reference/subsystems/schedule.md +189 -0
  206. package/kb/site/reference/subsystems/scope.md +62 -0
  207. package/kb/site/reference/subsystems/session-projection.md +265 -0
  208. package/kb/site/reference/subsystems/session-query.md +498 -0
  209. package/kb/site/reference/subsystems/session-reference.md +111 -0
  210. package/kb/site/reference/subsystems/session-telemetry.md +197 -0
  211. package/kb/site/reference/subsystems/session-title.md +207 -0
  212. package/kb/site/reference/subsystems/session.md +854 -0
  213. package/kb/site/reference/subsystems/settings.md +313 -0
  214. package/kb/site/reference/subsystems/shell.md +306 -0
  215. package/kb/site/reference/subsystems/skills.md +334 -0
  216. package/kb/site/reference/subsystems/spill.md +120 -0
  217. package/kb/site/reference/subsystems/storage.md +232 -0
  218. package/kb/site/reference/subsystems/subagent.md +739 -0
  219. package/kb/site/reference/subsystems/subprocess.md +327 -0
  220. package/kb/site/reference/subsystems/system-prompt.md +210 -0
  221. package/kb/site/reference/subsystems/terminal.md +187 -0
  222. package/kb/site/reference/subsystems/token-meter.md +93 -0
  223. package/kb/site/reference/subsystems/tools.md +723 -0
  224. package/kb/site/reference/subsystems/typert.md +339 -0
  225. package/kb/site/reference/subsystems/user-questions.md +181 -0
  226. package/kb/site/reference/subsystems/web-server.md +111 -0
  227. package/kb/site/reference/subsystems/web.md +202 -0
  228. package/kb/site/reference/subsystems/workflow.md +281 -0
  229. package/kb/site/reference/subsystems/workspace.md +231 -0
  230. package/kb/site/reference/tool-catalog.md +1880 -0
  231. package/kb/site/reference/tool-execution-pipeline.md +66 -0
  232. package/package.json +40 -0
  233. package/scripts/rebuild-index.mjs +88 -0
  234. package/skills/dsh-plugin-dev-kb.md +66 -0
@@ -0,0 +1,221 @@
1
+ ---
2
+ editSource: "docs/subsystems/sandbox.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # Process Sandbox
7
+
8
+ The process-sandbox seam of [dsh-sandbox](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox) wraps a same-world subprocess argv in a file-effect policy without coupling consumers to a platform runner. [dsh-sandbox-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox-local) supplies Linux bwrap/Landlock, macOS Seatbelt, and the Windows ACL restricted-token backend; [dsh-bash-sandbox](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/shell/bash-sandbox) and [dsh-pwsh-sandbox](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/shell/pwsh-sandbox) consume it. Containers, microVMs, and remote execution are sibling implementations of whole capability seams, not providers of `ctx.sandbox`.
9
+
10
+ Source: [`packages/sandbox/sandbox/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox/src/index.ts)
11
+
12
+ ## Modes and enforcement
13
+
14
+ `SandboxMode` governs filesystem effects only. `read-only` asks the backend to deny writes — the POSIX runners additionally grant the `/dev/null` sink their shells require, while the Windows ACL runner grants no explicit writable root and reports partial enforcement for its ambient ACL gaps; `workspace-write` permits writes under the workspace root and the backend's promised temp area; `danger-full-access` bypasses confinement. Network and process visibility are outside this vocabulary.
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
+ Only the first two modes can be sent to a provider. A `danger-full-access` consumer spawns its original argv and does not call `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
+ Enforcement is a reported fact. `full` means the backend governs every file effect promised by the mode; `partial` means an active backend or older kernel ABI governs only a subset, so consumers that require the absolute promise must reject or surface that distinction. Older Landlock ABIs and the Windows ACL runner's Everyone/hard-link boundaries are current partial cases.
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
+ ## Per-call policy
45
+
46
+ The complete execution policy is resolved and carried per capability call. It includes `danger-full-access` so a consumer can resolve policy once before deciding whether to bypass confinement. Normal tool calls derive `workspaceRoot` from the calling session's immutable cwd; deployment configuration is the agentless fallback. The root is canonicalized with filesystem semantics before lexical normalization, so a cwd containing `symlink/..` identifies the directory where a spawned process actually runs.
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()` accepts the active session and, for an approved retry, an explicit mode. The service owns precedence and root fallback so bash and fs do not repeat it.
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
+ Only a confined execution reaches `ctx.sandbox`; its provider policy narrows the mode while retaining the same root. This permits concurrent sessions, consumers, and one-shot escalated retries to ask the same provider for different boundaries without mutating provider state.
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
+ ## Wrapped argv and classification dialects
100
+
101
+ `RunnerFailureRule` combines evidence that a runner failed before executing the command. A consumer requires a nonzero exit, the optional allowed-exit-code gate, and a case-insensitive fatal signature within one remaining stderr line. Case-insensitive exact full-line informational exclusions are removed first, so a benign runner notice cannot prove failure by itself. The matched line remains available as error detail; classification does not rewrite 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` is what the consumer spawns. Besides the replacement argv, it carries the backend's enforcement fact and two orthogonal stderr classifiers. `denialSignatures` identify the confined command being blocked while the sandbox works correctly. `runnerFailureRules` identify the sandbox runner refusing or failing before it executes the command; consumers check these first and surface a sandbox infrastructure failure, never an ordinary task failure.
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
+ The [local provider](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-local/README.md) owns operator configuration and maps its runner dialect into these rules. The [sandboxed bash consumer](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/shell/bash-sandbox/README.md) owns spawn and result attribution.
154
+
155
+ ## Provider and fail-closed errors
156
+
157
+ `ctx.sandbox.confine(argv, policy)` returns a `ConfinedArgv` or throws `SandboxUnavailableError` with code `SANDBOX_UNAVAILABLE` when no usable backend exists. Consumers may also classify a failure while spawning or observing the returned argv; that attribution belongs to the consumer contract. Silent unconfined passthrough is never legal for a confined policy.
158
+
159
+ Provider selection, probing, caching, and backend-specific enforcement reports belong to the [local provider](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.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # Session-local Schedule
7
+
8
+ Schedule owns durable reminders that return to the original live Session as ordinary later conversation turns. The [durable Schedule Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md) owns the persistence and lifecycle decisions, [conversational delivery](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-08-09-conversational-schedule-delivery.md) owns the no-receipt boundary, the [explicit time-zone boundary](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.md) owns browser-local interpretation, and [bounded fixed-rate Schedule](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-08-09-bounded-fixed-rate-schedule.md) owns recurrence. This page records the durable and model-facing shapes from [`packages/schedule/schedule/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/schedule/schedule/src/types.ts); the [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/schedule/schedule/README.md) owns composition, tool behavior, and the exact reminder framing.
9
+
10
+ ## Durable records
11
+
12
+ `ScheduleId` is a [branded id](./core.md#branded-ids), unique and never reused within one Session. Version 1 supports a positive safe-integer `after_seconds` delay, an explicit absolute `at` target, or a safe-integer `every_seconds` interval of at least five minutes. Creation canonicalizes every first target into a four-digit-year RFC 3339 UTC `scheduledAt`; an `after` record retains its submitted delay, an `at` record stores only the resulting instant, and an `every` record retains its fixed interval and next target.
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
+ ## Absolute-time input
71
+
72
+ The `at` selector is either a strict offset-bearing RFC 3339 string or an exact local-calendar object. The local form keeps its interpretation explicit at the tool boundary:
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
+ The official Web overlay samples the browser's IANA zone for every prompt. Time-context tells the model to interpret otherwise-unqualified natural-language dates and times in that request-local zone when the open turn has one unambiguous browser zone; mixed or missing provenance tells the model to ask. That guidance is not a durable Session default: the model must still pass an offset in the string form or `time_zone` in the local form, and Schedule never reads browser, Session, process, or model context.
92
+
93
+ Schedule rejects invalid offsets and zones, offset-free strings, non-future targets, and local times inside daylight-saving gaps. A daylight-saving overlap chooses its first, earlier instant. Successful creation stores only canonical UTC `scheduledAt`, so replay never depends on ambient time-zone state.
94
+
95
+ ## Fixed-rate input and catch-up
96
+
97
+ `every_seconds` is a per-record interval of at least 300 seconds, anchored to creation time. It is fixed-rate recurrence only: the protocol has no calendar or Cron expression, recurrence time zone, shared cooldown, or cross-record admission gate.
98
+
99
+ When a Session was cold or busy across several targets, one Every record contributes only its latest due occurrence. The dispatch advances it directly to the first creation-anchor-aligned target after the dispatch decision time, without enumerating, persisting, or replaying missed intervals. If that next target cannot fit in a four-digit UTC year, the final dispatch terminates the record.
100
+
101
+ When multiple distinct Every records are overdue and no one-shot is due, each contributes one occurrence to the same follow-up batch in target and creation order. Every record keeps independent state, while all dispatches in that admitted batch use the same decision time. Batching bounds model turns; the five-minute minimum bounds each record's timer frequency.
102
+
103
+ ## Durable changes and replay
104
+
105
+ The version-1 `schedule/change` Session event is the only durable Schedule authority. Create stores the complete record, and delete is a terminal id-only transition. A one-shot dispatch is also terminal and id-only. An Every dispatch carries the wall-clock decision time used to select its latest due occurrence and normally advances the active record instead of terminating it. Dispatch means the follow-up was synchronously queued, not that a model answer succeeded or the user read it.
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
+ The strict decoder and fold reject unknown versions, extra fields, reused ids, mismatched one-shot or Every dispatch shapes, and delete or dispatch transitions against inactive records. A normal Session folds its complete event stream. A fork folds only events at or after `SessionHeader.seedLength`, so it retains history without adopting the parent Session's active reminders. The `schedule/change` declaration and source location are also indexed in the [persistence catalog](../persistence-catalog.md#schedulechange--log-only).
156
+
157
+ ## Active views and management
158
+
159
+ Tool values combine the durable record with delivery state derived from the current wall clock. `session-local` means the original Session must be live: no external notification channel or cold-session scheduler exists.
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
+ The generated [tool catalog](../tool-catalog.md#deepseek-aidsh-schedule) owns the argument and result schemas for `schedule_create`, `schedule_list`, and `schedule_delete`. Management calls serialize with due work in one Agent-scoped queue. Every read or decision first waits for the shared Session persistence barrier; create and an actual delete wait again after appending. A barrier failure reports `persistence_uncertain` instead of guessing whether an eager write committed. The other stable error codes are `invalid_prompt`, `invalid_selector`, `invalid_rule`, `invalid_time_zone`, `not_future`, `time_out_of_range`, `frequency_too_high`, `corrupt_schedule_log`, and `internal_error`.
182
+
183
+ ## Live delivery
184
+
185
+ The process-local owner derives its earliest timer from the durable fold and rereads the wall clock after every bounded wait. Cold Sessions do no work; reopening one reconstructs timers and makes past targets overdue. Due one-shots take priority and enter one later turn at a time. When no one-shot is due, all overdue Every records form the single batch described above.
186
+
187
+ Due work waits for the Agent to become fully idle and claims the maintenance phase before it refolds state, samples the decision, queues one `followup()`, and appends the corresponding dispatch changes. It never calls `steer()` and never interrupts a current turn.
188
+
189
+ The admitted one-shot or fixed-rate batch starts one normal later turn and appears only through the ordinary conversation transcript; Schedule has no independent durable Web receipt or browser renderer. If framing or synchronous queue admission fails, no dispatch is recorded and the reminder stays active. The narrow crash interval after admission but before durable dispatch can repeat reminder content after recovery, so the boundary is best-effort at-least-once rather than exactly-once delivery.
@@ -0,0 +1,62 @@
1
+ ---
2
+ editSource: "docs/subsystems/scope.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # Scoped Registration
7
+
8
+ The [scope package](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/scope) supplies the identity, carrier, and scoped-layer vocabulary that makes one registration context mean both per-agent visibility and shared lifetime ownership. It is a library primitive rather than a Cordis service; the [agent-scope runtime-design 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) owns the lifecycle rationale, the [shared-storage Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-12-scoped-layers-store.md) owns the registry-layer decision, and the package [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/scope/README.md) owns the callable API and filtering semantics.
9
+
10
+ Sources: [`packages/core/scope/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/scope/src/index.ts) and [`packages/core/scope/src/store.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/scope/src/store.ts).
11
+
12
+ ## Identity and dispatch carrier
13
+
14
+ `ScopeKey` is an opaque object identity. The shipped loop uses the live `Agent` object as its own key, but the primitive never inspects the object.
15
+
16
+ ```ts type-equiv
17
+ /** An opaque, identity-compared scope key. */
18
+ type ScopeKey = object
19
+ ```
20
+
21
+ `Scoped<T>` is the compile-time brand on the opaque routing receiver returned by `scopeTarget(base, key)`. Scope-filtered event declarations require this carrier as their `this` type, while the real event subject remains an explicit argument.
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
+ ## Owned registration context
33
+
34
+ `Scope` pairs the tagged registration context with two teardown paths. `rawDispose` preserves the exact Cordis disposer identity needed by an ordered composite effect; `dispose()` is the public shared quiescence boundary for direct and racing callers.
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
+ ## Scoped registry layer
49
+
50
+ `ScopeLayer` represents one registry's complete contribution at the global or exact-scope level. A concrete layer may aggregate multiple named and anonymous tables; whole-layer emptiness lets `ScopedLayers` reclaim scoped state without discarding a sibling 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>` owns the eager global layer and lazily created exact-scope layers. Reads do not create layers: `peek(undefined)` means no overlay, while `merge()` materializes insertion-ordered global named entries followed by scoped shadows. Registrations use one context for both visibility and Cordis effect ownership, collect one synchronous undo before optional notification, return Cordis's exact disposer, and reclaim a scoped layer only when its complete `ScopeLayer` is empty.
61
+
62
+ `NamedEntries<V>` supplies insertion-ordered lookup and live iteration with caller-owned duplicate errors. `AnonymousEntries<V>` gives every append a unique identity so equal values remain independent. Iteration stays live within one nonempty table generation; draining the table detaches existing iterators from later insertions. Both return idempotent exact-entry undos; the shared `EntryValues` implementation interface is not public.