1
0
Эх сурвалжийг харах

fix(session): keep upload defaults independent of test runners

creatixchu 1 долоо хоног өмнө
parent
commit
31ec6bc7e3
39 өөрчлөгдсөн 134 нэмэгдсэн , 93 устгасан
  1. 2 2
      .agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.i18n.yaml
  2. 4 4
      .agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md
  3. 4 4
      .agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.zh.md
  4. 2 2
      .agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml
  5. 2 2
      .agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.md
  6. 2 2
      .agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.zh.md
  7. 2 2
      .agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml
  8. 2 2
      .agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.md
  9. 2 2
      .agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.zh.md
  10. 6 0
      .agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.i18n.yaml
  11. 28 0
      .agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md
  12. 28 0
      .agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.zh.md
  13. 2 2
      apps/cli/reference/README.i18n.yaml
  14. 2 2
      apps/cli/reference/README.md
  15. 2 2
      apps/cli/reference/README.zh.md
  16. 1 0
      apps/web/tests/scaffold.ts
  17. 2 2
      docs/config-catalog.i18n.yaml
  18. 1 1
      docs/config-catalog.md
  19. 1 1
      docs/config-catalog.zh.md
  20. 2 2
      docs/user/guide/python-sdk.i18n.yaml
  21. 1 1
      docs/user/guide/python-sdk.md
  22. 1 1
      docs/user/guide/python-sdk.zh.md
  23. 2 2
      packages/bundle/base/README.i18n.yaml
  24. 1 1
      packages/bundle/base/README.md
  25. 1 1
      packages/bundle/base/README.zh.md
  26. 2 2
      packages/llm/llm-deepseek/README.i18n.yaml
  27. 2 2
      packages/llm/llm-deepseek/README.md
  28. 2 2
      packages/llm/llm-deepseek/README.zh.md
  29. 5 6
      packages/llm/llm-deepseek/tests/loader-composition.spec.ts
  30. 2 2
      packages/session/session-log-deepseek/README.i18n.yaml
  31. 0 3
      packages/session/session-log-deepseek/README.md
  32. 0 3
      packages/session/session-log-deepseek/README.zh.md
  33. 1 14
      packages/session/session-log-deepseek/src/index.ts
  34. 6 6
      packages/session/session-log-deepseek/tests/config.spec.ts
  35. 3 3
      packages/session/session-log-deepseek/tests/upload.spec.ts
  36. 4 0
      snapshots/acp/escalation-approved/cordis.yml
  37. 0 5
      snapshots/sdk/text-turn/cordis.snapshot.yml
  38. 0 5
      snapshots/sdk/text-turn/cordis.yml
  39. 4 0
      snapshots/session/text-turn/cordis.yml

+ 2 - 2
.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.i18n.yaml

@@ -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 .agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md
-2026-08-21-deepseek-llm-api-request-extensions.md: a0e38c1da5af32b0ba5e07df632ac4e25148419e
-2026-08-21-deepseek-llm-api-request-extensions.zh.md: 763f418c7bd6029c08027cd5f4705bffd984b9ee
+2026-08-21-deepseek-llm-api-request-extensions.md: 7a3609a3f7d8b2aa6edb634643ef234b7e3e8c07
+2026-08-21-deepseek-llm-api-request-extensions.zh.md: 69426df3cc85851e448b98dc51af79555b8cbafc

+ 4 - 4
.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.md

@@ -14,13 +14,13 @@ Both values belong only on the official DeepSeek adapter path. Adding them to `G
 
 ## Decision
 
-`@deepseek-ai/dsh-deepseek-llm-api-extensions` registers `ctx.deepseekLlmApiExtensions`, an additive registry of top-level fields for `deepseek-official` request bodies. A contributor claims one declaration-merged field with `register()`. The adapter invokes `prepare()` after serializing the exact wire messages, passes the request cancellation signal, rejects preparation or base-field collision before HTTP, merges the detached fields, and calls the captured `accept()` transaction after HTTP 2xx. The registry stops awaiting preparation after cancellation even if a contributor ignores the signal. Acceptance failures remain request failures under `REQUEST_EXTENSION`; transport and non-2xx failures never accept a contribution. A composition without the registry retains the reusable base adapter. Shipped compositions mount the registry and both contributors: package metadata is enabled by default, while Session-log upload is disabled by default and requires `session-log-deepseek.enabled: true`. Keyless `deepseek-official` replay invokes preparation with a synthetic empty base body and the same acceptance transaction before its first recorded chunk, preserving post-2xx extension side effects rather than field bytes.
+`@deepseek-ai/dsh-deepseek-llm-api-extensions` registers `ctx.deepseekLlmApiExtensions`, an additive registry of top-level fields for `deepseek-official` request bodies. A contributor claims one declaration-merged field with `register()`. The adapter invokes `prepare()` after serializing the exact wire messages, passes the request cancellation signal, rejects preparation or base-field collision before HTTP, merges the detached fields, and calls the captured `accept()` transaction after HTTP 2xx. The registry stops awaiting preparation after cancellation even if a contributor ignores the signal. Acceptance failures remain request failures under `REQUEST_EXTENSION`; transport and non-2xx failures never accept a contribution. A composition without the registry retains the reusable base adapter. Shipped compositions mount the registry and both contributors: both package metadata and Session-log upload are enabled by default; `session-log-deepseek.enabled: false` disables log upload under the [default-upload decision](2026-09-14-session-log-upload-default.md). Keyless `deepseek-official` replay invokes preparation with a synthetic empty base body and the same acceptance transaction before its first recorded chunk, preserving post-2xx extension side effects rather than field bytes.
 
 The provider-neutral `llm` package and `llm-pi-ai` contain no extension type, service lookup, field merge, or acceptance call.
 
 ## Incremental session-log field
 
-`@deepseek-ai/dsh-session-log-deepseek` owns `dsh_session_log` as an explicit opt-in. When enabled, each request carrying a live Session id sends the contiguous canonical event suffix after the greatest durable `session-log-deepseek/delivery-accepted` watermark for that same Session identity. The field includes the immutable Session header and complete event envelopes. A 2xx appends a new watermark for the transmitted `throughSeq`; that event enters the following request's suffix. Forked logs retain parent watermark ids, so a child starts from sequence zero under its own identity. Concurrent acceptances may arrive out of order, and the maximum watermark remains authoritative. A process-local fold scans each Session event once and incrementally consumes later appends; a new Session object or HMR generation rebuilds the fold from durable history.
+`@deepseek-ai/dsh-session-log-deepseek` owns the default-on `dsh_session_log` field. When enabled, each request carrying a live Session id sends the contiguous canonical event suffix after the greatest durable `session-log-deepseek/delivery-accepted` watermark for that same Session identity. The field includes the immutable Session header and complete event envelopes. A 2xx appends a new watermark for the transmitted `throughSeq`; that event enters the following request's suffix. Forked logs retain parent watermark ids, so a child starts from sequence zero under its own identity. Concurrent acceptances may arrive out of order, and the maximum watermark remains authoritative. A process-local fold scans each Session event once and incrementally consumes later appends; a new Session object or HMR generation rebuilds the fold from durable history.
 
 The failure direction is at least once. A transport or provider rejection records no watermark. A crash after remote acceptance but before the watermark persists causes replay after resume, never a skipped sequence. Existing session checkpoints persist the event; the upload plugin owns no second store.
 
@@ -50,7 +50,7 @@ The process-lifetime manifest-identity cache remains separate because in-process
 
 ## Verification
 
-Registry tests pin duplicate ownership, effect-scoped disposal, detached field values, concurrent and abortable preparation, receiver-preserving acceptance, one acceptance settlement, and failure aggregation. Session tests pin the default-off policy, explicit full-first/suffix-later delivery, direct complete event envelopes independent of base-body messages, incremental watermark folding, persisted restart recovery, fork identity fencing, out-of-order acceptance, and late invariant loading. Package-inventory tests pin default-on and explicit-off policies, host and standing-preset discovery, conflicting Loader resolution bases, manifest resolution, lifecycle filtering, and exact name/version ordering. The direct adapter mock proves pre-HTTP preparation failure, cancellation, non-2xx non-acceptance, 2xx acceptance before a later stream failure, and field collision. Keyless replay pins post-2xx extension acceptance, and the TypeScript JSON-RPC plus Python packaged-runtime snapshots project the acceptance event through both SDKs. Real Loader composition pins default package metadata plus opt-in Session upload, one real-API request mounts both shipped extensions and proves the official endpoint accepts them, and pi-ai tests retain their unchanged wire requests.
+Registry tests pin duplicate ownership, effect-scoped disposal, detached field values, concurrent and abortable preparation, receiver-preserving acceptance, one acceptance settlement, and failure aggregation. Session tests pin default-on and explicit-off policies, full-first/suffix-later delivery, direct complete event envelopes independent of base-body messages, incremental watermark folding, persisted restart recovery, fork identity fencing, out-of-order acceptance, and late invariant loading. Package-inventory tests pin default-on and explicit-off policies, host and standing-preset discovery, conflicting Loader resolution bases, manifest resolution, lifecycle filtering, and exact name/version ordering. The direct adapter mock proves pre-HTTP preparation failure, cancellation, non-2xx non-acceptance, 2xx acceptance before a later stream failure, and field collision. Keyless replay pins post-2xx extension acceptance, and the TypeScript JSON-RPC plus Python packaged-runtime snapshots project the acceptance event through both SDKs. Real Loader composition pins default package metadata and Session upload plus explicit upload disablement, one real-API request mounts both shipped extensions and proves the official endpoint accepts them, and pi-ai tests retain their unchanged wire requests.
 
 ## Alternatives considered
 
@@ -85,7 +85,7 @@ About 98% of the measured v1 real-session events were `assistant/chunk`. Omittin
 
 ## Consequences
 
-Official DeepSeek requests carry active package versions to their resolved `baseURL`, including configured gateways. An explicit Session-log opt-in also carries the complete newly unaccepted Session suffix. The fields are model-hidden and add no prompt tokens or KV-cache changes, but can substantially increase HTTP body size. Manifest resolution, field collision, acceptance logging, or provider schema rejection fails the model request rather than silently dropping metadata.
+Official DeepSeek requests carry active package versions to their resolved `baseURL`, including configured gateways. Unless Session-log upload is disabled, each eligible request also carries the complete newly unaccepted Session suffix. The fields are model-hidden and add no prompt tokens or KV-cache changes, but can substantially increase HTTP body size. Manifest resolution, field collision, acceptance logging, or provider schema rejection fails the model request rather than silently dropping metadata.
 
 The `delivery-accepted` event becomes part of the canonical log and is itself delivered on a later request. Crash recovery can duplicate a suffix but does not infer acceptance from assistant output or create a second local cursor store. Direct calls without a live Session omit the session field; host package inventory remains available.
 

+ 4 - 4
.agents/notes/implemented/architecture/2026-08-21-deepseek-llm-api-request-extensions.zh.md

@@ -14,13 +14,13 @@ Status: implemented
 
 ## 决策
 
-`@deepseek-ai/dsh-deepseek-llm-api-extensions` 注册 `ctx.deepseekLlmApiExtensions`,即 `deepseek-official` 请求正文顶层字段的增量注册表。贡献方通过 `register()` 认领一个经声明合并的字段。适配器在序列化确切协议消息后调用 `prepare()`、传入请求取消信号,在 HTTP 前拒绝准备失败或基础字段冲突,合并分离字段,并在 HTTP 2xx 后调用捕获的 `accept()` 事务。即使贡献方忽略信号,注册表也会在取消后停止等待准备。接受失败仍以 `REQUEST_EXTENSION` 使请求失败;传输失败与非 2xx 失败绝不会接受贡献。未挂载注册表的组合会保留可复用基础适配器。随附组合会挂载注册表与两个贡献方:插件包元数据默认开启,会话日志上传默认关闭,需要设置 `session-log-deepseek.enabled: true`。无密钥 `deepseek-official` 回放会使用合成的空基础正文执行准备,并在第一个已记录分片前调用同一接受事务;它保持的是 2xx 后扩展副作用,而非字段字节。
+`@deepseek-ai/dsh-deepseek-llm-api-extensions` 注册 `ctx.deepseekLlmApiExtensions`,即 `deepseek-official` 请求正文顶层字段的增量注册表。贡献方通过 `register()` 认领一个经声明合并的字段。适配器在序列化确切协议消息后调用 `prepare()`、传入请求取消信号,在 HTTP 前拒绝准备失败或基础字段冲突,合并分离字段,并在 HTTP 2xx 后调用捕获的 `accept()` 事务。即使贡献方忽略信号,注册表也会在取消后停止等待准备。接受失败仍以 `REQUEST_EXTENSION` 使请求失败;传输失败与非 2xx 失败绝不会接受贡献。未挂载注册表的组合会保留可复用基础适配器。随附组合会挂载注册表与两个贡献方:插件包元数据和会话日志上传均默认开启;按[默认上传决策](2026-09-14-session-log-upload-default.zh.md),设置 `session-log-deepseek.enabled: false` 可关闭日志上传。无密钥 `deepseek-official` 回放会使用合成的空基础正文执行准备,并在第一个已记录分片前调用同一接受事务;它保持的是 2xx 后扩展副作用,而非字段字节。
 
 提供方无关的 `llm` 包与 `llm-pi-ai` 不包含任何扩展类型、服务查找、字段合并或接受调用。
 
 ## 增量会话日志字段
 
-`@deepseek-ai/dsh-session-log-deepseek` 以显式选择启用的方式拥有 `dsh_session_log`。启用后,每个携带存活会话 id 的请求都会发送该确切会话身份最大持久 `session-log-deepseek/delivery-accepted` 水位之后的连续权威事件后缀。该字段包含不可变会话 header 与完整事件信封。2xx 会为已发送的 `throughSeq` 追加新水位;该事件会进入下一次请求的后缀。Fork 日志会保留父级水位 id,因此子会话会在自己的身份下从序列零开始。并发接受可能乱序到达,最大水位仍保持权威。进程内 fold 会让每条会话事件只被扫描一次,并增量消费后续追加;新的会话对象或 HMR generation 会从持久历史重建该 fold。
+`@deepseek-ai/dsh-session-log-deepseek` 拥有默认开启的 `dsh_session_log` 字段。启用后,每个携带存活会话 id 的请求都会发送该确切会话身份最大持久 `session-log-deepseek/delivery-accepted` 水位之后的连续权威事件后缀。该字段包含不可变会话 header 与完整事件信封。2xx 会为已发送的 `throughSeq` 追加新水位;该事件会进入下一次请求的后缀。Fork 日志会保留父级水位 id,因此子会话会在自己的身份下从序列零开始。并发接受可能乱序到达,最大水位仍保持权威。进程内 fold 会让每条会话事件只被扫描一次,并增量消费后续追加;新的会话对象或 HMR generation 会从持久历史重建该 fold。
 
 失败方向为至少一次。传输失败或提供方拒绝不会记录水位。远端接受后、水位持久化前发生崩溃,会在恢复后触发重放,绝不会跳过序列。现有会话检查点会持久化该事件;上传插件不拥有第二份存储。
 
@@ -50,7 +50,7 @@ Status: implemented
 
 ## 验证
 
-注册表测试固定重复所有权、effect 作用域 dispose(资源释放)、分离字段值、并发且可取消的准备、保留接收者的接受操作、单次接受结算与失败聚合。会话测试固定默认关闭策略、显式启用后的首次完整/后续后缀交付、与基础正文消息无关的直接完整事件信封、增量水位 fold、持久化重启恢复、fork 身份围栏、乱序接受与 invariant 延迟加载。插件包清单测试固定默认开启与显式关闭策略、宿主与 standing preset 发现、冲突的 Loader 解析基址、manifest 解析、生命周期过滤及确切名称/版本排序。直接适配器 mock 测试证明 HTTP 前准备失败、取消、非 2xx 不接受、2xx 在后续流失败前接受,以及字段冲突。无密钥回放会固定 2xx 后扩展接受,TypeScript JSON-RPC 与 Python 打包运行时快照则通过两套 SDK 投影接受事件。真实 Loader 组合会固定默认包元数据与显式启用的会话上传,一个真实 API 请求会挂载两个随附扩展并证明官方端点接受它们;pi-ai 测试保持其协议请求不变。
+注册表测试固定重复所有权、effect 作用域 dispose(资源释放)、分离字段值、并发且可取消的准备、保留接收者的接受操作、单次接受结算与失败聚合。会话测试固定默认开启与显式关闭策略、首次完整/后续后缀交付、与基础正文消息无关的直接完整事件信封、增量水位 fold、持久化重启恢复、fork 身份围栏、乱序接受与 invariant 延迟加载。插件包清单测试固定默认开启与显式关闭策略、宿主与 standing preset 发现、冲突的 Loader 解析基址、manifest 解析、生命周期过滤及确切名称/版本排序。直接适配器 mock 测试证明 HTTP 前准备失败、取消、非 2xx 不接受、2xx 在后续流失败前接受,以及字段冲突。无密钥回放会固定 2xx 后扩展接受,TypeScript JSON-RPC 与 Python 打包运行时快照则通过两套 SDK 投影接受事件。真实 Loader 组合会固定默认包元数据、默认会话上传与显式关闭上传,一个真实 API 请求会挂载两个随附扩展并证明官方端点接受它们;pi-ai 测试保持其协议请求不变。
 
 ## 考虑过的替代方案
 
@@ -85,7 +85,7 @@ Status: implemented
 
 ## 后果
 
-DeepSeek 官方请求会把存活包版本发送到解析后的 `baseURL`,包括已配置 gateway。显式选择启用会话日志后,请求还会携带完整的未接受会话新后缀。这些字段对模型不可见,不增加提示词 token,也不改变 KV Cache,但可能显著增大 HTTP 正文。Manifest 解析、字段冲突、接受记录或提供方 schema 拒绝会使模型请求失败,而不会静默丢弃元数据。
+DeepSeek 官方请求会把存活包版本发送到解析后的 `baseURL`,包括已配置 gateway。除非关闭会话日志上传,否则符合条件的请求还会携带完整的未接受会话新后缀。这些字段对模型不可见,不增加提示词 token,也不改变 KV Cache,但可能显著增大 HTTP 正文。Manifest 解析、字段冲突、接受记录或提供方 schema 拒绝会使模型请求失败,而不会静默丢弃元数据。
 
 `delivery-accepted` 事件会成为权威日志的一部分,并在后续请求中自行交付。崩溃恢复可能重复后缀,但不会根据 assistant 输出推断接受,也不会创建第二份本地游标存储。缺少存活会话的直接调用会省略会话字段;宿主包清单仍然可用。
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.i18n.yaml

@@ -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 .agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.md
-2026-09-05-canonical-feedback-log.md: c890064817ac0604fa4cc2b4073850174195e511
-2026-09-05-canonical-feedback-log.zh.md: e7e8563df8ad37d7aba641e58da4fc8872ec10b9
+2026-09-05-canonical-feedback-log.md: ce7b705b24cb0a4f7432215e19589095a9afc719
+2026-09-05-canonical-feedback-log.zh.md: 7d970ff7aea4962ea52c764fec5b6c07e3669099

+ 2 - 2
.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.md

@@ -14,7 +14,7 @@ The canonical Session log owns feedback. Session-level remarks use `feedback/rec
 
 Live message-feedback mutations append through the owning Session and await its durability checkpoint; cold mutations hold a persistence write handle across read, comparison, append, and flush without creating a Session or Agent. A matching no-op appends nothing but still awaits persistence. Failures propagate, and a failed live flush can leave an observable in-memory item for retry. Per-item versions prevent unrelated message edits from conflicting; strict stale-write rejection prevents ABA overwrites even when the desired value matches. Target validation binds a judgment to a sent assistant message, and forks keep independent judgments. These choices retain rationale recorded in the [archived sidecar decision](../../archived/architecture/2026-08-10-message-feedback-sidecar.md), whose storage and commit mechanism is superseded.
 
-The existing opt-in [session-log-deepseek contribution](../../../../packages/session/session-log-deepseek/README.md) includes feedback in the ordinary `dsh_session_log` suffix on a subsequent eligible request. It uses the existing DeepSeek destination selection and acceptance watermark. There is no separate `dsh_feedback` uploader, feedback-triggered LLM request, or model-input field. The [explicit-feedback OTel decision](2026-09-05-nonofficial-feedback-otel.md) owns the independent feedback-triggered upload for all users and providers.
+The existing default-on [session-log-deepseek contribution](../../../../packages/session/session-log-deepseek/README.md) includes feedback in the ordinary `dsh_session_log` suffix on a subsequent eligible request. It uses the existing DeepSeek destination selection and acceptance watermark. There is no separate `dsh_feedback` uploader, feedback-triggered LLM request, or model-input field. The [explicit-feedback OTel decision](2026-09-05-nonofficial-feedback-otel.md) owns the independent feedback-triggered upload for all users and providers.
 
 The command confirms recording with the Session and anonymous user ids, without depending on telemetry or disclosing its policy. Its append remains unflushed. This supersedes the command-copy decision in the [archived sharing disclosure note](../../archived/feature/2026-08-07-feedback-acknowledgement-sharing-disclosure.md). The [telemetry service's policy API](../../../../packages/session/session-telemetry/README.md#the-sharing-disclosure) remains independently available: a backend discloses its policy, not delivery or retention, and the optional OTel package does not own that vocabulary.
 
@@ -24,7 +24,7 @@ The command confirms recording with the Session and anonymous user ids, without
 
 **Reuse `feedback/record` for message edits.** A free-text Session remark does not identify an item mutation. Distinct events preserve message identity and deletion semantics; upload policy remains consumer-owned.
 
-**Add a dedicated feedback uploader or immediate LLM request.** The opt-in log contribution carries canonical events on eligible requests. The existing OTel pipeline independently handles explicit-feedback uploads for all providers, without a custom feedback uploader or another model request.
+**Add a dedicated feedback uploader or immediate LLM request.** The default-on log contribution carries canonical events on eligible requests. The existing OTel pipeline independently handles explicit-feedback uploads for all providers, without a custom feedback uploader or another model request.
 
 ## Consequences
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-09-05-canonical-feedback-log.zh.md

@@ -14,7 +14,7 @@ Status: implemented
 
 live 消息反馈变更通过所属 Session 追加,并等待其持久化检查点;cold 变更在读取、比较、追加和 flush 期间持有持久化写句柄,不创建 Session 或 Agent。匹配版本的无变更操作不追加事件,但仍等待持久化。故障会原样传播,live flush 失败可能留下可观测的内存条目以供重试。逐条版本避免不同消息的编辑互相冲突;严格拒绝陈旧写入避免 ABA 覆盖,即使期望值已经匹配也不例外。目标校验把判断绑定到已发送的 assistant 消息,fork 保持独立判断。这些选择保留[已归档伴随记录决策](../../archived/architecture/2026-08-10-message-feedback-sidecar.md)记载的理由,但其存储与提交机制已被取代。
 
-现有需显式启用的 [session-log-deepseek 贡献](../../../../packages/session/session-log-deepseek/README.zh.md)会在后续符合条件的请求中,把反馈纳入普通 `dsh_session_log` 后缀。它使用现有的 DeepSeek 目标选择和接受水位。没有独立的 `dsh_feedback` 上传器、反馈触发的 LLM 请求或模型输入字段。[显式反馈 OTel 决策](2026-09-05-nonofficial-feedback-otel.zh.md)负责面向所有用户和提供方的独立反馈触发上传。
+现有默认开启的 [session-log-deepseek 贡献](../../../../packages/session/session-log-deepseek/README.zh.md)会在后续符合条件的请求中,把反馈纳入普通 `dsh_session_log` 后缀。它使用现有的 DeepSeek 目标选择和接受水位。没有独立的 `dsh_feedback` 上传器、反馈触发的 LLM 请求或模型输入字段。[显式反馈 OTel 决策](2026-09-05-nonofficial-feedback-otel.zh.md)负责面向所有用户和提供方的独立反馈触发上传。
 
 命令用 Session 与匿名用户 id 确认记录,不依赖遥测,也不披露其策略。其追加仍不执行 flush。这取代[已归档共享披露记录](../../archived/feature/2026-08-07-feedback-acknowledgement-sharing-disclosure.md)中的命令文案决策。[遥测服务的策略 API](../../../../packages/session/session-telemetry/README.zh.md#the-sharing-disclosure) 仍可独立使用:后端披露策略,而不保证投递或保留,可选 OTel 包不拥有这套词汇。
 
@@ -24,7 +24,7 @@ live 消息反馈变更通过所属 Session 追加,并等待其持久化检查
 
 **对消息编辑复用 `feedback/record`。** 自由文本的 Session 备注不能标识条目变更。独立事件保留消息身份和删除语义;上传策略仍由消费方负责。
 
-**增加专用反馈上传器或立即发起 LLM 请求。** 需显式启用的日志贡献在符合条件的请求上传送权威事件。现有 OTel 流水线独立处理所有提供方的显式反馈上传,无需自定义反馈上传器或另一个模型请求。
+**增加专用反馈上传器或立即发起 LLM 请求。** 默认开启的日志贡献在符合条件的请求上传送权威事件。现有 OTel 流水线独立处理所有提供方的显式反馈上传,无需自定义反馈上传器或另一个模型请求。
 
 ## 后果
 

+ 2 - 2
.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.i18n.yaml

@@ -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 .agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.md
-2026-09-05-nonofficial-feedback-otel.md: bbc947455f7a84a41af6651223eb62129fa8d452
-2026-09-05-nonofficial-feedback-otel.zh.md: de9b0322861118cdc1163a0faefb172fc1062776
+2026-09-05-nonofficial-feedback-otel.md: 8225d8bea030c4f09b60fd1a228f0425e9489d39
+2026-09-05-nonofficial-feedback-otel.zh.md: e8ea48b3fe2f228ef57ae1a20f92100dfc333f9c

+ 2 - 2
.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.md

@@ -16,7 +16,7 @@ An authorized prefix includes all unhanded canonical context from seq 0 through
 
 The backend uses on-demand capture with complete history and the existing redaction waterfall. `DISABLED` constructs no transport. `FULL` is rejected rather than aliased. Direct `ctx.sessionTelemetry.emit()` calls are no-ops, so callers cannot bypass feedback authorization. SDK scheduled flush and shutdown may finish previously authorized batches but never capture new records. Sending after submission needs no further user interaction or model call.
 
-The [canonical-feedback decision](2026-09-05-canonical-feedback-log.md) owns storage, versions, deletion, and plain command confirmation. The [opt-in DeepSeek contribution](../../../../packages/session/session-log-deepseek/README.md) remains independent, with its existing destination and acceptance behavior.
+The [canonical-feedback decision](2026-09-05-canonical-feedback-log.md) owns storage, versions, deletion, and plain command confirmation. The [default-on DeepSeek contribution](../../../../packages/session/session-log-deepseek/README.md) remains independent, with its existing destination and acceptance behavior.
 
 ## Alternatives considered
 
@@ -28,6 +28,6 @@ The [canonical-feedback decision](2026-09-05-canonical-feedback-log.md) owns sto
 
 ## Consequences
 
-Handoff is best-effort, not collector acceptance. Same-object cursors suppress repeated capture, but fresh cold snapshots and new feedback after restart can repeat prefixes; receivers deduplicate on `(session.id, session.format_version, event.seq)`. There is no durable OTel outbox, delivery watermark, or harness HTTP retry promise. SDK batching and loss behavior apply after enqueue. OTel and the opt-in DeepSeek path can overlap. Withdrawal exports a deletion event, not remote erasure.
+Handoff is best-effort, not collector acceptance. Same-object cursors suppress repeated capture, but fresh cold snapshots and new feedback after restart can repeat prefixes; receivers deduplicate on `(session.id, session.format_version, event.seq)`. There is no durable OTel outbox, delivery watermark, or harness HTTP retry promise. SDK batching and loss behavior apply after enqueue. OTel and the default-on DeepSeek path can overlap. Withdrawal exports a deletion event, not remote erasure.
 
 [OTel tests](../../../../packages/session/session-telemetry-otel/tests/otel.spec.ts) cover explicit-feedback capture, provider-independent behavior, lifecycle silence, fork consent, cold commits, and direct-call denial. [Coordinator tests](../../../../packages/session/session-telemetry/tests/telemetry.spec.ts) cover history capture; [base tests](../../../../packages/bundle/base/tests/base.spec.ts) pin the mounted default.

+ 2 - 2
.agents/notes/implemented/architecture/2026-09-05-nonofficial-feedback-otel.zh.md

@@ -16,7 +16,7 @@ Status: implemented
 
 后端使用包含完整历史的按需捕获与现有脱敏 waterfall(瀑布式事件)。`DISABLED` 不构造传输。`FULL` 被拒绝,不作为别名。直接调用 `ctx.sessionTelemetry.emit()` 是空操作,因此调用方不能绕过反馈授权。SDK 定时刷新和关闭可以完成先前已授权的批次,但绝不捕获新记录。提交后的发送无需进一步用户交互或模型调用。
 
-[权威反馈决策](2026-09-05-canonical-feedback-log.zh.md)负责存储、版本、删除与纯命令确认。[需主动开启的 DeepSeek 贡献](../../../../packages/session/session-log-deepseek/README.zh.md)保持独立,保留现有目标与接受行为。
+[权威反馈决策](2026-09-05-canonical-feedback-log.zh.md)负责存储、版本、删除与纯命令确认。[默认开启的 DeepSeek 贡献](../../../../packages/session/session-log-deepseek/README.zh.md)保持独立,保留现有目标与接受行为。
 
 ## 考虑过的替代方案
 
@@ -28,6 +28,6 @@ Status: implemented
 
 ## 后果
 
-交接尽力而为,不代表采集端接受。同对象游标抑制重复捕获,但新冷快照和重启后的新反馈可能重复前缀;接收方按 `(session.id, session.format_version, event.seq)` 去重。没有持久化 OTel outbox、投递水位或 harness HTTP 重试承诺。入队后适用 SDK 批处理与丢失行为。OTel 与需主动开启的 DeepSeek 路径可能重叠。撤回导出删除事件,不是远端擦除。
+交接尽力而为,不代表采集端接受。同对象游标抑制重复捕获,但新冷快照和重启后的新反馈可能重复前缀;接收方按 `(session.id, session.format_version, event.seq)` 去重。没有持久化 OTel outbox、投递水位或 harness HTTP 重试承诺。入队后适用 SDK 批处理与丢失行为。OTel 与默认开启的 DeepSeek 路径可能重叠。撤回导出删除事件,不是远端擦除。
 
 [OTel 测试](../../../../packages/session/session-telemetry-otel/tests/otel.spec.ts)覆盖显式反馈捕获、提供方无关行为、生命周期静默、fork 同意、冷会话提交与直接调用拒绝。[协调器测试](../../../../packages/session/session-telemetry/tests/telemetry.spec.ts)覆盖历史捕获;[基础配置测试](../../../../packages/bundle/base/tests/base.spec.ts)固定挂载默认值。

+ 6 - 0
.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# 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 .agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md
+2026-09-14-session-log-upload-default.md: c1e7c9e050d1b1809ff3abba03fe4e17a3779daa
+2026-09-14-session-log-upload-default.zh.md: d7b6e64098eca3fe07c43272fcba18a3790182e2

+ 28 - 0
.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.md

@@ -0,0 +1,28 @@
+# Agent Note: Default DeepSeek Session-log upload
+
+Status: implemented
+
+English | [中文](2026-09-14-session-log-upload-default.zh.md)
+## Problem
+
+Ordinary DeepSeek requests do not contain the complete canonical Session trajectory. Requiring each installation to enable log contribution prevents the default product configuration from supplying that trajectory. Recorded-session scenarios also need stable, explicit upload policies because acceptance events are part of their expected logs.
+
+## Decision
+
+`session-log-deepseek.Config.enabled` defaults to `true` in every process. An explicit `enabled: false` disables the contribution. The plugin does not inspect test-runner or snapshot environment variables.
+
+This supersedes only the opt-in default in the [request-extension decision](2026-08-21-deepseek-llm-api-request-extensions.md); that note still owns field serialization, destinations, acceptance, and retry semantics. The headless and ACP corpus base patches and Web scaffold explicitly disable upload. Later scenario patches can enable it. The SDK text-turn recording omits the setting and exercises the shipped default, including durable acceptance events.
+
+## Alternatives considered
+
+**Derive the production default from test environment markers.** This also changes downstream SDK behavior when callers inherit those variables and makes ordinary tests exercise a different product default.
+
+**Refresh every recorded Session to include upload acceptance.** Explicit test composition preserves the existing scenarios while a default-configured SDK recording and Loader regression cover the default-on path.
+
+**Retain opt-in upload.** This does not supply the complete trajectory from ordinary product requests without installation-specific configuration.
+
+## Consequences
+
+Eligible requests send the complete unaccepted canonical log suffix, including message text, tool arguments and results, workspace paths, and feedback, to the resolved DeepSeek endpoint or configured gateway. No prompt tokens or model-visible content are added. Request bodies can grow substantially, and provider rejection still fails the request. OTel remains independent; disabling OTel does not disable this contribution.
+
+Configuration tests cover default-on and explicit overrides with and without test environment markers. Both DeepSeek protocol Loader cases observe the default request field and recorded acceptance watermark, and explicit-off cases observe their absence. Existing headless, ACP, Web, and SDK recordings validate their declared upload policies without rewriting committed Session generations.

+ 28 - 0
.agents/notes/implemented/architecture/2026-09-14-session-log-upload-default.zh.md

@@ -0,0 +1,28 @@
+# Agent Note: DeepSeek 会话日志默认上传
+
+Status: implemented
+
+[English](2026-09-14-session-log-upload-default.md) | 中文
+## 问题
+
+普通 DeepSeek 请求不包含完整的规范会话轨迹。要求每个安装环境启用日志贡献,会使默认产品配置无法提供该轨迹。录制会话场景也需要稳定、明确的上传策略,因为接受事件属于其期望日志。
+
+## 决策
+
+`session-log-deepseek.Config.enabled` 在所有进程中均默认为 `true`。显式设置 `enabled: false` 可关闭贡献。插件不读取测试运行器或快照环境变量。
+
+本决策仅取代[请求扩展决策](2026-08-21-deepseek-llm-api-request-extensions.zh.md)中的主动启用默认策略;该记录仍负责字段序列化、目的地址、接受与重试语义。headless 和 ACP 语料的基础 patch 以及 Web scaffold 显式关闭上传。后续场景 patch 可以启用上传。SDK text-turn 录制省略该设置,验证产品默认值及持久接受事件。
+
+## 考虑过的替代方案
+
+**根据测试环境标记决定生产默认值。** 调用者继承这些变量时,下游 SDK 行为也会改变,普通测试还会采用不同的产品默认值。
+
+**刷新所有录制会话以包含上传接受事件。** 显式测试配置保留现有场景,同时使用默认配置的 SDK 录制和 Loader 回归验证默认开启路径。
+
+**保留主动启用策略。** 没有安装环境专用配置时,该策略无法从普通产品请求提供完整轨迹。
+
+## 后果
+
+符合条件的请求会向解析后的 DeepSeek 端点或已配置网关发送完整的未接受规范日志后缀,包括消息文本、工具参数与结果、工作区路径和反馈。不增加提示词 token 或模型可见内容。请求正文可能显著增大,提供方拒绝仍会使请求失败。OTel 保持独立,关闭 OTel 不会关闭此贡献。
+
+配置测试覆盖有无测试环境标记时的默认开启与显式覆盖。两种 DeepSeek 协议的 Loader 用例观察默认请求字段和已记录的接受水位,显式关闭用例观察两者均不存在。现有 headless、ACP、Web 和 SDK 录制验证各自声明的上传策略,无需重写已提交的会话代际。

+ 2 - 2
apps/cli/reference/README.i18n.yaml

@@ -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 apps/cli/reference/README.md
-README.md: 5a92052eb24c8af432c2ede371a2ff2bc84f57c0
-README.zh.md: a9268ad4920a7d5a72a4b0ead9b2672d22e10805
+README.md: ce8dcc40297cb8ae7eff4f90ada61f97588677d4
+README.zh.md: 32bc15a3be5cd28866c4db0dbe593a4b1e119101

+ 2 - 2
apps/cli/reference/README.md

@@ -98,9 +98,9 @@ New sessions in base-backed profiles default to the `workspace-write` permission
 
 ## Shared deployment behavior
 
-The base bundle mounts the native DeepSeek adapter, settings and credential providers, stable `web_search` and `web_fetch`, the public-only HTTP fetch provider, opt-in DeepSeek session-log upload, and feedback-gated OTel upload for all users. Provider credentials resolve from the inherited environment, `$DSH_HOME/.credentials.yaml`, the invoking directory's `.env`, then `$DSH_HOME/.env`; the managed document is never materialized into `process.env`, while both `.env` files are ordinary launch environment layers. Search uses `DEEPSEEK_API_KEY` and accepts `DEEPSEEK_SEARCH_BASE_URL`. Enabled fetch calls run in every sandbox and approval mode without per-call confirmation; the provider rejects non-public destinations before connecting. The Web app disables the base tool row and exposes the same tools through its `cordis`, `ptc`, and `standard` agent presets.
+The base bundle mounts the native DeepSeek adapter, settings and credential providers, stable `web_search` and `web_fetch`, the public-only HTTP fetch provider, default-on DeepSeek session-log upload, and feedback-gated OTel upload for all users. Provider credentials resolve from the inherited environment, `$DSH_HOME/.credentials.yaml`, the invoking directory's `.env`, then `$DSH_HOME/.env`; the managed document is never materialized into `process.env`, while both `.env` files are ordinary launch environment layers. Search uses `DEEPSEEK_API_KEY` and accepts `DEEPSEEK_SEARCH_BASE_URL`. Enabled fetch calls run in every sandbox and approval mode without per-call confirmation; the provider rejects non-public destinations before connecting. The Web app disables the base tool row and exposes the same tools through its `cordis`, `ptc`, and `standard` agent presets.
 
-Feedback is recorded in the Session log without starting model work. Enable the [DeepSeek session-log contributor](../../../packages/session/session-log-deepseek/README.md) to send complete unaccepted log suffixes with subsequent DeepSeek requests, including requests sent through configured gateways. [OTel session upload](../../../packages/session/session-telemetry-otel/README.md) applies to all users and providers, including `deepseek-official`, without requiring a request header. The base defaults to `FEEDBACK_ONLY`: new own text feedback, message ratings, edits, and withdrawals release the complete canonical prefix through that event, including stored context; later records wait for the next explicit feedback. Inherited parent feedback does not authorize a fork. Requests, restoration, mount, and HMR do not trigger capture. SDK batching may finish an authorized upload without further interaction or model work. `DSH_TELEMETRY_MODE=DISABLED` disables OTel delivery; `FULL` is rejected, and any non-empty `DSH_TELEMETRY_DISABLED` disables its row. `DSH_TELEMETRY_OTLP_URL` selects the collector. Handoff is best-effort, not collector acceptance; no durable outbox or retry guarantee is provided. These OTel settings do not enable or disable the DeepSeek contribution. Neither path changes model input, but exports can include message text, tool arguments and results, and workspace paths.
+Feedback is recorded in the Session log without starting model work. The [DeepSeek session-log contributor](../../../packages/session/session-log-deepseek/README.md) sends complete unaccepted log suffixes with subsequent DeepSeek requests by default, including requests sent through configured gateways; set its `enabled` configuration to `false` to opt out. [OTel session upload](../../../packages/session/session-telemetry-otel/README.md) applies to all users and providers, including `deepseek-official`, without requiring a request header. The base defaults to `FEEDBACK_ONLY`: new own text feedback, message ratings, edits, and withdrawals release the complete canonical prefix through that event, including stored context; later records wait for the next explicit feedback. Inherited parent feedback does not authorize a fork. Requests, restoration, mount, and HMR do not trigger capture. SDK batching may finish an authorized upload without further interaction or model work. `DSH_TELEMETRY_MODE=DISABLED` disables OTel delivery; `FULL` is rejected, and any non-empty `DSH_TELEMETRY_DISABLED` disables its row. `DSH_TELEMETRY_OTLP_URL` selects the collector. Handoff is best-effort, not collector acceptance; no durable outbox or retry guarantee is provided. These OTel settings do not enable or disable the DeepSeek contribution. Neither path changes model input, but exports can include message text, tool arguments and results, and workspace paths.
 
 Install external plugin bundles through `dsh plugin --profile <name> add <package-or-git-spec>`. The installed package owns its dependencies and contributes its declared `cordis.patch.yml` layer. The CLI also ships `@deepseek-ai/dsh-mcp-client` as a dependency for patch layers, but no MCP server is enabled by default because each server command is trusted executable code outside the agent sandbox.
 

+ 2 - 2
apps/cli/reference/README.zh.md

@@ -100,9 +100,9 @@ dsh web --help
 
 ## 共享部署行为
 
-基础组合包挂载原生 DeepSeek 适配器、settings 与凭据提供方、稳定的 `web_search` 和 `web_fetch`、仅限公网的 HTTP fetch 提供方,需主动开启的 DeepSeek 会话日志上传,以及面向所有用户的反馈门控 OTel 上传。提供方凭据依次从继承环境、`$DSH_HOME/.credentials.yaml`、调用目录的 `.env` 和 `$DSH_HOME/.env` 解析;受管文档从不物化进 `process.env`,而两个 `.env` 文件都是普通启动环境层。搜索使用 `DEEPSEEK_API_KEY` 并接受 `DEEPSEEK_SEARCH_BASE_URL`。已启用的抓取调用会在所有 sandbox 与审批模式下执行,无需逐次确认;提供方会在连接前拒绝非公开目的地址。Web app 会禁用 base 工具配置项,再通过 `cordis`、`ptc` 与 `standard` agent preset 暴露相同工具。
+基础组合包挂载原生 DeepSeek 适配器、settings 与凭据提供方、稳定的 `web_search` 和 `web_fetch`、仅限公网的 HTTP fetch 提供方,默认开启的 DeepSeek 会话日志上传,以及面向所有用户的反馈门控 OTel 上传。提供方凭据依次从继承环境、`$DSH_HOME/.credentials.yaml`、调用目录的 `.env` 和 `$DSH_HOME/.env` 解析;受管文档从不物化进 `process.env`,而两个 `.env` 文件都是普通启动环境层。搜索使用 `DEEPSEEK_API_KEY` 并接受 `DEEPSEEK_SEARCH_BASE_URL`。已启用的抓取调用会在所有 sandbox 与审批模式下执行,无需逐次确认;提供方会在连接前拒绝非公开目的地址。Web app 会禁用 base 工具配置项,再通过 `cordis`、`ptc` 与 `standard` agent preset 暴露相同工具。
 
-反馈记录在会话日志中,不会启动模型工作。开启 [DeepSeek 会话日志贡献器](../../../packages/session/session-log-deepseek/README.zh.md)后,后续 DeepSeek 请求会发送尚未确认接收的完整日志后缀,包括经已配置网关发送的请求。[OTel 会话上传](../../../packages/session/session-telemetry-otel/README.zh.md)适用于所有用户和提供方,包括 `deepseek-official`,无需请求头。基础配置默认使用 `FEEDBACK_ONLY`:新的自身文本反馈、消息评分、编辑与撤回会释放截至该事件的完整规范日志前缀,包含存储的上下文;后续记录等待下一次显式反馈。继承的父级反馈不构成 fork 的授权。请求、恢复、挂载和 HMR 不触发捕获。SDK 批处理可完成已授权上传,无需进一步交互或模型工作。`DSH_TELEMETRY_MODE=DISABLED` 禁止 OTel 投递;`FULL` 被拒绝,任何非空的 `DSH_TELEMETRY_DISABLED` 都会禁用其配置行。`DSH_TELEMETRY_OTLP_URL` 选择采集端。交接尽力而为,不代表采集端接受;不提供持久化 outbox 或重试保证。这些 OTel 设置不会开启或关闭 DeepSeek 贡献。两条路径都不改变模型输入,但导出可能包含消息文本、工具参数和结果,以及工作区路径。
+反馈记录在会话日志中,不会启动模型工作。[DeepSeek 会话日志贡献器](../../../packages/session/session-log-deepseek/README.zh.md)默认随后续 DeepSeek 请求发送尚未确认接收的完整日志后缀,包括经已配置网关发送的请求;将其 `enabled` 配置设为 `false` 可关闭上传。[OTel 会话上传](../../../packages/session/session-telemetry-otel/README.zh.md)适用于所有用户和提供方,包括 `deepseek-official`,无需请求头。基础配置默认使用 `FEEDBACK_ONLY`:新的自身文本反馈、消息评分、编辑与撤回会释放截至该事件的完整规范日志前缀,包含存储的上下文;后续记录等待下一次显式反馈。继承的父级反馈不构成 fork 的授权。请求、恢复、挂载和 HMR 不触发捕获。SDK 批处理可完成已授权上传,无需进一步交互或模型工作。`DSH_TELEMETRY_MODE=DISABLED` 禁止 OTel 投递;`FULL` 被拒绝,任何非空的 `DSH_TELEMETRY_DISABLED` 都会禁用其配置行。`DSH_TELEMETRY_OTLP_URL` 选择采集端。交接尽力而为,不代表采集端接受;不提供持久化 outbox 或重试保证。这些 OTel 设置不会开启或关闭 DeepSeek 贡献。两条路径都不改变模型输入,但导出可能包含消息文本、工具参数和结果,以及工作区路径。
 
 通过 `dsh plugin --profile <name> add <package-or-git-spec>` 安装外部插件组合包。安装的包拥有其依赖,并贡献其声明的 `cordis.patch.yml` 层。CLI 还随附 `@deepseek-ai/dsh-mcp-client` 作为供 patch 层使用的依赖,但默认不启用 MCP 服务器,因为每条服务器命令都是 agent 沙箱之外的受信任可执行代码。
 

+ 1 - 0
apps/web/tests/scaffold.ts

@@ -521,6 +521,7 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise<We
   const patches: PatchOptions[] = [
     ...basePatches,
     ...surfacePatches,
+    { id: 'session-log-deepseek', config: { enabled: false } },
     // The historical Messages fixture retains its recorded route during replay;
     // live configuration uses the shared DeepSeek route. Explicit overlays win.
     ...messages

+ 2 - 2
docs/config-catalog.i18n.yaml

@@ -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/config-catalog.md
-config-catalog.md: 06e2a8417e219799a59a0531fef39f62a5b1dc6a
-config-catalog.zh.md: 246705482367b5618223a922f1c31f82073061e8
+config-catalog.md: 351aa11257708e4f7af06d621d38a3d7088ee857
+config-catalog.zh.md: 6da38435c9da889a0e4166eb95f6b04f0bb68ef0

+ 1 - 1
docs/config-catalog.md

@@ -2031,7 +2031,7 @@ export interface Config {
 }
 ```
 
-Source: [`packages/session/session-log-deepseek/src/index.ts:51`](../packages/session/session-log-deepseek/src/index.ts)
+Source: [`packages/session/session-log-deepseek/src/index.ts:38`](../packages/session/session-log-deepseek/src/index.ts)
 
 <a id="deepseek-aidsh-session-log-export"></a>
 

+ 1 - 1
docs/config-catalog.zh.md

@@ -2033,7 +2033,7 @@ export interface Config {
 }
 ```
 
-来源:[`packages/session/session-log-deepseek/src/index.ts:51`](../packages/session/session-log-deepseek/src/index.ts)
+来源:[`packages/session/session-log-deepseek/src/index.ts:38`](../packages/session/session-log-deepseek/src/index.ts)
 
 <a id="deepseek-aidsh-session-log-export"></a>
 

+ 2 - 2
docs/user/guide/python-sdk.i18n.yaml

@@ -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/user/guide/python-sdk.md
-python-sdk.md: 6fde258d9f4f3e8ba1fd41537129ba5b8f02fd58
-python-sdk.zh.md: f50fd6d2bd37e3dc203b519e07d0df4098cab0c7
+python-sdk.md: 2cb01ffa19d173231902c5c816929fa6b4d499f0
+python-sdk.zh.md: 3db859116530e51a7c7478ab222cbc4d2435dbf2

+ 1 - 1
docs/user/guide/python-sdk.md

@@ -157,7 +157,7 @@ Pass `patches=("/absolute/path/to/editor.patch.yml",)` when constructing `DeepSe
 | Runtime context and compaction | Absent |
 | Session persistence | Uncompressed JSONL under `<dsh_home>/sessions` |
 
-The profile's sole bundle inserts the complete tree over an empty root and does not include `dsh-base`; later base-profile tools therefore cannot appear implicitly. It contains the SDK protocol, one environment-configured DeepSeek adapter, local execution, and persistence, while filesystem tools, settings, managed credentials, telemetry, Web tools, subagents, local instruction discovery, and compaction are absent. It pins `danger-full-access`, so the platform-selected persistent shell can modify any path visible to the runtime; use a disposable checkout or container.
+The profile's sole bundle inserts the complete tree over an empty root and does not include `dsh-base`; later base-profile tools therefore cannot appear implicitly. It contains the SDK protocol, one environment-configured DeepSeek adapter, local execution, and persistence, while filesystem tools, settings, managed credentials, OTel telemetry, Web tools, subagents, local instruction discovery, and compaction are absent. The [DeepSeek session-log contributor](../../../packages/session/session-log-deepseek/README.md) uploads complete unaccepted log suffixes with DeepSeek requests by default; set `session-log-deepseek.enabled: false` in a profile patch to disable it. It pins `danger-full-access`, so the platform-selected persistent shell can modify any path visible to the runtime; use a disposable checkout or container.
 
 The installed wheel still packages the full `web` profile and frontend assets. Run `dsh web` against an explicit `DSH_HOME` when a Python SDK deployment also needs the browser application; `web` is a separate CLI application and cannot serve a Python SDK client.
 

+ 1 - 1
docs/user/guide/python-sdk.zh.md

@@ -157,7 +157,7 @@ dsh plugin --profile sdk-minimal add file:C:/work/my-plugin-bundle
 | 运行时上下文与 compaction | 不存在 |
 | 会话持久化 | `<dsh_home>/sessions` 下的未压缩 JSONL |
 
-该 profile 的唯一组合包会在空根之上插入完整配置树,且不包含 `dsh-base`,因此基础 profile 以后新增的工具不会隐式出现。它包含 SDK 协议、一个由环境配置的 DeepSeek 适配器、本地执行与持久化;文件系统工具、settings、托管凭据、遥测、Web 工具、subagent、本地指令发现和 compaction 均不存在。它固定使用 `danger-full-access`,因此按平台选择的持久 shell 可以修改运行时可见的任何路径;应使用一次性 checkout 或容器。
+该 profile 的唯一组合包会在空根之上插入完整配置树,且不包含 `dsh-base`,因此基础 profile 以后新增的工具不会隐式出现。它包含 SDK 协议、一个由环境配置的 DeepSeek 适配器、本地执行与持久化;文件系统工具、settings、托管凭据、OTel 遥测、Web 工具、subagent、本地指令发现和 compaction 均不存在。[DeepSeek 会话日志贡献器](../../../packages/session/session-log-deepseek/README.zh.md)默认随 DeepSeek 请求上传完整的未接受日志后缀;在 profile patch 中设置 `session-log-deepseek.enabled: false` 可将其关闭。它固定使用 `danger-full-access`,因此按平台选择的持久 shell 可以修改运行时可见的任何路径;应使用一次性 checkout 或容器。
 
 已安装 wheel 仍会打包完整 `web` profile 与前端产物。如果 Python SDK 部署还需要浏览器应用,请针对显式 `DSH_HOME` 运行 `dsh web`;`web` 是独立 CLI 应用,不能为 Python SDK client 提供服务。
 

+ 2 - 2
packages/bundle/base/README.i18n.yaml

@@ -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/bundle/base/README.md
-README.md: fdf2ca4115d87d1ae1ca363468e2140ea4fa896f
-README.zh.md: baaa2047a0e868a66ca8a7669a3a918c3a5b8d4a
+README.md: f9cc3e4d03a0d71d1f598d97633c0f89f7700b42
+README.zh.md: 2e98bb710502b62ad87f04ae768833487b4b5787

+ 1 - 1
packages/bundle/base/README.md

@@ -47,7 +47,7 @@ Run `dsh --profile my-profile "your task"` and you get a working agent with mode
 
 ### What you get
 
-Out of the box, every profile built on this core provides: a DeepSeek model connection (the provider and model are configurable, and you can enable extra providers from your settings), the full tool set — file editing, shell commands, web search, public HTTP(S) fetch, subagents, task and goal tracking — durable sessions that survive restarts, and the default permission policy that confines file writes to your workspace and asks before risky actions. Web fetch runs without per-call approval; its provider rejects non-public destinations. Feedback stays in the Session log. [OTel session upload](../../session/session-telemetry-otel/README.md) defaults to `FEEDBACK_ONLY` for all users, including `deepseek-official`: new text feedback, message ratings, edits, and withdrawals release the complete canonical prefix through that event, including context. Later records wait for the next explicit feedback; sending an authorized batch needs no further interaction or model call. `DISABLED` prevents OTel capture. The opt-in [DeepSeek session-log contributor](../../session/session-log-deepseek/README.md) remains a separate request path.
+Out of the box, every profile built on this core provides: a DeepSeek model connection (the provider and model are configurable, and you can enable extra providers from your settings), the full tool set — file editing, shell commands, web search, public HTTP(S) fetch, subagents, task and goal tracking — durable sessions that survive restarts, and the default permission policy that confines file writes to your workspace and asks before risky actions. Web fetch runs without per-call approval; its provider rejects non-public destinations. Feedback stays in the Session log. [OTel session upload](../../session/session-telemetry-otel/README.md) defaults to `FEEDBACK_ONLY` for all users, including `deepseek-official`: new text feedback, message ratings, edits, and withdrawals release the complete canonical prefix through that event, including context. Later records wait for the next explicit feedback; sending an authorized batch needs no further interaction or model call. `DISABLED` prevents OTel capture. The default-on [DeepSeek session-log contributor](../../session/session-log-deepseek/README.md) remains a separate request path.
 
 Default file editing uses `read`, `write`, and `edit`. The `str_replace_editor` tool remains available as an explicit opt-in. To add it to a base-backed profile, put this entry in the profile, home, or invocation patch:
 

+ 1 - 1
packages/bundle/base/README.zh.md

@@ -47,7 +47,7 @@ kind: "package-bundle"
 
 ### 你得到什么
 
-开箱即用,基于本核心构建的每个 profile 都提供:DeepSeek 模型连接(提供方与模型可配置,你还可以在设置中启用额外提供方)、完整工具集——文件编辑、shell 命令、web 搜索、公开 HTTP(S) 抓取、subagent、任务与目标跟踪——可跨重启存活的持久会话,以及默认权限策略:把文件写入限制在工作区内,危险操作前征询许可。Web 抓取无需逐次审批,其提供方会拒绝非公开目的地址。反馈保存在会话日志中。[OTel 会话上传](../../session/session-telemetry-otel/README.zh.md)对所有用户默认使用 `FEEDBACK_ONLY`,包括 `deepseek-official`:新的文本反馈、消息评分、编辑与撤回会释放截至该事件的完整规范会话日志前缀,包含上下文。后续记录等待下一次显式反馈;发送已授权批次无需进一步交互或模型调用。`DISABLED` 阻止 OTel 捕获。需主动开启的 [DeepSeek 会话日志贡献器](../../session/session-log-deepseek/README.zh.md)仍是独立的请求路径。
+开箱即用,基于本核心构建的每个 profile 都提供:DeepSeek 模型连接(提供方与模型可配置,你还可以在设置中启用额外提供方)、完整工具集——文件编辑、shell 命令、web 搜索、公开 HTTP(S) 抓取、subagent、任务与目标跟踪——可跨重启存活的持久会话,以及默认权限策略:把文件写入限制在工作区内,危险操作前征询许可。Web 抓取无需逐次审批,其提供方会拒绝非公开目的地址。反馈保存在会话日志中。[OTel 会话上传](../../session/session-telemetry-otel/README.zh.md)对所有用户默认使用 `FEEDBACK_ONLY`,包括 `deepseek-official`:新的文本反馈、消息评分、编辑与撤回会释放截至该事件的完整规范会话日志前缀,包含上下文。后续记录等待下一次显式反馈;发送已授权批次无需进一步交互或模型调用。`DISABLED` 阻止 OTel 捕获。默认开启的 [DeepSeek 会话日志贡献器](../../session/session-log-deepseek/README.zh.md)仍是独立的请求路径。
 
 默认文件编辑使用 `read`、`write` 和 `edit`。`str_replace_editor` 工具仍可显式启用。要将它加入基于 base 的 profile,请在 profile、home 或逐次调用 patch 中添加以下条目:
 

+ 2 - 2
packages/llm/llm-deepseek/README.i18n.yaml

@@ -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/llm/llm-deepseek/README.md
-README.md: bfa56e9b10772cd98bab934b75f32c7d651a57e3
-README.zh.md: 395b0106a920a4e31b98588d0e5a06ac19a9b745
+README.md: 48df51396e60f071503e5babd721bca0dcd18249
+README.zh.md: 9fe86f7ea6b93de847247d4a8f8434930d7d664e

+ 2 - 2
packages/llm/llm-deepseek/README.md

@@ -105,7 +105,7 @@ Connection facts are re-read once per operation through the optional settings an
 
 ### Provider-specific request fields
 
-For either protocol, when `ctx.deepseekLlmApiExtensions` is present, the adapter prepares its registered top-level fields from the exact serialized base request before `fetch`. Preparation or field collisions fail before HTTP; after a 2xx response, the adapter accepts every captured contribution before consuming SSE. Transport and non-2xx failures do not accept them. Shipped compositions use this for the optional incremental `dsh_session_log` field and the default-on active `dsh_plugin_packages` inventory; both stay outside model input.
+For either protocol, when `ctx.deepseekLlmApiExtensions` is present, the adapter prepares its registered top-level fields from the exact serialized base request before `fetch`. Preparation or field collisions fail before HTTP; after a 2xx response, the adapter accepts every captured contribution before consuming SSE. Transport and non-2xx failures do not accept them. Shipped compositions use this for the default-on incremental `dsh_session_log` field and the default-on active `dsh_plugin_packages` inventory; both stay outside model input.
 
 ### Failures and recovery
 
@@ -157,7 +157,7 @@ Read these pages when the package-level contract is not enough. They move from t
 - [LLM streaming subsystem](../../../docs/subsystems/llm-streaming.md) — the `StreamChunk` protocol and adapter contract.
 - [llm-retry](../llm-retry/README.md) — the retry executor that applies this adapter's `retryPolicy`.
 - [DeepSeek request extensions](../deepseek-llm-api-extensions/README.md) — lifecycle and acceptance semantics for provider-specific top-level fields.
-- [Session-log upload](../../session/session-log-deepseek/README.md) — the opt-in incremental `dsh_session_log` contribution.
+- [Session-log upload](../../session/session-log-deepseek/README.md) — the default-on incremental `dsh_session_log` contribution.
 - [Plugin package inventory](../plugin-package-inventory-deepseek/README.md) — the default-on `dsh_plugin_packages` contribution.
 - [Twin LLM adapters](../../../.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md) — why DeepSeek ships two structurally different adapters.
 - [Mandatory app attribution headers](../../../.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.md) — the identity every provider request carries.

+ 2 - 2
packages/llm/llm-deepseek/README.zh.md

@@ -105,7 +105,7 @@ Files 模式通过 `maxRequestFilesBytes` 与 `maxImagesPerRequest` 限制保留
 
 ### 提供方专用请求字段
 
-两种协议中,存在 `ctx.deepseekLlmApiExtensions` 时,适配器都会在 `fetch` 前根据确切序列化基础请求准备已注册顶层字段。准备或字段冲突在 HTTP 前失败;2xx 响应后,适配器会在消费 SSE(Server-Sent Events)前接受每项已捕获贡献。传输与非 2xx 失败不会接受它们。随产品交付的组合用它提供可选增量 `dsh_session_log` 字段和默认启用的活跃 `dsh_plugin_packages` 清单;两者都留在模型输入之外。
+两种协议中,存在 `ctx.deepseekLlmApiExtensions` 时,适配器都会在 `fetch` 前根据确切序列化基础请求准备已注册顶层字段。准备或字段冲突在 HTTP 前失败;2xx 响应后,适配器会在消费 SSE(Server-Sent Events)前接受每项已捕获贡献。传输与非 2xx 失败不会接受它们。随产品交付的组合用它提供默认启用的增量 `dsh_session_log` 字段和默认启用的活跃 `dsh_plugin_packages` 清单;两者都留在模型输入之外。
 
 ### 失败与恢复
 
@@ -157,7 +157,7 @@ Files 模式通过 `maxRequestFilesBytes` 与 `maxImagesPerRequest` 限制保留
 - [LLM 流式子系统](../../../docs/subsystems/llm-streaming.zh.md)——`StreamChunk` 协议与适配器约定。
 - [llm-retry](../llm-retry/README.zh.md)——应用本适配器 `retryPolicy` 的重试执行器。
 - [DeepSeek 请求扩展](../deepseek-llm-api-extensions/README.zh.md)——提供方专用顶层字段的生命周期与接受语义。
-- [会话日志上传](../../session/session-log-deepseek/README.zh.md)——可选的增量 `dsh_session_log` 贡献。
+- [会话日志上传](../../session/session-log-deepseek/README.zh.md)——默认启用的增量 `dsh_session_log` 贡献。
 - [插件包清单](../plugin-package-inventory-deepseek/README.zh.md)——默认启用的 `dsh_plugin_packages` 贡献。
 - [孪生 LLM 适配器](../../../.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.zh.md)——为什么 DeepSeek 交付两个结构不同的适配器。
 - [强制应用归因标头](../../../.agents/notes/implemented/architecture/2026-06-21-mandatory-app-attribution-headers.zh.md)——每个提供方请求携带的身份。

+ 5 - 6
packages/llm/llm-deepseek/tests/loader-composition.spec.ts

@@ -75,8 +75,8 @@ async function loadComposition(
     "  name: '@deepseek-ai/dsh-deepseek-llm-api-extensions'",
     '- id: session-log-deepseek',
     "  name: '@deepseek-ai/dsh-session-log-deepseek'",
-    ...options.enableSessionLog === true
-      ? ['  config:', '    enabled: true']
+    ...options.enableSessionLog !== undefined
+      ? ['  config:', `    enabled: ${String(options.enableSessionLog)}`]
       : [],
     '- id: plugin-package-inventory-deepseek',
     "  name: '@deepseek-ai/dsh-plugin-package-inventory-deepseek'",
@@ -152,10 +152,10 @@ async function extensionServer(protocol: 'chat-completions' | 'messages') {
 }
 
 describe('llm-deepseek real dynamic composition', () => {
-  it.each(['chat-completions', 'messages'] as const)('keeps session upload off and package inventory on by default through %s Loader composition', async (protocol) => {
+  it.each(['chat-completions', 'messages'] as const)('keeps package inventory on when the %s Loader composition disables session upload', async (protocol) => {
     vi.stubEnv('DEEPSEEK_API_KEY', 'entry-key')
     const server = await extensionServer(protocol)
-    const { ctx } = await loadComposition({ withDynamic: false, baseURL: server.url, protocol })
+    const { ctx } = await loadComposition({ withDynamic: false, baseURL: server.url, protocol, enableSessionLog: false })
     const session = ctx.sessions.create(SessionId('extension-composition'))
     session.append('turn/start', { turn: 1 })
 
@@ -171,13 +171,12 @@ describe('llm-deepseek real dynamic composition', () => {
     expect(SessionLogDeepSeek.acceptedThrough(session)).toBe(-1)
   })
 
-  it.each(['chat-completions', 'messages'] as const)('sends the canonical session suffix when the %s Loader composition explicitly enables upload', async (protocol) => {
+  it.each(['chat-completions', 'messages'] as const)('sends the canonical session suffix by default through %s Loader composition', async (protocol) => {
     vi.stubEnv('DEEPSEEK_API_KEY', 'entry-key')
     const server = await extensionServer(protocol)
     const { ctx } = await loadComposition({
       withDynamic: false,
       baseURL: server.url,
-      enableSessionLog: true,
       protocol,
     })
     const session = ctx.sessions.create(SessionId('extension-composition-enabled'))

+ 2 - 2
packages/session/session-log-deepseek/README.i18n.yaml

@@ -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-log-deepseek/README.md
-README.md: 6322e4e792e2186aee40236e861b15ea8a6225f5
-README.zh.md: 9a0f42975135e5c6726f3258b6234e09618c6d71
+README.md: 27396f96191e0f88268558a1426b28e0b7dc6f12
+README.zh.md: a2840223f043283b0f7f0176108d23a5c94213ef

+ 0 - 3
packages/session/session-log-deepseek/README.md

@@ -31,8 +31,6 @@ Incremental canonical session-log upload for official DeepSeek LLM API requests.
 
 Shipped profiles mount the plugin, so the default configuration registers the request field and appends the acceptance watermark; an overlay opts out with `enabled: false`.
 
-Recorded-Session lanes (`test`, `test:snapshot`, `test:web`, and the ACP, SDK, and Web snapshot suites) replace that default with `false`, because their committed fixtures are both replay input and expected output for the persisted log. Such a process is identified by `$VITEST` or `$DSH_SNAPSHOT`; an explicit `enabled: true` still enables upload there. A deployed process sets neither variable.
-
 <a id="request-field"></a>
 ## Request field
 
@@ -72,7 +70,6 @@ None; the model-visible request prefix remains unchanged.
 - **No live Session means no field** — direct or stale-session calls have no canonical log to snapshot; explicit absence semantics remain deferred.
 - **No independent request-size cap** — complete delivery is fail-closed; provider rejection leaves the cursor unchanged instead of truncating the log.
 
-
 <a id="dev-note"></a>
 ### Dev Note
 

+ 0 - 3
packages/session/session-log-deepseek/README.zh.md

@@ -31,8 +31,6 @@ kind: "package-reference"
 
 随附 profile 会挂载该插件,因此默认配置会注册请求字段并追加接受水位;overlay 可用 `enabled: false` 选择退出。
 
-录制会话通道(`test`、`test:snapshot`、`test:web`,以及 ACP、SDK 与 Web 快照套件)会把该默认值改为 `false`,因为它们的已提交 fixture 既是回放输入也是持久日志的期望输出。此类进程由 `$VITEST` 或 `$DSH_SNAPSHOT` 标识;显式设置 `enabled: true` 仍可在其中启用上传。已部署进程不会设置这两个变量。
-
 <a id="request-field"></a>
 ## 请求字段
 
@@ -72,7 +70,6 @@ DeepSeek 适配器会在 HTTP 2xx 后、消费 SSE(Server-Sent Events)正文
 - **缺少存活会话就没有字段**——直接调用或陈旧会话调用没有可供快照的规范日志;显式缺失语义仍暂缓处理。
 - **没有独立请求大小上限**——完整交付采用 fail-closed 策略;提供方拒绝会保持游标不变,而非截断日志。
 
-
 <a id="dev-note"></a>
 ### 开发备注
 

+ 1 - 14
packages/session/session-log-deepseek/src/index.ts

@@ -34,19 +34,6 @@ export const name = 'session-log-deepseek'
 /** Services required to resolve sessions and contribute the provider request field. */
 export const inject = ['deepseekLlmApiExtensions', 'sessions']
 
-/** Environment markers that identify a recorded-Session lane. */
-const RECORDED_SESSION_LANE_MARKERS = ['VITEST', 'DSH_SNAPSHOT'] as const
-
-/**
- * Recorded-Session lanes (`test`, `test:snapshot`, `test:web`, and the ACP, SDK,
- * and Web snapshot suites) boot shipped profiles and compare persisted request
- * fields and Session logs against recorded expectations, so they keep this
- * contribution off unless a composition sets `enabled: true`. A deployed
- * process sets neither marker and contributes the field by default.
- */
-const RECORDED_SESSION_LANE = RECORDED_SESSION_LANE_MARKERS
-  .some(marker => process.env[marker] !== undefined)
-
 /** Session-log request contribution configuration. */
 export interface Config {
   /** Contribute `dsh_session_log` to official DeepSeek requests. Defaults to `true`. */
@@ -55,7 +42,7 @@ export interface Config {
 
 /** Validated Session-log request contribution configuration. */
 export const Config: z<Config> = z.object({
-  enabled: z.boolean().default(!RECORDED_SESSION_LANE),
+  enabled: z.boolean().default(true),
 })
 
 interface AcceptanceFold {

+ 6 - 6
packages/session/session-log-deepseek/tests/config.spec.ts

@@ -8,16 +8,16 @@ afterEach(() => {
 describe('session-log upload configuration', () => {
   it.each([
     { lane: 'ordinary process', vitest: undefined, snapshot: undefined, enabled: true },
-    { lane: 'Vitest', vitest: 'true', snapshot: undefined, enabled: false },
-    { lane: 'snapshot process', vitest: undefined, snapshot: '1', enabled: false },
-    { lane: 'Vitest snapshot', vitest: 'true', snapshot: '1', enabled: false },
-    { lane: 'empty Vitest marker', vitest: '', snapshot: undefined, enabled: false },
-    { lane: 'empty snapshot marker', vitest: undefined, snapshot: '', enabled: false },
+    { lane: 'Vitest', vitest: 'true', snapshot: undefined, enabled: true },
+    { lane: 'snapshot process', vitest: undefined, snapshot: '1', enabled: true },
+    { lane: 'Vitest snapshot', vitest: 'true', snapshot: '1', enabled: true },
+    { lane: 'empty Vitest marker', vitest: '', snapshot: undefined, enabled: true },
+    { lane: 'empty snapshot marker', vitest: undefined, snapshot: '', enabled: true },
   ])('defaults upload for $lane and honors explicit overrides', async ({ vitest, snapshot, enabled }) => {
     vi.stubEnv('VITEST', vitest)
     vi.stubEnv('DSH_SNAPSHOT', snapshot)
     try {
-      // The schema captures the process environment when its module loads.
+      // Import under each environment to catch environment-dependent schema defaults.
       vi.resetModules()
       const { Config } = await import('../src/index.ts')
       expect(Config({}).enabled).toBe(enabled)

+ 3 - 3
packages/session/session-log-deepseek/tests/upload.spec.ts

@@ -146,13 +146,13 @@ describe('incremental DeepSeek session-log upload', () => {
     }
   })
 
-  it('does not contribute the session log under its default configuration', async () => {
+  it('does not contribute the session log when explicitly disabled', async () => {
     const ctx = new Context()
     contexts.push(ctx)
     await ctx.plugin(SessionStore)
     await ctx.plugin(DeepSeekLlmApiExtensionRegistry)
-    await ctx.plugin(SessionLogDeepSeek)
-    const session = ctx.sessions.create(SessionId('default-off'))
+    await ctx.plugin(SessionLogDeepSeek, { enabled: false })
+    const session = ctx.sessions.create(SessionId('explicit-off'))
     session.append('turn/start', { turn: 1 })
 
     const prepared = await ctx.deepseekLlmApiExtensions.prepare({

+ 4 - 0
snapshots/acp/escalation-approved/cordis.yml

@@ -88,3 +88,7 @@
       name: '@deepseek-ai/dsh-hooks-codex'
       config:
         configPath: ./codex-hooks.json
+
+- id: session-log-deepseek
+  config:
+    enabled: false

+ 0 - 5
snapshots/sdk/text-turn/cordis.snapshot.yml

@@ -13,8 +13,3 @@
             name: DeepSeek
             models:
               - id: deepseek-v4-flash
-
-- id: session-log-deepseek
-  name: '@deepseek-ai/dsh-session-log-deepseek'
-  config:
-    enabled: true

+ 0 - 5
snapshots/sdk/text-turn/cordis.yml

@@ -28,11 +28,6 @@
     enableRunInBackground: false
     maxDepth: 1
 
-- id: session-log-deepseek
-  name: '@deepseek-ai/dsh-session-log-deepseek'
-  config:
-    enabled: true
-
 - insert:
     - id: snapshot-message-feedback
       name: '@deepseek-ai/dsh-message-feedback'

+ 4 - 0
snapshots/session/text-turn/cordis.yml

@@ -78,3 +78,7 @@
       name: '@deepseek-ai/dsh-hooks-codex'
       config:
         configPath: ./codex-hooks.json
+
+- id: session-log-deepseek
+  config:
+    enabled: false