第 13 章
附录 A:术语表精校版
使用说明
这个附录是正文各章出现过的核心术语的精校词典。读者在某章卡住时,按术语名查回这里。仓库词汇表(docs/glossary.md)定下一条纪律:一个概念只用一个规范词(one canonical term per concept),本附录沿用这个口径,定义一律落到词汇表或源码的真实行号。
术语分两组。第一组是词汇表本身的六个条目域,共 22 个条目,全部精校收录,关键定义贴原文;第二组是正文高频术语,用 grep 对 chapters/ 目录逐词扫描后按实际出现收编。统计时正文共 11 章(第 12 章在并行写作,未纳入统计)。候选清单里 Typert、JSON-RPC 在正文零出现,其中 Typert 因对应 packages/typert 包存在且属第 12 章主题仍予收编,JSON-RPC 在语料中无定义页,按「定义必须落到真实行号」的纪律不收条目。每一条目给三样东西:一句白话定义、出处(引用块或行内行号)、与相关术语的差异。
一、词汇表六域(docs/glossary.md 全文精校)
capability-seam 域
seam
seam 是一个可换装的能力:一个 Service Definition 拥有 ctx.<key> 和词汇类型,配一个或多个 Provider 和 Consumer。它是第 7 章 shell 三件套、第 9 章 fs 三方(dsh-fs、dsh-fs-local、dsh-tool-fs)的通用骨架。
9- **seam** — a *swappable capability* with three roles: a **Service Definition** (the Cordis `Service` that owns its `ctx.<key>` and vocabulary types — an abstract class such as `ShellExecutor`, or a concrete registry such as `WebRuntime`, never a TypeScript `interface`), one or more **Service Providers**, and one or more **Consumers** that inject the service. `packages/shell` is the canonical example: `dsh-shell` (Service Definition), `dsh-bash-local` / `dsh-bash-sandbox` (providers), and `dsh-tool-bash` (Consumer). Roles normally occupy separate packages when they evolve independently, but a package may own multiple roles when they are one concern (`dsh-llm` owns its Service Definition and Consumer). The seam is the complete capability, never one role; reserve the term for that meaning and name a constituent by its role, class, service, contract, or extension point.与 Service(B 组)的差别:seam 指完整能力,Service Definition 只是其中一个角色。正文第 2 章「从 cordis.yml 到运行中的树」用 Loader 装载链演过一遍,第 7 章解剖了 shell 实例。
agent-scope 域
scope
scope 是每次 agent 注册的归属单位:一个贡献(工具、提示词片段、变量、restriction、监听器)要么全局,要么只属于一个 scope key。只有两层,扁平,不向下继承。正文第 5 章(system-prompt 组装)和第 11 章(subagent)用得多,正文统计 161 次。
13- **scope** — the unit of per-agent registration: a contribution (tool, prompt section, variable, restriction, listener) is either *global* (visible to every agent) or *scoped* (owned by exactly one [scope key](#scope-key)). Two levels, flat: scoped registrations do not inherit down to subagents; subtree behavior is expressed with [lineage](#lineage) data, never scope structure.与 shadowing 的关系:scope 决定「注册到哪一层」,shadowing 决定「同名时谁赢」。
scope key
scope 的透明身份,按对象同一性比较。仓库惯例是活 agent 自己当自己 scope 的 key。
14- **scope key** — the opaque identity a scope is keyed by, compared by object identity. The harness convention: a live agent is the key of its own scope. <a id="scope-key"></a>agent context(agent.ctx)
agent 的带作用域上下文。往它上面注册的东西同时获得两个性质:scope-visible 和 scope-lifetime,一个事实驱动两个结果。
15- **agent context (`agent.ctx`)** — the agent's scoped context; registrations through it are scope-visible AND scope-lifetime (one fact drives both), and listeners on it participate in that agent's scope-filtered dispatches. Registry-subject events may remain deliberately unfiltered under their own event contracts.scope carrier 与 scoped dispatch
这两个条目正文没直接用过,属于机制的内部件。scope carrier 是 scope 过滤派发携带的 thisArg,scopeTarget 造出来;scoped dispatch 是规则本身:关于某个 agent 活动的事件,用那个 agent 的 carrier 派发;关于注册表自身的事件(加了把工具)不过滤(glossary.md:16-17)。
shadowing
最具体者胜出的名字解析:某个 scope 里的同名工具、片段、变量替换掉全局的孪生,只对该 scope 生效。正文第 5 章用 9 次。工具层的落地在 packages/core/tools/README.md:20:ctx.tools.register 在 agent.ctx 上注册时,在该 agent 层 shadow 同名全局工具。
18- **shadowing** — most-specific-wins name resolution: a scoped tool/section/variable replaces its same-named global twin for that scope alone. The per-agent persona and per-agent tool-variant mechanism.restriction / scope-local registration
restriction 过滤全局工具集,scope-local 注册在过滤之后并入。被滤掉的全局工具从提示词消失,执行也拒绝,和「不存在」无从区分。正文第 5 章 20 次、第 6 章 1 次。
19- **restriction / scope-local registration** — a restriction (`tools.restrict`) filters the GLOBAL tool set for one scope (compose by intersection); scope-local registrations are merged after that filter. A filtered-away global tool is absent from the prompt AND refuses execution, indistinguishably from a nonexistent one.与 shadowing 的差别:shadowing 是同名替换,restriction 是过滤掉,两者可以叠用(先滤后并)。
setup window 与 lineage
setup window 是创建者组装 agent 作用域世界的时段:CreateAgentOptions.setup 里,scope 和 agent 对象已存在、agent 或会话还没发布、agent/session-start 还没触发、第一个提示词还没组装。setup 只注册,不驱动。lineage 是父子关系的事实数据(parentSession、持久的 delegationDepth、运行时的 subagentDepth),永远不影响可见性(glossary.md:20-21)。
goal 域
goal
挂在一个已有会话上的持久完成目标,带修订的 active/paused/blocked/complete 阶段和 goal-round 上限。goal 是状态,调度器和独立会话都不是它;会话日志是它的事实来源。正文第 11 章用了 81 次,包实现在 packages/goal。
25- **goal** — one durable completion objective attached to an existing session, with a revisioned `active` / `paused` / `blocked` / `complete` phase and a goal-round cap; `blocked` retains a policy code and explanation. A goal is state, not a scheduler or a separate conversation; the session log remains its source of truth.goal round
当前 goal 被允许的一个继续周期。同一个会话驱动把一轮 goal round 物化成一个 goal 来源的 turn,这个 turn 里可以有零个或多个 step;同会话里无关的人类 turn 不消耗 goal-round 上限。
26- **goal round** — one continuation cycle admitted for the current goal. The same-session driver materializes a goal round as one goal-sourced [turn](#turn), which can contain zero or more steps; unrelated human turns in the same session do not consume the goal-round cap. <a id="goal-round"></a>与 Ralph round 的差别:goal round 留在原会话,Ralph round 是新开一个干净子会话。
goal activation
进程本地的继续许可:arm 或 disarm。它刻意不进持久化回放,所以 resume 和 fork 之后必须先有人类授权的恢复操作(/goal 或模型工具),自动继续才放行。正文里这个术语本身没出现,机制在第 11 章有展开。
27- **goal activation** — process-local permission for a continuation consumer to admit another goal round. Activation is either `armed` or `disarmed`; it is deliberately absent from durable replay, so resume and fork require a later human-authorized resume mutation through `/goal` or the model tool before automatic work.human command 域
human command
斜杠开头、由面向人的适配器经 ctx.commands 解释执行的指令,不变成模型消息。它和模型工具、和 ctx.shell 的 shell 命令执行是三条分开的路。
31- **human command** — a slash-prefixed instruction interpreted and executed by a human-facing adapter through `ctx.commands`, without becoming a model message. It is distinct from a model-facing tool and from shell command execution through `ctx.shell`.command plane 与 goal command
command plane 是发现、解析、派发、取消、结果渲染这五件事的归属,由 UI 适配器和命令插件拥有;命令输出是 UI 状态,除非 handler 另行改动持久领域。goal command 是 dsh-command-goal 贡献的 /goal 命令,直接观察或改动当前 goal,而每条持久、模型可见的记录都由 goal 领域拥有(glossary.md:32-33)。
loop hierarchy 域
turn
一个会话里一次获准输入的处理,模型和它的工具停手或终态策略介入为止。正文高频词之首,542 次。
37- **turn** — one drain of admitted input in a session, ending after the model and its tools stop or a terminal policy intervenes. <a id="turn"></a>step
一次模型请求加上它的响应引发的所有工具执行。一个 turn 含零个或多个 step。正文 198 次,第 4 章是主战场。
38- **step** — one model request plus the tool executions caused by its response; a turn contains zero or more steps. <a id="step"></a>round
外层策略的一轮迭代,里面装一个 turn,比如 goal round 或一次全新 agent 的 Ralph 尝试。round 的计数器属于那个策略,不数会话里每一次 turn。
39- **round** — an outer policy iteration containing a turn, such as a [goal round](#goal-round) or one fresh-agent Ralph attempt. Round counters belong to that policy and do not count every turn in a session. <a id="round"></a>Ralph 域
Ralph loop
一种前台全新 agent 工作流:向着一个不可变目标跑。它是从 workflow 和 subagent 原语组合出来的模型工具策略,不是同会话 goal、不是 agent-loop 模式、不是调度器、也不是通用工作流脚本。正文 11 章里只出现 6 次(都在第 3 章),因为完整机制对应章节尚在写作,本附录以词汇表与 packages/workflow 为准收录。
43- **Ralph loop** — one foreground fresh-agent workflow run toward an immutable objective. It is a model-facing tool policy composed from workflow and subagent primitives, not a same-session goal, agent-loop mode, scheduler, or generic workflow-script feature. <a id="ralph-loop"></a>Ralph round
Ralph loop 里的一次全新子会话。子会话不继承父会话或前一轮的对话种子;共享工作区加一个有界的 Ralph handoff 负责跨轮状态。
44- **Ralph round** — one fresh child session in a [Ralph loop](#ralph-loop). The child receives no parent or prior-child conversation seed; the shared workspace and one bounded [Ralph handoff](#ralph-handoff) carry cross-round state. <a id="ralph-round"></a>Ralph handoff
从一轮 Ralph 传给下一轮的规范化有界结构报告,含状态、摘要、证据、下一步、阻塞文本。它补充共享工作区,不取代工作区成为权威。
45- **Ralph handoff** — the normalized bounded structured report passed from one continuing Ralph round to the next, containing status, summary, evidence, next steps, and blocker text. It supplements the shared workspace rather than replacing it as authority. <a id="ralph-handoff"></a>二、正文高频术语
基础设施层
Context
核心对象,服务、事件、生命周期 API 全从 ctx 出去。正文 123 次,第 1、5、6 章最多。cordis 的 API 镜像文档在 docs/cordis-api/,这是 dsh 自带的 cordis 参考面。
6The context is the core Cordis object: every service, event, and lifecycle API is reached through `ctx`. Event methods are documented on [Events](events.md), effects and the current fiber on [Fiber](fiber.md), and plugin loading on [Registry](registry.md).与 agent.ctx 的差别:ctx 是全局上下文,agent.ctx 是带 scope 的上下文,见词汇表 agent context 条目。
Service
上下文服务的基类。子类作为插件装载时把自己注册成 ctx.<name>。正文 59 次,第 7 章最多(25 次)。
6The base class for context services. A subclass loaded as a plugin registers itself as `ctx.<name>`.与 seam 的差别:Service 是基类名,seam 是三个角色的完整能力。第 9 章 FileSystem extends Service(fs/src/index.ts:86-89)就是服务注册的标准写法。
Fiber
一个已装载的插件实例:它的生命周期状态、校验过的配置、注册的 effect。ctx.fiber 是当前 fiber,ctx.effect() 委托给它。正文 15 次,集中在第 1、2 章。
6A fiber is one loaded plugin instance: its lifecycle state, validated config, and registered effects. `ctx.fiber` is the current fiber, and `ctx.effect()` delegates to it.effect
向 fiber 注册一个带清理的副作用:execute 立即跑,产出的 disposer 被收集,在「返回的 disposer 被调用」和「fiber 卸载」两个时点先到者触发,逆序执行。正文 60 次,第 1 章 31 次。
12 * Register a cleanup-aware effect on this fiber.13 *14 * `execute` runs immediately; the disposers it produces are collected and15 * run (in reverse order) either when the returned disposer is called or16 * when the fiber unloads, whichever comes first. Calling the disposer twicedisposer
effect 产出的清理函数。正文 28 次。调用两次是 no-op;已卸载的 fiber 上再注册 effect 抛 INACTIVE_EFFECT(fiber.md:22-30)。第 9 章 fs-observation-policy 的 apply 里 ctx.effect(() => () => gate.clear(), ...)(fs-observation-policy/src/index.ts:106-109)是标准用法:卸载时清掉观察状态。
DispatchMode
事件派发策略,五种:emit、parallel、serial、bail、waterfall。正文只出现 3 次,但五种模式遍布全书事件语义。
193`emit` runs synchronous listeners without awaiting them, `parallel` awaits all listeners together, `serial` awaits them in order until one bails, `bail` stops on the first synchronous bail value, and `waterfall` composes listeners around a final `next` callback.waterfall
瀑布式事件派发:监听者围着最终的 next 回调组合。dsh 的注册入口三件套是 ctx.effect()、ctx.on()、ctx.waterfall()。正文 67 次,第 6、9 章最多。
5npm scope: `@deepseek-ai/dsh-*`; Cordis `Service` subclasses and function plugins contribute through `ctx.effect()`, `ctx.on()`, or `ctx.waterfall()`. Rules: [package](AGENTS.md), [root](../AGENTS.md#conventions).第 9 章的 fs/write-intent 是 unbound waterfall:工具插件派发、不绑定服务实例,监听器不调 next 就占住单槽(事件闸门笔记第 111 行)。第 6 章 llm/stream 是服务绑定 waterfall 的对照。
inject 与 provide
注册服务引用与提供服务的两件套。规范条款把边界讲清:可选服务用 ctx.get(name),ctx.<name> 留给声明式注入,属性代理对拓扑敏感,严格的 ctx.get 读全局服务存储。正文 inject 37 次、provide 在机制意义上集中于第 7、9 章的服务注册。
6- **Optional services use `ctx.get(name)`.** Reserve `ctx.<name>` for declared injections; the property proxy is topology-sensitive, while strict `ctx.get` reads the global service store ([postmortem](../docs/postmortem/0001-acp-default-export-drops-inject.md)).第 6 章审批 seam 就是机会式消费的活例:ctx.get('approval'),无静态注入,没部署就退化为拒绝(tools/README.md:31)。
启动与配置层
profile、bundle、patch
profile 是 $DSH_HOME/profiles/<name> 下的一个目录,bundle 是声明了补丁清单的 npm 包,patch 是补丁层。装配顺序:bundle 按 profile 清单顺序叠,然后 profile 自己的补丁,再 launcher 层(--patch 与命令行派生的补丁)。正文第 2 章 87 次、69 次、174 次,是全书的配置骨架。
7 * `dsh.profile` with its ordered `bundles` list) and a `cordis.patch.yml`8 * (the user's own patch layer, applied after every bundle layer). Bundles are9 * npm packages whose manifest declares10 * `"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }`; the tree is11 * composed by applying each bundle's patch list in `dsh.profile.bundles` order over12 * an empty entry list, then the profile's own patches, then any launcher13 * layers (`--patch` files and flag-derived patches).三者的层级关系:profile 是目录,bundle 是包的补丁提供方,patch 是实际生效的配置差量。
会话日志层
SessionEvent
会话日志的事件类型,按类型判别联合展开。每个事件带 type、单调 seq、毫秒时间戳、data,事件类型集合由 SessionEventMap 拥有。正文第 3 章 37 次。
408export type SessionEvent<T extends SessionEventType = SessionEventType> = {409 [K in SessionEventType]: {410 type: K411 /** Monotonic sequence number within the session. */412 seq: number413 /** Unix epoch milliseconds. */414 time: number415 data: SessionEventMap[K]SESSION_FORMAT_VERSION
会话日志格式版本,固定钉在 0。后端拒绝任何其他版本并说明方向:新版本提示升级 harness,旧版本说明尚无升级路径。正文第 3 章 10 次。
143- **`SESSION_FORMAT_VERSION` stays pinned at `0`** — pre-release, no broad compatibility implied: `Session` accepts only current seed shapes, and a backend refuses any other version naming the direction (newer: "written by a newer harness — upgrade"; older: no upgrade path ships yet). Unknown event types refuse the same way unless marked `ignorable` in the envelope; the versioning mechanism is the [session-log-version-mechanism note](../../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md). Narrow storage import upgrades belong to the persistence boundary ([policy](../../../AGENTS.md), [pre-identity message recovery](../../../.agents/notes/implemented/bug-fix/2026-07-28-load-pre-identity-session-messages.md)).ignorable
事件信封上的可选标记:带上它,读取器遇到不认识的事件类型可以安全跳过;缺了就是必需,不认识的事件类型会拒绝会话重建。正文第 3 章 27 次。
83- `ignorable?: true` — marks an event a reader may safely skip when it does not recognize the type; absent means required, so an unknown-type event refuses session reconstruction ([mechanism](../../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md)).与「required-on-read」的关系:后者是第 3 章正文为「缺少 ignorable 标记即必须读取」造的简称,语义完全由本条定义,本附录并入此处不单列。
Model-visible ⟺ logged
模型可见的,就是日志里有的。仓库规范条款把它写成写作纪律:提示词、工具 schema、结果、诊断里只放任务相关概念,不放 UI、传输、实现词汇,模型可见文本按字钉死。正文第 3、4 章共 11 次。
13- **Write model-facing contracts from the model's perspective.** Prompts, tool schemas, results, and diagnostics contain only task-relevant concepts, not UI, transport, or implementation vocabulary. Pin stable model-visible text verbatim and dynamic behavior through snapshots or end-to-end coverage.claim
turn 认领自己的输入。认领机制把「一次 turn 认领了输入」和「工作没跑就被丢弃」分开记账:inbox 每次变更记 removedCount,取消标 outcome: canceled。正文 86 次,第 4 章 76 次。
6 * no-op turns a rejection or an empty claim produces, so reading turns in7 * isolation either credits cut-short work as finished or convicts every no-op.8 * The missing fact is the inbox's own record: {@link Inbox} logs each mutation9 * with `removedCount` and marks a cancellation `outcome: 'canceled'`, which10 * separates a turn claiming its input from work being dropped unrun.11 *12 * @module @deepseek-ai/dsh-agent/consumed-work循环与执行层
ReactLoopAgent
agent-loop 的驱动类:实现 Agent 接口,持 inbox 和 phase。正文第 4 章 7 次、第 5 章 2 次。第 4 章用它对比 claude-code 的隐式主循环(上游无源码,检索关键词 main loop、ReactLoop、turn、step)。
64export class ReactLoopAgent implements Agent {65 readonly inbox: Inbox66 private phase: PhasePhase
ReactLoopAgent 的内部状态机,三态:idle、maintenance、running。idle 带 lastTurn,maintenance 带 abort 与 wakeRequested,running 带当前 turn/step 计数。外部 AgentStatus 只有 idle/running 两态(runtime-types.ts:43-50)。
38type Phase =39 | { kind: 'idle'; lastTurn: number }40 | {41 kind: 'maintenance'42 abort: AbortController43 lastTurn: number44 wakeRequested: boolean45 }46 | { kind: 'running'; abort: AbortController; turn: number; step: number; wakeRequested: boolean }agent/pre-step
每轮第一个 step 之前的事件检查点。tmux-context 插件是活例:它前置注册一个 pre-step 监听器,只在每轮第一个 step 跑,注入时机到了就跑一条只读命令并往拟议批次里加一条带来源的 UserMessage。正文 24 次,第 4 章 17 次。
20The plugin prepends an `agent/pre-step` listener that runs only on the first step of each turn. When due, it runs one read-only command through the `ctx.shell` executor service:tools/pre-execute 与 tools/post-execute
工具执行管线的两端守卫事件。pre-execute 做扩展性 deny/ask,post-execute 做结果决策,中间是 tools/execute,末端是 tools/result。正文 pre-execute 40 次、post-execute 43 次,第 6 章是主战场。
77- Hooks and policy: the relevant `agent/*` checkpoints plus the guarded `tools/pre-execute` → `tools/execute` → `tools/post-execute` → definition-owned `finalizeContent` → `tools/result` pipeline; exact event signatures and modes live in the generated regions of [core.md](../../../docs/subsystems/core.md#cordis-surface) and [tools.md](../../../docs/subsystems/tools.md#cordis-surface)approval
通道无关的一次性审批 seam:ctx.approval.request(req) 返回 allowed-once、rejected、cancelled、unavailable;缺失或失败的应答者 fail closed,一次授权只适用于所请求的动作。正文 91 次,第 6 章 82 次。
5Channel-neutral one-shot approval seam. `ctx.approval.request(req)` returns `allowed-once`, `rejected`, `cancelled`, or `unavailable`; missing or failing answerers fail closed, and a grant applies only to the requested action. Exact event signatures live in the generated region of [approval.md](../../../docs/subsystems/approval.md#cordis-surface).permission-presets
面向用户的权限预设:ctx.permissionPresets,每个配置名把 sandbox/mode 和 approval/policy 捆在一起。默认两档:workspace-write(workspace-write + ask)和 danger-full-access(danger-full-access + never)。正文 3 次。
5User-facing permission presets through `ctx.permissionPresets` ([`PermissionPresetService`](src/index.ts)). Each configured name bundles `sandbox/mode` with `approval/policy`; the defaults are `workspace-write` (`workspace-write` + `ask`) and `danger-full-access` (`danger-full-access` + `never`). UI adapters may expose the table as one selector, while sandbox execution and approval continue to consume their own knobs.与 approval 的差别:approval 是决策机制,preset 是把两个决策旋钮打包给用户挑的配置层。
PreToolDecision
pre-execute 的返回类型:allow、deny(带原因)、ask(带可选原因)。刻意不提供输入改写;ask 在有 approval seam 时被服务,否则退化为 deny。正文第 6 章多处使用。
49- `PreToolDecision` — `{kind:'allow'}` | `{kind:'deny', reason}` | `{kind:'ask', reason?}`. Input rewrite is deliberately not offered; `ask` is serviced by [`ctx.approval`](../../interaction/user-approval/README.md) when mounted and otherwise degrades to deny.hooks 桥
把 claude-code 风格的 PreToolUse/PostToolUse 钩子映射到 tools 管线事件。PreToolUse 监听 tools/pre-execute,deny/ask 直译;PostToolUse 监听 tools/post-execute,deny 变成带反馈的 block。正文第 6 章 13 次。
237 // --- PreToolUse → PreToolDecision. Matcher subject is the tool name. ---238 ctx.on('tools/pre-execute', async (exec, next): Promise<PreToolDecision> => {239 const turn = lastTurn(exec.agent)240 const merged = await runPoint('PreToolUse', exec.name, preToolPayload(ctx, exec), { ...exec.agent ? { agent: exec.agent } : {}, turn, signal: exec.signal })241 if (merged.decision === 'deny') return { kind: 'deny', reason: merged.reason ?? 'blocked by PreToolUse hook' }242 if (merged.decision === 'ask') return { kind: 'ask', ...merged.reason !== undefined ? { reason: merged.reason } : {} }243 return next()244 })245246 // --- PostToolUse → PostToolDecision. Matcher subject is the tool name. ---247 ctx.on('tools/post-execute', async (exec, result, next): Promise<PostToolDecision> => {248 const turn = lastTurn(exec.agent)249 const merged = await runPoint('PostToolUse', exec.name, postToolPayload(ctx, exec, result), { ...exec.agent ? { agent: exec.agent } : {}, turn, signal: exec.signal })250 const context = contextFrom(merged)251 if (merged.decision === 'deny') {252 return { kind: 'block', feedback: [{ type: 'text', text: merged.reason ?? 'blocked by PostToolUse hook' }], ...context ? { additionalContexts: [context] } : {} }253 }提示与工具层
system-prompt
系统提示词装配。注册表自动把工具 schema 经 ctx.systemPrompt.tools() 送进系统提示词组装;审批 seam 走 ctx.get('approval') 机会式消费。正文 23 次,第 5 章 20 次。
31`SystemPrompt` — the registry automatically feeds its tool schemas into the system-prompt assembly via `ctx.systemPrompt.tools()`. The approval seam is consumed opportunistically instead (`ctx.get('approval')`, no static inject): a deployment without it keeps the ask→deny degrade, and the registry stays active either way.tool schema
工具对模型暴露的参数契约。与 system-prompt 同源:schema 进提示词,模型按 schema 填参。第 5 章 32 次。schema 之外的执行层判定在 completeScheduledExecution(tools/src/index.ts:1346-1362)按 kind 三分支。
文件与沙箱层
FS_SANDBOX_DENIED
文件沙箱栅栏的统一错误码。read-only 模式拒绝一切变更,workspace-write 模式用重新归一化的新鲜路径查可写根集合,越界即抛此码(fs-sandbox/src/index.ts:131-132、144-146)。正文第 9 章 4 次。模型侧靠 [sandbox: …] 前缀识别,与 Bash 沙箱共用同一条识别路径。
intent 槽
事件闸门的单槽决策位。fs/write-intent 与 fs/edit-intent 是 unbound waterfall:工具带一个返回 undefined 的默认 thunk 派发,监听器不调 next 就完整占住,先注册者赢。fs/observed 是 fire-and-forget 的记录事件,监听器必须同步纯副作用(事件闸门笔记第 111 行;docs/subsystems/filesystem.md:185)。
landlock
Linux 上的强制访问控制机制,dsh 沙箱后端之一。判定规则:Landlock 要求退出码 125 且排除部分强制执行通知后仍有 landlock-run: 致命行,才算 runner 失败;带通知的子进程按子进程结果处理。Bubblewrap 和 Seatbelt 只看签名。正文第 8 章 30 次。
11Policy is per call; the provider stores only the mechanism and cached runner verdict. Each wrap reports enforcement completeness plus backend-specific denial signatures and runner-failure rules. Landlock requires exit 125 and a `landlock-run:` fatal line after excluding only the exact partial-enforcement notice; a notice with child exit 1, 2, or 125 remains a child outcome. Bubblewrap and Seatbelt remain signature-only because neither public contract reserves a launcher-failure status. Consumers spawn the returned argv directly, so a missing or unexecutable runner is an out-of-band spawn failure while a successfully launched child exit 126 or 127 remains ordinary. `runnerCommand` skips probes and requires one or more non-empty, single-line, case-insensitive `runnerFailureSignatures` entries for the custom runner's own fatal dialect. Because its mechanism is unknown, it carries both Linux denial dialects. `probeTimeoutMs` bounds functional probes. The [sandbox Agent Note](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.md) owns selection and failure semantics.进程树(subprocess)
subprocess seam:一个执行世界共用的进程底座。可执行查找、完全规格化的受管子进程树(裸 stdio 或收集式)、一个拥有 PTY 分配、前台进程组、会话清理的深层终端原语。命令默认化、shell 语义、截止时间留给消费方。正文第 7、8 章共 15 次。
5The shared process substrate for one execution world: executable lookup, fully-specified managed child-process trees with raw or collected stdio, and one deep terminal-process primitive that owns PTY allocation, foreground groups, and provider-observable session cleanup. Command defaulting, shell semantics, deadlines, protocol framing, readiness, and presentation stay with consumers — the [bash executors](../shell/README.md), [LSP host](../lsp/README.md), [PTY shell backend](../terminal/README.md), and [ACP subagent backend](../subagent/README.md). See the [subprocess seam Agent Note](../../.agents/notes/implemented/architecture/2026-07-26-subprocess-seam.md).e2b
实验性的远程运行时组合 POC:把文件系统与进程执行放进一个 E2B Linux 沙箱。E2B 只提供沙箱生命周期和两个底层 OS 适配器,更高能力由 provider 无关的消费方构建。正文第 8 章 25 次,状态是 POC。
5An experimental provider-composition POC that places one filesystem/process execution world in an E2B Linux sandbox. E2B supplies only sandbox lifecycle and the two fundamental OS adapters; provider-neutral consumers build higher capabilities above them.LLM 层
twin adapters(孪生适配器)
LLM 适配器成对出现:适配器在 seam 上注册提供方路由,重试与 token 计量是独立消费方。正文第 10 章 7 次。设计原理在孪生适配器 Agent Note(2026-06-13-twin-llm-adapters.md)。
15Adapters register provider routes on the seam; retry and token measurement remain separate consumers. The child READMEs own routing, metadata, replay, and provider-wire details; the [LLM architecture decisions](../../.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md) own the rationale.StreamChunk(chunk)
流式协议的原生分片判别联合:block-start、text-delta、reasoning-delta、tool-call-delta、block-end、usage、finish。usage 必须在 finish 之前,finish 之后不能再有。正文 chunk 159 次,第 10 章 96 次。
192type StreamChunk =193 | { type: 'block-start'; index: number; blockType: ContentBlockType }194 | { type: 'text-delta'; index: number; text: string }195 | { type: 'reasoning-delta'; index: number; text: string }196 | { type: 'tool-call-delta'; index: number; id: CallId; name?: string; argumentsDelta: string }197 | { type: 'block-end'; index: number; block: ContentBlock }198 | { type: 'usage'; usage: TokenUsage }199 | {200 type: 'finish'201 reason: FinishReason202 /** Replay metadata for a successful response; see {@link ReplayEnvelope}. */203 replayState?: ReplayEnvelope204 }委托层
subagent
让 agent 把工作委托给子 agent 的能力族,多个命名 provider 可共存于一个上下文。正文 110 次,第 11 章 101 次。
5This family lets an agent delegate work to child agents. Multiple named providers may coexist in one context.delegationDepth
会话元数据里的递归预算。创建元数据带 cwd、parentSession、seedLength、origin、delegationDepth,是持久会话数据,会话边界在异步 setup 开始前校验并快照。与 lineage(词汇表)的关系:delegationDepth 是 lineage 的一个字段。正文第 11 章 15 次。
84 * Session creation metadata: validated absolute `cwd`, `parentSession`85 * fork lineage, the `seedLength` seed boundary, the coarse `origin`86 * classification, and the `delegationDepth` recursion budget. Mirrors the87 * `cwd`/`parentSession`/`seedLength`/`origin`/`delegationDepth` fields of88 * {@link CreateSessionOptions.meta} in dsh-session (the internal-only89 * `createdAt`, used when reconstructing a persisted session, is deliberately90 * excluded — a factory caller never sets it). This is durable session data,91 * so the session boundary validates and snapshots it before asynchronous92 * setup begins.93 */94 readonly meta?: {95 readonly cwd?: string96 readonly parentSession?: SessionId97 readonly seedLength?: number98 readonly origin?: 'subagent'99 readonly delegationDepth?: numberworkflow
工作流 seam、worker 线程引擎、面向模型的 workflow/ralph 工具。worker 线程隔离执行但与主事件循环隔离,那层隔离不是安全边界。正文 55 次,第 11 章 41 次。
35| [`workflow/`](workflow/README.md) | Workflow seam, worker-thread engine, and model-facing `workflow`/`ralph` tools | Product — stable API |14Worker threads isolate workflow execution from the host event loop but are not a security boundary. See the [dynamic-workflow](../../.agents/notes/implemented/feature/2026-07-05-dynamic-workflows.md) and [Ralph tool](../../.agents/notes/implemented/feature/2026-07-19-fresh-agent-ralph-workflow-tool.md) decisions.goal(正文侧)
goal 域在词汇表已收,正文侧补包位置:packages/goal 提供持久目标状态,独立于消费它的模型工具与继续策略,状态属于所属会话日志,消费方只依赖 dsh-goal。
5Durable objective state for an agent session, owned independently of the model-facing tools and continuation policy that consume it. Goal state is part of the owning session log; consumers depend on `dsh-goal`, never on the concrete agent loop.协议层
Typert
把源码分析、运行时存储、Loader 发现三者分开的解析与装载基建。正文当前零出现(对应第 12 章在写作),按 packages/typert 收录。
5Typert separates source analysis, runtime storage, and Loader discovery.ACP
Agent Client Protocol,让外部程序化客户端驱动 harness agent 的互操作传输层,不是表现层也不是人类交互层。配套的进程外 subagent 客户端实现 subagent provider 接口。正文第 6、11 章共 3 次。
5The ACP group exposes harness agents to programmatic clients over the Agent Client Protocol. It is an interoperability transport, not a presentation or human-interaction layer; the matching out-of-process subagent *client* lives in [`subagent/subagent-acp`](../subagent/subagent-acp/README.md) because it implements the subagent provider interface.MCP
Model Context Protocol,连接 harness 与 MCP 生态的桥接包组。正文第 8、9 章共 3 次。
5Packages bridging the harness to the MCP ecosystem.SDK
从另一个进程驱动 harness 运行时的协议栈。调用方提供运行时可执行文件和它的 cordis.yml;本组不创建、不配置、不构建、不启动开发者项目。正文 12 次,第 10 章 7 次。
5This group contains the protocol stack for driving a Harness runtime from another process. Callers supply the runtime executable and its `cordis.yml`; this group does not create, configure, build, or launch developer projects. The [TypeScript SDK decision](../../.agents/notes/implemented/feature/2026-07-27-typescript-sdk-and-sdk-subagent-backend.md) owns the client contract, and the [toolchain removal](../../.agents/notes/implemented/simplification/2026-08-11-remove-sdk-project-toolchain.md) owns the product boundary.