docs: reserve seam for complete capabilities

This commit is contained in:
Turtle
2026-08-09 15:34:32 +08:00
parent 27ac49e687
commit dda02250f5
966 changed files with 2166 additions and 2159 deletions

View File

@@ -161,7 +161,7 @@ export class SessionPersistenceJsonl extends SessionPersistence implements Persi
}
// Each backend keeps the typed service surface beside its storage hooks;
// extracting these trivial forwards would add an inheritance seam.
// extracting these trivial forwards would add an inheritance layer.
/* jscpd:ignore-start */
// --- SessionPersistence service surface (delegated to the coordinator) ---

View File

@@ -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 packages/session/session-persistence-sqlite/README.md
README.md: 4961f62bf6854c343d35b8406c9d721590274534
README.zh.md: 0507e0fa99bc553317c34e51f30e4daaceee93fd
README.md: 745c25616e06c391a70b37471917aa9d2539c4dd
README.zh.md: c86531bcaeca85fa565b537f1fc1beca5d6ac7b3

View File

@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
A SQLite durable session-persistence backend — a second `SessionPersistence` implementation ([session persistence](../../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md)), built to validate that the abstract seam and the shared `runPersistenceContract` suite are genuinely backend-agnostic. It satisfies the SAME contract as `dsh-session-persistence-jsonl` (append-only, contiguous-seq, lazy materialization, interrupted-turn close on load), expressed over `node:sqlite` rows instead of file bytes.
A SQLite durable session-persistence backend — a second `SessionPersistence` provider ([session persistence](../../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md)), built to validate that the Service Definition and the shared `runPersistenceContract` suite are genuinely backend-agnostic. It satisfies the SAME contract as `dsh-session-persistence-jsonl` (append-only, contiguous-seq, lazy materialization, interrupted-turn close on load), expressed over `node:sqlite` rows instead of file bytes.
`locate(meta)` returns `undefined`: all sessions share one database, so there is no honest independent per-session transcript path.

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
SQLite 持久会话存储后端:第二个 `SessionPersistence` 实现(见[会话持久化](../../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md)),用于验证抽象 seam 和共享 `runPersistenceContract` 套件真正与后端无关。它满足与 `dsh-session-persistence-jsonl` 相同的约定(仅追加、连续 seq、延迟实体化、在 load 时关闭中断轮次),但用 `node:sqlite` 行而非文件字节表达。
SQLite 持久会话存储后端:第二个 `SessionPersistence` 提供方(见[会话持久化](../../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md)),用于验证 Service Definition 和共享 `runPersistenceContract` 套件真正与后端无关。它满足与 `dsh-session-persistence-jsonl` 相同的约定(仅追加、连续 seq、延迟实体化、在 load 时关闭中断轮次),但用 `node:sqlite` 行而非文件字节表达。
`locate(meta)` 返回 `undefined`:所有会话共享一个数据库,因此不存在真实、独立的逐会话 transcript文本记录路径。
@@ -22,7 +22,7 @@ SQLite 持久会话存储后端:第二个 `SessionPersistence` 实现(见[
- **延迟实体化。**`create()` 只在内存记录意图,第一次 `append` 前不写行。从未 append 的会话没有 `sessions` 行,因此不在 `list()` 中(它精确报告有行的会话)。
- **在 load 时关闭中断轮次。**`load()` 实现共享[崩溃恢复约定](../../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md):保留有效中断轮次,在一个事务中追加合成关闭事件,并只移除撕裂尾部行。已提交解析错误或序列缺口使会话无法加载。恢复会变更已存储行,因此下一次 append 从平衡日志和准确游标开始。
- **非变更检查。**`inspect()` 返回不可变、平衡的逻辑视图,并可在内存中合成恢复 closer但不会删除撕裂尾部行、追加恢复行或更改轻量修订。
- **轻量修订。**`listSnapshots(signal?)` 组合不可变存储与数据库文件身份、每实体化 incarnation id以及在每个变更事务中递增的每会话计数器。完整前缀读取在同一个读事务中捕获该修订及其事件行,`readStoredRevision()` 则只查询会话行来校验保留的准备结果。它在不解析事件行的情况下保持未变观察稳定,并区分独立存储和重建的同 id 日志。它在共享就绪和同步元数据查询前后检查取消;查询本身不可抢占。
- **轻量修订。**`listSnapshots(signal?)` 组合不可变存储与数据库文件身份、每实体化 incarnation id以及在每个变更事务中递增的每会话计数器。完整前缀读取在同一个读事务中捕获该 revision 及其事件行,`readStoredRevision()` 则只查询 session 行来校验保留的 preparation。它在不解析事件行的情况下保持未变观察稳定,并区分独立存储和重建的同 id 日志。它在共享就绪和同步元数据查询前后检查取消;查询本身不可抢占。
## 配置schemastery
@@ -37,7 +37,7 @@ interface Config {
## 写入路径
与 JSONL 后端一样,插件将每个冻结的 `session/event` 复制到每个活动会话各自的 controller。第一个待处理事件会开启配置的固定批处理窗口后续事件会加入但不会重置截止时间。窗口到期后会启动一个事务该次写入期间接纳的事件会形成另一个独立有界的后续批次。`session/flush` 会取消等待并排空当前与待处理批次。Controller 会持久化一次 fork 种子,并保留写入游标,使恢复操作绝不重新 append 已存储事件;它还会在 apply 时为活动会话设置初始状态,因为 HMR热模块替换不回放 `session/created`。dispose资源释放会在关闭数据库前排空每个保留的 controller。每个事件仍各占一行 SQLite 记录;批处理只把更多 INSERT 归入同一个事务和同一次修订递增。
与 JSONL 后端一样,插件将每个冻结的 `session/event` 复制到每个活动会话各自的 controller。第一个待处理事件会开启配置的固定批处理窗口后续事件会加入但不会重置截止时间。窗口到期后会启动一个事务该次写入期间接纳的事件会形成另一个独立有界的后续批次。`session/flush` 会取消等待并排空当前与待处理批次。Controller 会持久化一次 fork 种子,并保留写入游标,使恢复操作绝不重新 append 已存储事件;它还会在 apply 时为活动会话设置初始状态,因为 HMR热模块替换不回放 `session/created`。dispose资源释放会在关闭数据库前排空每个保留的 controller。每个事件仍各占一行 SQLite 记录;批处理只把更多 INSERT 归入同一个事务和同一次修订版本递增。
## 模型体验

View File

@@ -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 packages/session/session-persistence/README.md
README.md: 29ee219a55d0823f03bb512c0fa37b7e249817eb
README.zh.md: c750d2f85fd267a94c36770452f1e5c7e647a2fb
README.md: c64826db1e9c7339f43a64ad7c13f01a2a39638e
README.zh.md: 651d920404300fa602f77cee63b0f31aec837919

View File

@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
The abstract durable session-persistence seam (`ctx.sessionPersistence`). Defines WHAT a persistence backend does — durably store, reload, and list sessions — without saying HOW. Mirrors the `dsh-bash` capability-seam template ([capability seams](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)): an abstract service here, a concrete implementation in a sibling package, consumers that inject the interface.
The durable session-persistence Service Definition (`ctx.sessionPersistence`). Defines WHAT a persistence backend does — durably store, reload, and list sessions — without saying HOW. Mirrors the `dsh-bash` capability-seam template ([capability seams](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)): an abstract service here, a Service provider in a sibling package, and Consumers that inject the service.
The persisted unit IS the existing `SessionEvent` (event-sourced model — the log is the single source of truth), so there is no parallel "persisted message" type. Metadata that is NOT replayable conversation state (format version, cwd, lineage, seed boundary, origin, delegation depth) travels separately as `SessionHeader`, owned by `dsh-session` and re-exported here.
@@ -41,7 +41,7 @@ When a live session emits `session/disposed`, the coordinator waits for its cont
The side-effect-free `locate`, lightweight `listSnapshots`, and per-id `readStoredRevision` queries remain backend-owned because they describe storage topology and revision identity rather than write orchestration. `listSnapshots(signal?)` passes the caller's exact signal into backend discovery so observers can cancel that work without detaching it.
The `PersistenceBackend<TornMarker>` hooks (the only seam between the coordinator and storage):
The `PersistenceBackend<TornMarker>` hooks (the only contract between the coordinator and storage):
| Hook | Role |
|---|---|

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
这是用于持久保存会话的抽象 seam`ctx.sessionPersistence`)。它定义持久化后端做什么:持久存储、重新加载和列出会话,而不规定如何实现。它与 `dsh-bash` 能力 seam 模板一致(见[能力 seam](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)):本包提供抽象服务,同级包提供具体实现,消费方注入接口
这是用于持久保存会话的 Service Definition`ctx.sessionPersistence`)。它定义持久化后端做什么:持久存储、重新加载和列出会话,而不规定如何实现。它与 `dsh-bash` 能力 seam 模板一致(见[能力 seam](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)):本包提供抽象服务,同级包提供 Service providerConsumer 注入服务
持久化单元就是现有 `SessionEvent`事件溯源模型日志是唯一真源因此不存在另一套并行的「持久消息」类型。不属于可回放对话状态的元数据格式版本、cwd、血缘、种子边界、origin、委托深度作为 `SessionHeader` 单独传输,该类型归 `dsh-session` 所有,并在此重新导出。
@@ -41,7 +41,7 @@
无副作用 `locate`、轻量 `listSnapshots` 和按 id 查询的 `readStoredRevision` 仍由后端负责,因为它们描述存储拓扑和修订身份,而非写入编排。`listSnapshots(signal?)` 将调用方传入的同一个信号传给后端发现流程,使观察者可在不脱离该工作的情况下取消。
`PersistenceBackend<TornMarker>` 钩子(协调器与存储之间的唯一 seam
`PersistenceBackend<TornMarker>` 钩子(协调器与存储之间的唯一约定
| 钩子 | 职责 |
|---|---|

View File

@@ -78,7 +78,7 @@ export interface StoredSuffix {
}
/**
* The storage seam between {@link PersistenceCoordinator} and a concrete
* The storage contract between {@link PersistenceCoordinator} and a concrete
* backend: the minimal set of durable primitives the orchestration calls. A
* backend implements these (over files, rows, an object store, …); the
* coordinator supplies everything else (buffering, serialization, cursors,

View File

@@ -1,5 +1,5 @@
/**
* Durable session-persistence seam (`ctx.sessionPersistence`). Backends store
* Durable session-persistence Service Definition (`ctx.sessionPersistence`). Backends store
* {@link SessionEvent}s as the event-sourced log and carry non-replayable
* {@link SessionHeader} metadata separately.
* @module @deepseek-ai/dsh-session-persistence
@@ -10,7 +10,7 @@ import { SessionPreparation } from '@deepseek-ai/dsh-session'
import type { SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session'
import type { SessionPersistenceRevision } from './revision.ts'
// Re-export the metadata vocabulary so consumers import it from the seam.
// Re-export the metadata vocabulary so Consumers import it from the Service Definition.
export type { SessionHeader } from '@deepseek-ai/dsh-session'
export { SessionPersistenceRevision } from './revision.ts'

View File

@@ -1279,7 +1279,7 @@ describe('PersistenceCoordinator observation cancellation', () => {
}
const suffix = await coordinator.readFrom(id, 3)
expect(suffix.events).toEqual(log.slice(3))
// The hook's undefined is the seam's not-found.
// The hook's `undefined` is the backend contract's not-found result.
await expect(coordinator.readFrom(SessionId('missing-seek'), 0)).rejects.toThrow('not found')
// A hook failure with no cancellation in play propagates as-is.

View File

@@ -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 packages/session/session-projection/README.md
README.md: a42e88c262915fc5e53cd72205079cbc8029a8df
README.zh.md: 01b23a7152a509efab6e169043a823d49d6d9fde
README.md: 2615b253999c798172168ec9d0232eb965b07fbc
README.zh.md: 0712e9c7a61fbcf43939791b3e7cd24af6777c3a

View File

@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
Session-projection seam. It owns `ctx.sessionProjections`, the registry that drives every registered projection unit over committed session events and serves finished whole values to carriers, currently the api-proxy history tail page and `session/projection` push frame. A domain registers pure mathematics; the framework owns the drive. The [session-projection RFC](../../../.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md) records the design rationale.
Session-projection Service Definition and drive registry. It owns `ctx.sessionProjections`, the registry that drives every registered projection unit over committed session events and serves finished whole values to carriers, currently the api-proxy history tail page and `session/projection` push frame. A domain registers pure mathematics; the framework owns the drive. The [session-projection RFC](../../../.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md) records the design rationale.
## Service: `SessionProjectionRegistry` (ctx key: `sessionProjections`)
@@ -25,11 +25,11 @@ Session-projection seam. It owns `ctx.sessionProjections`, the registry that dri
- **Synchronous unit discipline.** `init`/`apply`/`view` MUST be synchronous; carriers read `snapshot()` in the same tick as their page slice, which is what makes `asOfSeq` one consistent cut. An accidentally-async `view` returns a Promise, which fails the boundary `schema.parse` loudly.
- **State is plain JSON, `stateVersion` is its invalidation anchor.** The persisted projection cache stores `(sessionId, key, ver, seq, val)` rows; bump `stateVersion` whenever the state shape or the fold semantics change so stale rows are discarded instead of forward-applied into garbage.
- **No wire vocabulary here.** The registry exposes only the change feed and the snapshot read face; carriers (api-proxy) mint their own frames (`session/projection`) and blocks from them.
- **Optional seam.** Domain plugins register under `ctx.inject(['sessionProjections'], …)` so headless assemblies without the registry stay unaffected; carriers use `ctx.get('sessionProjections')` and omit their block/frames entirely when the registry is absent.
- **Optional capability.** Domain plugins register under `ctx.inject(['sessionProjections'], …)` so headless assemblies without the registry stay unaffected; carriers use `ctx.get('sessionProjections')` and omit their block/frames entirely when the registry is absent.
## Role
This is the interface-plus-drive package of the capability-seam split: domain host plugins (e.g. `dsh-tool-todo`) contribute units, carriers (`dsh-host-apiproxy`) consume the snapshot and change feed, and neither knows the other.
This package owns the Service Definition and drive roles of the capability seam: domain host plugins (e.g. `dsh-tool-todo`) contribute units, carriers (`dsh-host-apiproxy`) consume the snapshot and change feed, and neither knows the other.
## Model Experience

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
会话投影 seam。它拥有 `ctx.sessionProjections`:该注册表在已提交的会话事件上驱动每个已注册的投影单元,并向载体提供完整的最终值,目前包括 api-proxy 历史尾页和 `session/projection` 推送帧。领域注册的只是纯数学;驱动权归框架。[session-projection RFC](../../../.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md) 记录了设计理由。
会话投影 Service Definition 与驱动注册表。它拥有 `ctx.sessionProjections`:该注册表在已提交的会话事件上驱动每个已注册的投影单元,并向载体提供完整的最终值,目前包括 api-proxy 历史尾页和 `session/projection` 推送帧。领域注册的只是纯数学;驱动权归框架。[session-projection RFC](../../../.agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.md)记录了设计理由。
## 服务:`SessionProjectionRegistry`ctx 键:`sessionProjections`
@@ -25,11 +25,11 @@
- **单元的同步纪律。**`init`/`apply`/`view` 必须是同步的;载体在切出页面切片的同一 tick 内读取 `snapshot()``asOfSeq` 之所以是一个一致切面正系于此。误写成异步的 `view` 会返回 Promise让边界的 `schema.parse` 当场大声失败。
- **状态是纯 JSON`stateVersion` 是其失效锚点。** 持久投影缓存persisted projection cache存储 `(sessionId, key, ver, seq, val)` 行;状态形状或折叠语义一旦变化就递增 `stateVersion`,使陈旧行被丢弃,而不是被正向 apply 成垃圾。
- **本层没有协议词汇。** 注册表只暴露变更流与快照读取面载体api-proxy据此自铸各自的帧`session/projection`)与块。
- **可选 seam。** 领域插件在 `ctx.inject(['sessionProjections'], …)` 下注册,因此不带注册表的 headless 组装完全不受影响;载体使用 `ctx.get('sessionProjections')`,注册表缺席时完全省略自己的块与帧。
- **可选能力。** 领域插件在 `ctx.inject(['sessionProjections'], …)` 下注册,因此不带注册表的 headless 组装完全不受影响;载体使用 `ctx.get('sessionProjections')`,注册表缺席时完全省略自己的块与帧。
## 职责
这是能力 seam 拆分中「接口 + 驱动」的那个包:领域 host 插件(如 `dsh-tool-todo`)贡献单元,载体(`dsh-host-apiproxy`)消费快照与变更流,两侧互不相识。
本包承担能力 seam 的 Service Definition 与驱动角色:领域 host 插件(如 `dsh-tool-todo`)贡献单元,载体(`dsh-host-apiproxy`)消费快照与变更流,两侧互不相识。
## 模型体验

View File

@@ -1,5 +1,5 @@
/**
* Session-projection seam: the merge-extensible `SessionProjectionMap` type
* Service Definition and drive registry for the session-projection capability seam: the merge-extensible `SessionProjectionMap` type
* table, the `ProjectionDefinition` state-driven computation unit contract,
* and the `ctx.sessionProjections` registry that DRIVES every registered unit
* forward eagerly over committed session events. Domain host plugins
@@ -117,7 +117,7 @@ export interface ProjectionCheckpointRow {
/** Checkpoint rows keyed by projection key (one session's persisted cache value). */
export type ProjectionCheckpoint = Record<string, ProjectionCheckpointRow>
/** Type-erased unit view the drive machinery works with (the register seam already proved the typed contract). */
/** Type-erased unit view the drive machinery works with (the registration contract already proved the typed form). */
interface ErasedDefinition {
key: string
schema: { parse(value: unknown): unknown }

View File

@@ -1,5 +1,5 @@
/**
* Pure-type outlet of the session-projection seam: the one projection type
* Pure-type outlet of the session-projection Service Definition: the one projection type
* table, importable from client aggregates without dragging the host-side
* cordis Context merges of the package root (dsh-agent → dsh-session). Domain
* packages may declare-merge through either the package root or this outlet —

View File

@@ -1,9 +1,9 @@
/**
* OpenTelemetry backend for the DeepSeek Harness telemetry seam.
* OpenTelemetry Service provider for the DeepSeek Harness telemetry capability.
*
* Composes the OTel JS SDK as-is — a `LoggerProvider` with a
* `BatchLogRecordProcessor` and an OTLP/HTTP log exporter — and maps each
* record handed over by the seam onto `logger.emit()`. Per the seam's
* record handed over by the capture coordinator onto `logger.emit()`. Per the Service Definition's
* boundary axiom, everything downstream of that call (batching, retry,
* queueing, loss policy) is the SDK's documented behavior, configured
* verbatim through the `exporter`/`processor` passthroughs. This package owns
@@ -121,7 +121,7 @@ export const DEFAULT_SHUTDOWN_TIMEOUT_MILLIS = 3_000
// protocol limit, not a deployment default.
const MAX_TIMER_DELAY_MILLIS = 2_147_483_647
/** Severity mapping from the seam's three-level vocabulary to OTel severity numbers. */
/** Severity mapping from the Service Definition's three-level vocabulary to OTel severity numbers. */
const SEVERITY: Record<TelemetrySeverity, { severityNumber: SeverityNumber; severityText: string }> = {
info: { severityNumber: SeverityNumber.INFO, severityText: 'INFO' },
warn: { severityNumber: SeverityNumber.WARN, severityText: 'WARN' },
@@ -250,7 +250,7 @@ export class TelemetryOtel extends Telemetry {
this.directEmit(record)
}
// The seam's optional flush() hint is deliberately NOT implemented. The
// The Service Definition's optional flush() hint is deliberately NOT implemented. The
// batch processor exports on its own cadence (`processor.scheduledDelayMillis`,
// the SDK's documented knob), and this backend is the SDK pipeline's only
// caller — forwarding the hint to `forceFlush()` was the sole source of

View File

@@ -17,7 +17,7 @@ export const inject = ['invariants']
/**
* No runtime invariant: mode selection changes capture handoff, SDK setup, and
* local diagnostics without mutating session or service state an independent
* companion can compare. Export remains inside the SDK past the seam boundary.
* companion can compare. Export remains inside the SDK past the backend boundary.
*/
const install: InvariantInstaller = () => {}

View File

@@ -33,11 +33,11 @@ export const USER_ID_FILE_NAME = '.userid'
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
/** Ambient seams for locating and generating the id; every field has a default. */
/** Ambient hooks for locating and generating the id; every field has a default. */
export interface AnonymousUserIdOptions {
/** Environment consulted for `DSH_HOME`; defaults to `process.env`. */
env?: NodeJS.ProcessEnv
/** UUID generator; defaults to `crypto.randomUUID` (test seam). */
/** UUID generator; defaults to `crypto.randomUUID` (test hook). */
randomUUID?: () => string
}
@@ -65,7 +65,7 @@ function readPersistedId(file: string): AnonymousUserId | undefined {
* run; the next launch converges on the persisted one.) Persistence is
* best-effort — a write failure (read-only home) still returns a usable id
* for the current run so telemetry is never blocked.
* @param options - home-location and UUID-generation seams.
* @param options - Home-location and UUID-generation hooks.
* @returns the stable per-harness-home anonymous user id.
*/
export function getOrCreateAnonymousUserId(options: AnonymousUserIdOptions = {}): AnonymousUserId {

View File

@@ -57,7 +57,7 @@ describe('getOrCreateAnonymousUserId', () => {
const home = tempHome()
const winner = 'aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee'
const file = join(home, USER_ID_FILE_NAME)
// The generator seam runs between the initial read (absent) and the wx
// The generator hook runs between the initial read (absent) and the wx
// write, so planting the winner here simulates the concurrent first launch.
const id = getOrCreateAnonymousUserId({
env: { DSH_HOME: home },

View File

@@ -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 packages/session/session-telemetry/README.md
README.md: 67d95bcc62bbf6783f8dcd11f0236d8c926b557b
README.zh.md: 80044ceb57c93f8406398a9239d83cbb6015e98c
README.md: 506f0f5bcb03a54f09805ed0f866a396e3cf0334
README.zh.md: b5e47c8832452ece281dcdcfac007d6082813583

View File

@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
The telemetry seam: the capture side of session-event reporting, behind a backend contract any reporting SDK satisfies with zero bending. Capture can follow live session events or replay a canonical session-log prefix on demand. The boundary axiom that shapes everything here: **this package's aspect ends at `emit()`** — batching, retry, queueing, and loss policy belong to the backend's SDK and are neither specified nor wrapped. Rationale and rejected alternatives: [the revival Agent Note](../../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md), [feedback-gated delivery](../../../.agents/notes/implemented/feature/2026-08-05-feedback-gated-session-telemetry.md), and [buffer-free feedback replay](../../../.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.md).
The telemetry Service Definition and capture coordinator sit behind a backend contract any reporting SDK satisfies with zero bending. Capture can follow live session events or replay a canonical session-log prefix on demand. The boundary axiom that shapes everything here: **this package's aspect ends at `emit()`** — batching, retry, queueing, and loss policy belong to the backend's SDK and are neither specified nor wrapped. Rationale and rejected alternatives: [the revival Agent Note](../../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md), [feedback-gated delivery](../../../.agents/notes/implemented/feature/2026-08-05-feedback-gated-session-telemetry.md), and [buffer-free feedback replay](../../../.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.md).
## The backend contract
@@ -14,7 +14,7 @@ In `live` mode the coordinator registers, all through the composing fiber's effe
## The redact waterfall
Every record passes the `telemetry/record` waterfall immediately after projection — the seam's scrubbing extension point. The seam ships NO rules of its own: the innermost `next()` passes the record through unchanged, so with no listener mounted records reach the backend exactly as captured, and exported data is precisely as clean as the rules a deployment mounts. Listeners stack by transforming `next()`'s return value; returning without `next()` replaces everything beneath, and a throwing listener withholds that one record fail-closed inside the coordinator's containment. Live capture runs the waterfall at append time; on-demand capture runs it while replaying the canonical log, using the rules mounted at that time. Redaction applies to the outbound copy only; the canonical session log is never rewritten.
Every record passes the `telemetry/record` waterfall immediately after projection — the Service Definition's scrubbing extension point. This package ships NO rules of its own: the innermost `next()` passes the record through unchanged, so with no listener mounted records reach the backend exactly as captured, and exported data is precisely as clean as the rules a deployment mounts. Listeners stack by transforming `next()`'s return value; returning without `next()` replaces everything beneath, and a throwing listener withholds that one record fail-closed inside the coordinator's containment. Live capture runs the waterfall at append time; on-demand capture runs it while replaying the canonical log, using the rules mounted at that time. Redaction applies to the outbound copy only; the canonical session log is never rewritten.
## The handoff cursor
@@ -30,7 +30,7 @@ Only the first `assistant/chunk` of each `(turn, step)` ships; the rest are drop
## Model Experience
None, as the seam only observes the session stream and hands redacted copies to a reporting backend; it never contributes to a model request.
None, as this package only observes the session stream and hands redacted copies to a reporting backend; it never contributes to a model request.
#### KV Cache effect

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
遥测telemetryseam会话事件上报的捕获侧隔在一个后端约定之后,任何上报 SDK 都无需变形即可满足该约定。捕获侧可跟随实时会话事件,也可按需回放权威会话日志前缀。塑造本包一切设计的边界公理:**本包的职责止于 `emit()`**。批处理、重试、排队与丢失策略都属于后端自身的 SDK本包既不为其立规也不做包装。设计依据与被否决的替代方案见[复活 Agent Note](../../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md)、[反馈门控投递](../../../.agents/notes/implemented/feature/2026-08-05-feedback-gated-session-telemetry.md)与[无缓冲反馈回放](../../../.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.md)。
遥测telemetryService Definition 与捕获协调器位于一个后端约定之后,任何上报 SDK 都无需变形即可满足该约定。捕获侧可跟随实时会话事件,也可按需回放权威会话日志前缀。塑造本包package一切设计的边界公理:**本包的职责止于 `emit()`**。批处理、重试、排队与丢失策略都属于后端自身的 SDK本包既不为其立规也不做包装。设计依据与被否决的替代方案见[复活 Agent Noteagent 决策记录)](../../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md)、[反馈门控投递](../../../.agents/notes/implemented/feature/2026-08-05-feedback-gated-session-telemetry.md)与[无缓冲反馈回放](../../../.agents/notes/implemented/simplification/2026-08-06-buffer-free-feedback-telemetry.md)。
## 后端约定
@@ -14,7 +14,7 @@
## 脱敏 waterfall瀑布式事件
每条记录在投影后立即经过 `telemetry/record` waterfall这是该 seam 的脱敏扩展点。seam 自身不带任何规则:最内层的 `next()` 原样透传记录,因此未挂载监听器时,记录以捕获时的原样到达后端;导出数据能干净到什么程度,恰恰取决于部署方挂载了什么规则。监听器通过变换 `next()` 的返回值来堆叠;不调用 `next()` 就返回,即替换其下方的全部逻辑;抛出异常的监听器会在协调器的隔离范围内以 fail-closed 方式拦下这一条记录。实时捕获在追加时运行 waterfall按需捕获则在回放权威日志时使用当时挂载的规则运行 waterfall。脱敏只作用于外发副本权威会话日志永不改写。
每条记录在投影后立即经过 `telemetry/record` waterfall这是 Service Definition 的脱敏扩展点。本包自身不带任何规则:最内层的 `next()` 原样透传记录,因此未挂载监听器时,记录以捕获时的原样到达后端;导出数据能干净到什么程度,恰恰取决于部署方挂载了什么规则。监听器通过变换 `next()` 的返回值来堆叠;不调用 `next()` 就返回,即替换其下方的全部逻辑;抛出异常的监听器会在协调器的隔离范围内以 fail-closed 方式拦下这一条记录。实时捕获在追加时运行 waterfall按需捕获则在回放权威日志时使用当时挂载的规则运行 waterfall。脱敏只作用于外发副本权威会话日志永不改写。
## handoff 游标
@@ -30,7 +30,7 @@
## 模型体验
无。该 seam 只观察会话流,并把脱敏后的副本交给上报后端;它绝不向模型请求贡献任何内容。
无。本包只观察会话流,并把脱敏后的副本交给上报后端;它绝不向模型请求贡献任何内容。
#### KV Cache 影响

View File

@@ -1,5 +1,5 @@
/**
* Capture coordinator: the seam's upstream half. Live capture subscribes to
* Capture coordinator for the telemetry capability. Live capture subscribes to
* the session firehose plus the one live-bus relay (`agent/error`). Both
* capture paths apply the fixed chunk projection, build logical records, and
* run each through the
@@ -159,7 +159,7 @@ export class TelemetryCoordinator {
* at or below the start still feed the projection state (first-chunk
* tracking) without being re-handed, so a resumed fiber drops mid-step
* chunk continuations exactly like the fiber that saw the step begin. The
* cost, accepted with the seam's at-most-once stance: a resume no longer
* cost, accepted with the capture contract's at-most-once stance: a resume no longer
* backfills records a previous process failed to deliver.
* @param session - the live session to adopt; a second adoption is a no-op.
*/
@@ -204,7 +204,7 @@ export class TelemetryCoordinator {
/**
* Run the `telemetry/record` waterfall at capture time. The innermost `next`
* passes the record through unchanged — the seam ships no rules; exported
* passes the record through unchanged — this package ships no rules; exported
* data is as clean as the listeners a deployment mounts. Callers run inside
* {@link contain}, so a throwing rule withholds the record instead of
* reaching the loop (fail-closed). On-demand capture invokes this waterfall
@@ -289,7 +289,7 @@ function severityOf(event: SessionEvent): TelemetrySeverity {
case 'turn/end':
return event.data.reason.kind === 'error' ? 'error' : 'info'
default:
// Merge-extensible fall-through (no assertNever): event types this seam
// Merge-extensible fall-through (no assertNever): event types this coordinator
// does not depend on — including plugin-merged ones it never heard of —
// pass through as info; their owners' outcome semantics stay theirs.
return 'info'

View File

@@ -1,7 +1,7 @@
/**
* Telemetry seam for the DeepSeek Harness.
* Telemetry Service Definition for the DeepSeek Harness.
*
* The seam owns the CAPTURE side of session-event reporting — which records
* This package owns the CAPTURE side of session-event reporting — which records
* exist (the chunk projection), what they carry (the logical record), when
* they are captured (adoption, the per-append firehose, lifecycle
* forwarding), live versus on-demand canonical-log capture, and the HMR
@@ -24,7 +24,7 @@ declare module 'cordis' {
interface Events {
/**
* Transform one outbound record before it reaches the backend. This
* waterfall is the seam's redaction extension point. It ships NO rules
* waterfall is the Service Definition's redaction extension point. It ships NO rules
* of its own: the
* innermost `next()` passes the record through unchanged, and with no
* listener mounted records reach the backend as captured, so exported
@@ -55,7 +55,7 @@ declare module 'cordis' {
export type TelemetrySeverity = 'info' | 'warn' | 'error'
/**
* One logical record handed to a backend — the seam's whole outbound
* One logical record handed to a backend — the capture contract's whole outbound
* vocabulary. Ledger records mirror session-log events one-to-one;
* operational records (`channel: 'ops'`) carry the two signals with no log
* home (`agent-error`, `shutdown`) and deliberately omit `event.seq`-style
@@ -143,7 +143,7 @@ export abstract class Telemetry extends Service implements TelemetryBackend {
}
/**
* See {@link TelemetryBackend.emit} — the seam declaration is the contract's one home.
* See {@link TelemetryBackend.emit} — that declaration is the contract's one home.
* @param record - the logical record to report; owned by the backend after the call.
*/
abstract emit(record: TelemetryRecord): void

View File

@@ -15,7 +15,7 @@ export const name = 'session-telemetry-invariant'
export const inject = ['invariants']
/**
* No runtime invariant: the seam's whole output is the backend handoff — a
* No runtime invariant: the package's whole output is the backend handoff — a
* synchronous `emit()` call outside every authoritative event stream — and its
* capture side never appends session events, so no event/data relation exists
* for an independent companion to observe.

View File

@@ -1,5 +1,5 @@
/**
* Log-backed session title service, deterministic fallback, and provider seam.
* Log-backed session title service, deterministic fallback, and provider contract.
* @module @deepseek-ai/dsh-session-title
*/