docs: address prose review findings
This commit is contained in:
@@ -1196,9 +1196,10 @@ export interface Config {
|
||||
* Override the runner argv; bwrap-shaped profile arguments are appended. A
|
||||
* non-empty override asserts full enforcement and skips built-in selection and
|
||||
* probing. A runner that starts but refuses its profile must be identifiable by
|
||||
* {@link runnerFailureSignatures}. Consumers classify spawn rejection; only
|
||||
* attributable `ENOENT` or `EACCES` whose error path equals runner argv[0] becomes an
|
||||
* infrastructure failure.
|
||||
* {@link runnerFailureSignatures}. Consumers classify a spawn rejection only after
|
||||
* confirming the workdir is usable. `ENOENT` or `EACCES` identifies the runner when
|
||||
* `error.path` equals argv[0] and `error.syscall` is `spawn` or `spawn <runner>`, or
|
||||
* when `error.path` is absent and `error.syscall` is exactly `spawn <runner>`.
|
||||
*/
|
||||
runnerCommand?: string[]
|
||||
/**
|
||||
|
||||
@@ -68,7 +68,8 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
* (e.g. the `assistant/chunk` seqs that built an `assistant/message`,
|
||||
* or the surface nodes shadowed by a compaction replace node). An
|
||||
* `assistant/message` may carry a present empty array for a known empty
|
||||
* provider stream; omission means the source stream was not recorded.
|
||||
* provider stream; when the field is absent, the event does not record which
|
||||
* earlier events produced the message.
|
||||
*/
|
||||
sourceEventSeqs?: number[]
|
||||
/** How this event entered the surface; absent for non-surface events. */
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/session.md
|
||||
session.md: 6fb39e946cf5acdc407aab99888d40960d617248
|
||||
session.zh.md: 30edd630b4c945d3b696b5ac346b4bcebfb3df16
|
||||
session.md: 4b057317969c8dc59c899fb07812e01a0b5d94d3
|
||||
session.zh.md: 804edc32635ddfcc1335ecd9c0a6c4df4f998594
|
||||
|
||||
@@ -221,7 +221,8 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
* (e.g. the `assistant/chunk` seqs that built an `assistant/message`,
|
||||
* or the surface nodes shadowed by a compaction replace node). An
|
||||
* `assistant/message` may carry a present empty array for a known empty
|
||||
* provider stream; omission means the source stream was not recorded.
|
||||
* provider stream; when the field is absent, the event does not record which
|
||||
* earlier events produced the message.
|
||||
*/
|
||||
sourceEventSeqs?: number[]
|
||||
/** How this event entered the surface; absent for non-surface events. */
|
||||
@@ -232,7 +233,7 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
|
||||
`SessionEventType = keyof SessionEventMap`. Because `SessionEventMap` is merge-extensible, switches over `SessionEvent` must NOT use `assertNever` — a plugin-added variant is a valid unknown value; handle the known cases and fall through `default`.
|
||||
|
||||
For `assistant/message`, a present `sourceEventSeqs: []` is a complete known-empty provider stream, while an absent field means the source stream was not recorded in a legacy or foreign event. The loop writes the field for every successful model call; every other surface event requires a non-empty list when the field is present.
|
||||
For `assistant/message`, a present `sourceEventSeqs: []` is a complete known-empty provider stream, while a legacy or foreign event with no field does not record which earlier events produced the message. The loop writes the field for every successful model call; every other surface event requires a non-empty list when the field is present.
|
||||
|
||||
## Surface types
|
||||
|
||||
@@ -285,9 +286,9 @@ interface SurfaceIntent {
|
||||
surfaceOp: SurfaceOp
|
||||
/**
|
||||
* Complete set of known source-event seqs. `assistant/message` may use a
|
||||
* present empty array for a known empty provider stream; omission means its
|
||||
* source stream was not recorded. Other surface events require a non-empty set
|
||||
* when this field is present.
|
||||
* present empty array for a known empty provider stream; when the field is
|
||||
* absent, the event does not record which earlier events produced the message.
|
||||
* Other surface events require a non-empty set when this field is present.
|
||||
*/
|
||||
sourceEventSeqs?: number[]
|
||||
}
|
||||
@@ -295,7 +296,7 @@ interface SurfaceIntent {
|
||||
|
||||
Required for `SurfaceEventType` events — every message-producing event must declare how it joins the surface, the sole source of derived model history. A human-facing transcript is the other projection and reads the log's append-origin events instead, because the surface deliberately shadows the ranges a replacement summarizes (`isAppendSurfaceEvent` in [dsh-session](../../packages/core/session/README.md)). Non-surface types reject it at compile time.
|
||||
|
||||
Only `assistant/message` may carry a present empty `sourceEventSeqs`; omission means the source stream was not recorded and does not assert that the stream was empty.
|
||||
Only `assistant/message` may carry a present empty `sourceEventSeqs`; when the field is absent, the event does not record which earlier events produced the message, and the provider may still have emitted chunks.
|
||||
|
||||
### `SessionSurface` — the live readonly surface projection
|
||||
|
||||
@@ -577,7 +578,7 @@ Activity ordering excludes the boundary through `lastActivityTime(events)`: pick
|
||||
|
||||
## Plugin-contributed log-only events
|
||||
|
||||
A plugin may declaration-merge extra `SessionEventMap` types. These are **log-only**: NOT `SurfaceEventType`s (they carry no `surfaceOp` and contribute nothing to derived history). Their owner decides whether they belong to an open execution turn or may stand between turns, and enforces any relation in its own invariant companion. The generated [persistence log event catalog](../persistence-catalog.md) enumerates every core and plugin-contributed event with its payload, surface badge, cited source-event seqs, and declaration site; the compaction seam's `compact/*` semantics are discussed on [compaction.md](compaction.md).
|
||||
A plugin may declaration-merge extra `SessionEventMap` types. These are **log-only**: NOT `SurfaceEventType`s (they carry no `surfaceOp` and contribute nothing to derived history). Their owner decides whether they belong to an open execution turn or may stand between turns, and enforces any relation in its own invariant companion. The generated [persistence log event catalog](../persistence-catalog.md) enumerates every core and plugin-contributed event with its payload, surface badge, and declaration site; the compaction seam's `compact/*` semantics are discussed on [compaction.md](compaction.md).
|
||||
|
||||
The hook bridges' `hook/invoked` / `hook/result` pairs (from `@deepseek-ai/dsh-hook-protocol`) correlate by `handlerId`. `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `Stop` fire inside the loop's open turn, so their `hook/*` records are turn-enclosed by construction. `SessionStart` gets no `hook/*` record because it runs before turn 1; its context remains pending in the inbox until a waking delivery opens a turn (see [the hook-bridges Agent Note](../../.agents/notes/implemented/feature/2026-06-30-hook-bridges.md)).
|
||||
|
||||
|
||||
@@ -223,7 +223,8 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
* (e.g. the `assistant/chunk` seqs that built an `assistant/message`,
|
||||
* or the surface nodes shadowed by a compaction replace node). An
|
||||
* `assistant/message` may carry a present empty array for a known empty
|
||||
* provider stream; omission means the source stream was not recorded.
|
||||
* provider stream; when the field is absent, the event does not record which
|
||||
* earlier events produced the message.
|
||||
*/
|
||||
sourceEventSeqs?: number[]
|
||||
/** How this event entered the surface; absent for non-surface events. */
|
||||
@@ -234,7 +235,7 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
|
||||
`SessionEventType = keyof SessionEventMap`。由于 `SessionEventMap` 可通过合并扩展,对 `SessionEvent` 的 switch 语句禁止使用 `assertNever`:插件添加的变体是合法的未知值;处理已知 case 后在 `default` 中放行。
|
||||
|
||||
对于 `assistant/message`,存在的 `sourceEventSeqs: []` 表示提供方流已知且完整地为空;字段缺失则表示旧格式或外部事件没有记录源流。agent loop 会为每次成功的模型调用写入该字段;其他 surface 事件只要包含该字段,其列表就必须非空。
|
||||
对于 `assistant/message`,存在的 `sourceEventSeqs: []` 表示提供方流已知且完整地为空;旧格式或外部事件缺少该字段时,没有记录这条消息由哪些早期事件产生。agent loop 会为每次成功的模型调用写入该字段;其他 surface 事件只要包含该字段,其列表就必须非空。
|
||||
|
||||
## Surface 类型
|
||||
|
||||
@@ -287,9 +288,9 @@ interface SurfaceIntent {
|
||||
surfaceOp: SurfaceOp
|
||||
/**
|
||||
* Complete set of known source-event seqs. `assistant/message` may use a
|
||||
* present empty array for a known empty provider stream; omission means its
|
||||
* source stream was not recorded. Other surface events require a non-empty set
|
||||
* when this field is present.
|
||||
* present empty array for a known empty provider stream; when the field is
|
||||
* absent, the event does not record which earlier events produced the message.
|
||||
* Other surface events require a non-empty set when this field is present.
|
||||
*/
|
||||
sourceEventSeqs?: number[]
|
||||
}
|
||||
@@ -297,7 +298,7 @@ interface SurfaceIntent {
|
||||
|
||||
对 `SurfaceEventType` 事件必填:每个产生消息的事件都必须声明它如何加入 surface(派生模型历史的唯一来源)。面向人类的记录(transcript)是另一个投影,读取的是日志中追加来源的事件,因为 surface 会有意遮蔽替换所概括的范围(见 [dsh-session](../../packages/core/session/README.md) 的 `isAppendSurfaceEvent`)。非 surface 类型在编译期拒绝此参数。
|
||||
|
||||
只有 `assistant/message` 可以携带存在但为空的 `sourceEventSeqs`;省略该字段表示源流没有记录,而不是表示源流为空。
|
||||
只有 `assistant/message` 可以携带存在但为空的 `sourceEventSeqs`;字段不存在时,该事件没有记录这条消息由哪些早期事件产生,但提供方仍可能发出过分片。
|
||||
|
||||
### `SessionSurface`:实时只读 surface 投影
|
||||
|
||||
@@ -581,7 +582,7 @@ interface TurnEndReasonMap {
|
||||
|
||||
## 插件贡献的仅日志事件
|
||||
|
||||
插件可以通过 declaration merging 添加额外的 `SessionEventMap` 类型。这些是**仅日志**事件:不是 `SurfaceEventType`(不携带 `surfaceOp`,不参与派生历史)。事件所有方决定它们属于一个开放的执行轮次,还是可以独立位于轮次之间,并在自己的不变量配套插件中强制所需关系。生成的[持久化日志事件目录](../persistence-catalog.md)会列出每个核心或插件贡献的事件,以及其 payload、surface 标记、被引用的来源事件 seq 和声明位置;压缩 seam 的 `compact/*` 语义在 [compaction.md](compaction.md) 中讨论。
|
||||
插件可以通过 declaration merging 添加额外的 `SessionEventMap` 类型。这些是**仅日志**事件:不是 `SurfaceEventType`(不携带 `surfaceOp`,不参与派生历史)。事件所有方决定它们属于一个开放的执行轮次,还是可以独立位于轮次之间,并在自己的不变量配套插件中强制所需关系。生成的[持久化日志事件目录](../persistence-catalog.md)会列出每个核心或插件贡献的事件,以及其 payload、surface 标记和声明位置;压缩 seam 的 `compact/*` 语义在 [compaction.md](compaction.md) 中讨论。
|
||||
|
||||
钩子桥接层的 `hook/invoked` / `hook/result` 对(来自 `@deepseek-ai/dsh-hook-protocol`)通过 `handlerId` 关联。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 在 loop 已打开的轮次内触发,因此其 `hook/*` 记录天然位于轮次之内。`SessionStart` 不生成 `hook/*` 记录,因为它在轮次 1 之前运行;其上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次(见[钩子桥接 Agent Note](../../.agents/notes/implemented/feature/2026-06-30-hook-bridges.md))。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user