diff --git a/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.i18n.yaml b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.i18n.yaml new file mode 100644 index 0000000000..be42dfe317 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.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/process/2026-09-19-evidence-led-simplification-surveys.md +2026-09-19-evidence-led-simplification-surveys.md: c217f80239690ee2f7310ca8e97956ec06fb75c7 +2026-09-19-evidence-led-simplification-surveys.zh.md: 1b1a11731967c87ab54aa9eba82253f90bb2abde diff --git a/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.md b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.md new file mode 100644 index 0000000000..c217f80239 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.md @@ -0,0 +1,66 @@ +# Agent Note: Evidence-led simplification surveys + +Status: implemented + +English | [中文](2026-09-19-evidence-led-simplification-surveys.zh.md) + +## Problem + +Unused-symbol searches can miss working behavior whose implementation costs more than its required outcome, and can misclassify public extension APIs without fixed repository callers as dead. The previous simplification skill also combined discovery with lengthy archive procedures, omitted application and Python paths from its consumer examples, and suggested a proposal outline without the mandatory `Alternatives considered` section. + +## Decision + +The [simplification skill](../../../skills/dsh-find-simplifications/SKILL.md) traces a complete producer-to-outcome path, asks which distinctions change consumer actions, considers explicit reductions in supported behavior, and searches for maintained copies that an authoritative read can replace. It separates composition availability from deployment policy and counts removed configuration, lifecycle, tests, and documentation together with source code. + +Production use changes the required trade-off evidence; it does not automatically veto a proposal or authorize implementation. Dynamic plugin discovery, installed consumers, generated runtime assets, profiles, applications, and Python participate in consumer tracing. Protected adapters and persistence designs, released data, trust boundaries, independent invariant observations, synchronous publication, cancellation, and quiescent disposal remain constraints. + +The entry point separates decision criteria from an [optional historical reference](../../../skills/dsh-find-simplifications/references/historical-patterns.md) pairing mechanisms with counterexamples and residual obligations. Archive mechanics remain at their existing owner, and the proposal skeleton uses the canonical headings. + +## Historical evidence + +The author sampled 26 of the 100 English implemented or archived simplification notes: 11 implemented and 15 archived. All nine rejected simplification notes supplied counterexamples. The sample covers producerless variants, inert request knobs, explicit inputs, public projections, derived data, shared composition, lifecycle ownership, and dependency replacements; it is purposeful, not random or exhaustive. + +The frozen comparison inputs contained 2,222 whitespace-delimited words in the baseline entry, 1,372 in the revised entry, and 897 in its reference; the hashes below identify those measured artifacts. The reference teaches questions rather than current deletion instructions. An adapter-rejected knob differs from a working extension API; a simpler public status can retain internal residency distinctions; reading at feedback time changes the observation promise; replacing a dependency can lose deterministic clocks or necessary teardown. Archived records were read without following or repairing outbound links. No old note was edited, archived, or deleted. + +## Bounded survey evidence + +The source snapshot is master after #4618. Each arm uses fresh agents with the same inherited model and reasoning effort, identical owner domains, a time cap, and at most four submissions per domain. Other outputs remain hidden from discovery agents. The runtime domain covers `core`, `session`, `session-query`, `api`, `sdk`, and Python; execution covers `shell`, `subprocess`, `terminal`, `jobs`, `fs`, `mcp`, and `boot`. + +A third matched domain, covering `llm`, `compaction`, `context`, `skill`, and `extensions`, was added after the initial runtime results to broaden coverage. It is exploratory, uses a shorter equal cap, and remains separate from the initially declared two-domain comparison. The study stops after these three domains. + +The skill author derived the revision from historical notes while isolated from current candidates. The coordinator received accidental early baseline hints, but accepted the independent author's revision unchanged before revised runs. Candidate packets hid arm labels from a separate reviewer; the coordinator's integration was not blind. The frozen inputs had SHA-256 values `9830af2272a1a1c3832078f31a432c8abe0335a013bc6c248c072b388520e798` for the baseline entry, `3b101d16ae098855c9214ad7fed631a2f079b6078c83b49829ae87305f631a87` for the revised entry, and `9a6b674d1eeadb691481ea09838b211b8e94c94e5a8cd928726246b1c097b2b5` for its reference. + +After these runs, review replaced only the skill phrase “earns its place” with “is justified”; no discovery criterion changed and no new discovery run was performed. Each prompt requested exact source/search evidence, producer and consumer classification, note overlap, net reduction, the strongest counterargument, and acceptance requirements. Review applied those same criteria to every submission, distinguished local edits from durable decisions, and did not treat either public discoverability or a line-deletion count as a verdict by itself. + +| Version | Domain | Cap | Submitted | Durable as submitted | Durable after refinement | Local | Deferred | Elapsed | +|---|---|---|---:|---:|---:|---:|---:|---| +| Baseline | Runtime | 12m | 3 | 1 | 2 | 0 | 0 | 6m 30s | +| Baseline | Execution | 12m | 3 | 3 | 0 | 0 | 0 | 8m 40s | +| Revised | Runtime | 12m | 2 | 1 | 0 | 1 | 0 | 5m 05s | +| Revised | Execution | 12m | 3 | 2 | 0 | 1 | 0 | 8m 19s | +| Baseline | Model/context, exploratory | 10m | 2 | 2 | 0 | 0 | 0 | 6m 02s | +| Revised | Model/context, exploratory | 10m | 2 | 0 | 0 | 1 | 1 | 7m 51s | + +The baseline yields six durable proposals as submitted and two after refinement. The revised skill yields three durable proposals and three local cleanups, with one proposed behavior reduction deferred. Python RPC narrowing and filesystem-invariant omission overlap. The combined set contains nine distinct durable proposals; the revised version adds [configuration-only HMR](../../proposed/simplification/2026-09-19-config-only-hmr.md). This sample does not show higher durable-proposal yield from the revision. + +Review narrowed the [query API proposal](../../proposed/simplification/2026-09-19-trim-session-query-convenience-api.md) to retain `filterEvents`, whose literal substring behavior differs from FTS. The [prompt-event proposal](../../proposed/simplification/2026-09-19-retire-prompt-registry-change-event.md) explicitly retires an active extension promise instead of claiming per-step assembly makes notifications redundant. Both refined baseline findings remain useful and are retained. + +The three revised-only local findings were a mirrored provider reference, copied filesystem results, and duplicate assembler ordering state. They were counted separately and were not written as active design proposals. + +Review deferred replacing automatic Session-reference sizing with a fixed byte default. The [current budget decision](../bug-fix/2026-09-05-session-reference-model-budget.md) fixes lost useful context on large models; best-effort spill retrieval does not replace inline context. No new workload evidence justified restoring the problematic default. The proposal's deletion inventory was accurate, but that alone did not overcome the current requirement. + +## Alternatives considered + +**Keep caller counts as the main filter.** This misses producer support, dynamic consumers, and useful explicit behavior reductions. More symbol matches do not establish which obligations can disappear. + +**Encode historical successes as a deletion checklist.** Architecture and consumers change. The reference uses mechanisms and counterexamples without making frozen records current authority. + +**Select the revision by proposal count.** The observed count does not support superiority. Its demonstrated benefit is complementary discovery and explicit classification; the stronger union includes findings from both versions. + +## Consequences + +The skill changes survey guidance, not runtime behavior. The nine proposals still require scoped implementation and relevant tests; their future implementation checks were not run. Three local opportunities remain evaluation findings, and the unsupported budget reversal is excluded from the proposal set. + +There is one discovery run per version/domain, no randomized order or repetition, unequal actual elapsed time within equal caps, and subjective review. Source reductions are estimates, not implemented diffs. These results establish neither statistical superiority, reproducible speedup, nor exhaustive coverage. + +The [dependency](2026-07-26-dependencies-over-hand-rolling.md), [prose](2026-08-09-concrete-prose-names-actors-and-recorded-facts.md), [archive](2026-07-26-frozen-agent-note-archive.md), and [performance-workflow](2026-09-06-evidence-driven-performance-skill.md) decisions retain their independent responsibilities. This note adds simplification-specific discovery and evaluation criteria without superseding those owners. diff --git a/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.zh.md b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.zh.md new file mode 100644 index 0000000000..1b1a117319 --- /dev/null +++ b/.agents/notes/implemented/process/2026-09-19-evidence-led-simplification-surveys.zh.md @@ -0,0 +1,66 @@ +# Agent Note: 以证据指导简化调研 + +Status: implemented + +[English](2026-09-19-evidence-led-simplification-surveys.md) | 中文 + +## 问题 + +仅搜索未使用的符号,可能漏掉实现成本超出必要结果的有效行为,也可能将没有固定仓库调用方的公共扩展 API 误判为死代码。原简化 skill(技能)还将发现候选与冗长的归档流程混在一起,消费方示例遗漏应用与 Python 路径,建议的提案结构也缺少必需的 `Alternatives considered` 章节。 + +## 决策 + +[简化 skill](../../../skills/dsh-find-simplifications/SKILL.md) 追踪从生产方到结果的完整路径,判断哪些区分会改变消费方动作,考虑明确收缩受支持行为,并寻找可以用权威读取替代的持续维护副本。它区分组合可用性与部署策略,并在源码之外合计删除的配置、生命周期、测试和文档成本。 + +生产使用会改变所需的取舍证据,但不会自动否决提案,也不构成实施授权。动态插件发现、已安装消费方、生成的运行时产物、profile、应用和 Python 都纳入消费方追踪。受保护的适配器与持久化设计、已发布数据、信任边界、独立 invariant 观察、同步发布、取消及达到静止状态的释放仍是约束。 + +入口将判断标准与[可选历史参考页](../../../skills/dsh-find-simplifications/references/historical-patterns.md) 分开,后者将机制与反例、残留义务配对。归档操作仍由原有归属处负责,提案结构使用规范标题。 + +## 历史证据 + +作者从 100 份英文已实现或归档简化记录中抽样 26 份:11 份已实现、15 份归档。全部九份已否决简化记录提供反例。样本涵盖无生产方变体、无效请求开关、显式输入、公共投影、派生数据、共享组合、生命周期所有权和依赖替换;这是有目的的抽样,并非随机或穷尽审查。 + +冻结的比较输入按空白分隔计数:基线入口为 2,222 词,新版入口为 1,372 词,参考页为 897 词;下方哈希标识这些已测量产物。参考页提供问题,而非当前删除指令。所有适配器都拒绝的开关不同于有效扩展 API;更简单的公共状态可以保留内部驻留差别;反馈时读取会改变观察承诺;依赖替换可能丢失确定性时钟或必要的释放行为。阅读归档记录时未追踪或修复其出站链接。没有编辑、归档或删除任何旧记录。 + +## 有界调研证据 + +源码快照固定为 #4618 之后的 master。每组使用继承相同模型和推理强度的全新 agent(智能体),获得相同归属领域、时间上限及每域最多四个提交项。发现候选的 agent 不能读取其他输出。运行时域覆盖 `core`、`session`、`session-query`、`api`、`sdk` 和 Python;执行域覆盖 `shell`、`subprocess`、`terminal`、`jobs`、`fs`、`mcp` 和 `boot`。 + +初始运行时结果产生后,增加第三个配对领域,覆盖 `llm`、`compaction`、`context`、`skill` 和 `extensions`,以扩大覆盖。该领域属于探索性补充,采用较短但双方相同的时间上限,与最初声明的两域比较分开。调研在这三个领域后结束。 + +skill 作者与当前候选隔离,根据历史记录撰写修订。协调者意外提前收到少量基线提示,但在新版运行前原样接受独立作者的修订。交给独立审查方的候选材料隐藏了分组标签;协调者整合并非盲审。冻结输入的 SHA-256 为:基线入口 `9830af2272a1a1c3832078f31a432c8abe0335a013bc6c248c072b388520e798`,新版入口 `3b101d16ae098855c9214ad7fed631a2f079b6078c83b49829ae87305f631a87`,新版参考页 `9a6b674d1eeadb691481ea09838b211b8e94c94e5a8cd928726246b1c097b2b5`。 + +这些运行结束后,评审仅将 skill 中的「earns its place」改为「is justified」;没有改变发现标准,也没有重新运行发现测试。每份提示都要求精确源码/搜索证据、生产方与消费方分类、记录重叠、净减少量、最强反对理由和验收要求。审查对每个提交项使用相同标准,区分局部编辑与长期决策,既不单凭公共可发现性,也不单凭删除行数作结论。 + +| 版本 | 领域 | 上限 | 提交数 | 原样可用的长期提案 | 调整后可用的长期提案 | 局部项 | 暂缓 | 耗时 | +|---|---|---|---:|---:|---:|---:|---:|---| +| 基线 | 运行时 | 12m | 3 | 1 | 2 | 0 | 0 | 6m 30s | +| 基线 | 执行 | 12m | 3 | 3 | 0 | 0 | 0 | 8m 40s | +| 新版 | 运行时 | 12m | 2 | 1 | 0 | 1 | 0 | 5m 05s | +| 新版 | 执行 | 12m | 3 | 2 | 0 | 1 | 0 | 8m 19s | +| 基线 | 模型/上下文,探索性 | 10m | 2 | 2 | 0 | 0 | 0 | 6m 02s | +| 新版 | 模型/上下文,探索性 | 10m | 2 | 0 | 0 | 1 | 1 | 7m 51s | + +基线产生六个原样可用的长期提案,另有两个调整后可用。新版 skill 产生三个长期提案和三个局部清理项,一项行为收缩被暂缓。Python RPC 收缩和文件系统 invariant 省略相互重叠。合并集合包含九个互不重复的长期提案;新版增加了[仅保留配置更新的 HMR](../../proposed/simplification/2026-09-19-config-only-hmr.zh.md)。该样本未显示新版的长期提案产出更高。 + +审查缩小了[查询 API 提案](../../proposed/simplification/2026-09-19-trim-session-query-convenience-api.zh.md),保留其字面子串语义不同于 FTS 的 `filterEvents`。[提示事件提案](../../proposed/simplification/2026-09-19-retire-prompt-registry-change-event.zh.md) 明确撤回当前扩展承诺,而非声称逐步骤组装让通知多余。这两项经调整的基线发现仍有价值,因此保留。 + +三个仅新版发现的局部项分别是镜像的提供方引用、复制的文件系统结果,以及重复的组装器顺序状态。它们单独计数,没有写成当前设计提案。 + +审查暂缓了将自动 Session 引用大小改为固定字节默认值的提案。[当前预算决策](../bug-fix/2026-09-05-session-reference-model-budget.zh.md) 修复了大模型丢失有用上下文的问题;尽力而为的 spill 检索不能替代内联上下文。没有新的工作负载证据支持恢复有问题的默认值。提案的删除清单准确,但仅此不足以推翻当前要求。 + +## 考虑过的替代方案 + +**继续以调用数量为主要筛选依据。** 这会遗漏生产方支持、动态消费方及有价值的明确行为收缩。更多符号匹配不能证明哪些义务可以删除。 + +**将历史成功案例编码为删除清单。** 架构与消费方会变化。参考页使用机制与反例,不将冻结记录视为当前权威。 + +**按提案数量选择修订。** 观察到的数量不支持优越性结论。已展示的收益是互补发现和明确分类;更有价值的合并集合包含两个版本的发现。 + +## 后果 + +skill 改变调研指导,不改变运行时行为。九份提案仍需限定范围的实现与相关测试;本次未运行其未来实施检查。三个局部机会保留为评估发现,缺少依据的预算逆转排除在提案集合之外。 + +每个版本/领域只有一次发现运行,没有随机顺序或重复试验,相同上限内的实际耗时不等,审查带有判断性。源码减少量是估算,并非实现 diff。这些结果不能证明统计优越性、可复现的提速或穷尽覆盖。 + +[依赖](2026-07-26-dependencies-over-hand-rolling.zh.md)、[措辞](2026-08-09-concrete-prose-names-actors-and-recorded-facts.zh.md)、[归档](2026-07-26-frozen-agent-note-archive.zh.md)和[性能工作流](2026-09-06-evidence-driven-performance-skill.zh.md)决策保留各自独立职责。本记录增加简化专用的发现与评估标准,不取代这些归属处。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.i18n.yaml new file mode 100644 index 0000000000..c959db81ed --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.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/proposed/simplification/2026-09-19-config-only-hmr.md +2026-09-19-config-only-hmr.md: a5f447a8a426e9f2831a1292cae1132acab99023 +2026-09-19-config-only-hmr.zh.md: 24651aa310994b3fec4d925a84fe5d88ae6a5851 diff --git a/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.md b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.md new file mode 100644 index 0000000000..a5f447a8a4 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.md @@ -0,0 +1,36 @@ +# Agent Note: Limit DSH HMR to live profile configuration + +Status: proposed + +English | [中文](2026-09-19-config-only-hmr.zh.md) + +## Problem + +[DSH HMR](../../../../packages/boot/hmr/src/index.ts) owns both serialized profile configuration refresh and running JavaScript module replacement. Module replacement adds Node-loader internals, dependency traversal, cache backup, old/new plugin fibers, rollback, module watches, and import-error formatting. The [base composition](../../../../packages/bundle/base/cordis.patch.yml) uses `root: []`; other shipped profiles disable or omit HMR. The default product requires configuration refresh, while source replacement serves an explicit custom-profile opt-in. + +That opt-in is real supported behavior: [profile tests](../../../../apps/cli/tests/profile-hmr.spec.ts), module tests, and a [built CLI test](../../../../apps/cli/tests/built-bin.e2e.ts) exercise it, and generated inspection APIs advertise its methods and events. This proposal trades developer continuity for a smaller maintained subsystem; it does not classify the code as unreachable. + +## Proposal + +Keep `watchConfig`, `runExclusive`, exact profile/home patch and manifest watches, application-readiness coordination, serialized refresh, and disposal drainage. Require a process restart for source-module, arbitrary Include, and framework-dependency changes; remove automatic framework-change calls to `loader.exit()`. Keep browser Client loading independent. + +Remove the module watcher and dispatch, dependency graph analysis, module-cache/fiber replacement and restoration, module-only state/options, `baseDir`, `getOuterStack`, `getLinked`, and `hmr/change`/`hmr/reload`. Remove the [import-error formatter](../../../../packages/boot/hmr/src/error.ts), module-only dependencies, and dedicated module/error tests. Keep Chokidar and configuration watcher options actually used by [exact watches](../../../../packages/boot/hmr/src/watch-config.ts). Roughly 400 identified source lines and 372 dedicated test lines belong to the removable module paths; retained configuration code and mixed tests must be counted separately in implementation. + +Update the [profile-management decision](../../implemented/architecture/2026-09-14-current-profile-plugin-management.md) and [single-launcher decision](../../implemented/architecture/2026-08-22-single-dsh-application-launcher.md) only where they promise module replacement or its coordination. Their configuration, installation, and launcher responsibilities remain. The [non-transactional Loader decision](../../implemented/simplification/2026-09-09-nontransactional-loader.md) motivates avoiding duplicated rollback but does not already authorize withdrawing source HMR. + +## Alternatives considered + +**Keep opt-in source replacement.** Plugin authors can edit code without restarting an active Session, and failed replacements restore old plugins. That capability is useful; this proposal deliberately gives it up to remove loader-version coupling and replacement-state ownership from DSH. + +**Remove only rollback or delegate replacement elsewhere.** Partial removal can leave cached modules and live fibers from different generations. A wrapper around another HMR implementation retains the public behavior and coordination burden. Neither establishes the complete deletion proposed here. + +## Acceptance criteria + +- Live profile/home patch and bundle-list changes, Plugin Manager serialization, readiness, self-removal, disposal drainage, and recovery after a later valid edit retain coverage. +- Source and arbitrary Include changes take effect on restart. Removed source options receive an explicit migration/configuration error; update shipped `root: []` rows rather than silently ignoring obsolete options. +- Remove module-only APIs, events, dependencies, generated declarations, and tests. Preserve the remaining public queue/watch APIs and package installation/restart semantics. +- Run focused HMR configuration/watch/coordination and Plugin Manager tests, app-boot reload coverage, and a real built CLI profile-refresh scenario. Replace source-replacement expectations with the agreed restart behavior and update required assembled snapshots and documentation. + +## Risks + +Custom profiles and installed plugins lose live server-code replacement and its failure restoration. Restarting can interrupt long-lived development work; acceptance therefore requires agreement to this product trade-off. Removing shared configuration coordination or recreating source replacement in another package would defeat the proposal. diff --git a/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.zh.md b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.zh.md new file mode 100644 index 0000000000..24651aa310 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-config-only-hmr.zh.md @@ -0,0 +1,36 @@ +# Agent Note: 将 DSH HMR 限定为实时 profile 配置更新 + +Status: proposed + +[English](2026-09-19-config-only-hmr.md) | 中文 + +## 问题 + +[DSH HMR](../../../../packages/boot/hmr/src/index.ts) 同时拥有串行 profile 配置刷新和运行中的 JavaScript 模块替换。模块替换增加了 Node loader 内部接口、依赖遍历、缓存备份、新旧插件 fiber、回滚、模块监听与导入错误格式化。[基础组合](../../../../packages/bundle/base/cordis.patch.yml) 使用 `root: []`;其他随产品发布的 profile 禁用或省略 HMR(热模块替换)。默认产品需要配置刷新,而源码替换服务于自定义 profile 的显式启用。 + +该选项是真实受支持的行为:[profile 测试](../../../../apps/cli/tests/profile-hmr.spec.ts)、模块测试和[构建后 CLI 测试](../../../../apps/cli/tests/built-bin.e2e.ts) 都覆盖它,生成的检查 API 也展示其方法和事件。本提案以开发连续性换取更小的维护子系统,并不将代码判定为不可达。 + +## 提案 + +保留 `watchConfig`、`runExclusive`、精确的 profile/home 补丁与 manifest(元数据清单)监听、应用就绪协调、串行刷新和释放排空。源码模块、任意 Include 和框架依赖的修改要求重启进程;删除框架变化时对 `loader.exit()` 的自动调用。浏览器 Client 加载保持独立。 + +删除模块监听与分发、依赖图分析、模块缓存/fiber 替换与恢复、仅供模块使用的状态/选项、`baseDir`、`getOuterStack`、`getLinked` 及 `hmr/change`/`hmr/reload`。删除[导入错误格式化器](../../../../packages/boot/hmr/src/error.ts)、仅供模块使用的依赖和模块/错误专用测试。保留 Chokidar 及[精确监听](../../../../packages/boot/hmr/src/watch-config.ts) 实际使用的配置监听选项。已定位约 400 行源码和 372 行专用测试属于可删除模块路径;实现时必须单独计算保留的配置代码和混合测试。 + +仅修改[profile 管理决策](../../implemented/architecture/2026-09-14-current-profile-plugin-management.zh.md) 与[单一启动器决策](../../implemented/architecture/2026-08-22-single-dsh-application-launcher.zh.md) 中承诺模块替换及其协调的部分。其配置、安装与启动器职责保留。[非事务式 Loader 决策](../../implemented/simplification/2026-09-09-nontransactional-loader.zh.md) 为避免重复回滚提供理由,但尚未授权撤回源码 HMR。 + +## 考虑过的替代方案 + +**保留可选源码替换。** 插件作者可以在不重启活动 Session 的情况下编辑代码,失败替换会恢复旧插件。这项能力有价值;本提案有意放弃它,以移除 DSH 对 loader 版本的耦合及替换状态所有权。 + +**仅删除回滚或将替换委托到别处。** 部分删除可能让缓存模块和活动 fiber 属于不同代。包装另一个 HMR 实现仍保留公共行为及协调负担。这两种方式都不能实现此处提出的完整删除。 + +## 验收标准 + +- 实时 profile/home 补丁与组合包列表变化、Plugin Manager 串行化、就绪、自身移除、释放排空及后续有效编辑后的恢复仍有覆盖。 +- 源码和任意 Include 修改在重启后生效。删除的源码选项给出明确迁移/配置错误;更新随产品发布的 `root: []` 项,不静默忽略过时选项。 +- 删除仅供模块使用的 API、事件、依赖、生成声明与测试。保留剩余公共队列/监听 API,以及包安装/重启语义。 +- 运行聚焦的 HMR 配置/监听/协调及 Plugin Manager 测试、app-boot 重载覆盖与真实构建后 CLI(命令行界面)profile 刷新场景。将源码替换预期改为已同意的重启行为,并更新所需的组装快照与文档。 + +## 风险 + +自定义 profile 和已安装插件会失去实时服务端代码替换及其失败恢复。重启可能中断长时间开发工作,因此接受该提案需要同意此产品取舍。删除共享配置协调,或在另一个包重建源码替换,都会违背提案目的。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.i18n.yaml new file mode 100644 index 0000000000..e582498d41 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.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/proposed/simplification/2026-09-19-omit-fs-payload-invariant.md +2026-09-19-omit-fs-payload-invariant.md: e91fa1784aa99869e3d457f7fc25a330fbc43088 +2026-09-19-omit-fs-payload-invariant.zh.md: ba81baed5f7d7051ef22218d9d59180ac87c8a21 diff --git a/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.md b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.md new file mode 100644 index 0000000000..e91fa1784a --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.md @@ -0,0 +1,34 @@ +# Agent Note: Omit the filesystem payload-only invariant companion + +Status: proposed + +English | [中文](2026-09-19-omit-fs-payload-invariant.zh.md) + +## Problem + +The [filesystem invariant](../../../../packages/fs/fs/src/invariant.ts) checks non-empty target strings, a non-empty present version, and an observation discriminant. It reads one dispatch payload, retains no history, and compares no provider, policy, filesystem, or independently mutable state. Its [tests](../../../../packages/fs/fs/tests/invariant.spec.ts) construct malformed payloads directly. Publishing this check costs a companion module, export/build wiring, invariant dependencies, compiler references, and dedicated tests. + +Current guidance needs an explicit decision: the [independent-observation rule](../../implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.md) requires observations that can independently diverge, while the [runtime-contract examples](../../implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md) specifically endorse filesystem target/version validity. The later rule retains the earlier note's semantic authority, so chronology alone does not resolve this conflict. + +## Proposal + +Apply the independent-observation criterion to this concrete companion and remove it. The event producers are independent plugins, but checking the format of each single payload does not compare their observations. Keep typed filesystem events and the real [observation-policy consumer](../../../../packages/fs/fs-observation-policy/src/index.ts), along with parser, wire, read, edit, and write validation at their existing owners. + +Remove the 48-line companion, its 55-line dedicated test, `./invariant` export/publication, invariant-only dependencies and compiler references. Add the package-specific omission reason to both fs READMEs. Amend the earlier representative-check row when implementing this decision, retaining its other semantic examples and the shared invariant registration machinery. This proposal leaves those current owners unchanged until acceptance. + +## Alternatives considered + +**Keep payload validation as an explicit policy exception.** It can detect malformed third-party emissions early, but this would deliberately broaden the stated independent-observation criterion. The proposal prefers input validation at its owner and reserves companions for relational checks. + +**Add a second state source to justify the companion.** Rejected without a concrete missing invariant. Duplicating policy state or exposing new API solely to retain this diagnostic increases the maintenance burden. + +## Acceptance criteria + +- Resolve the named policy conflict in the active owning notes; do not claim this is already an uncontested mechanical omission. +- No companion source, test, export, artifact entry, invariant-only dependency, or compiler reference remains; package topology checks accept the explained omission. +- Real file-tool and observation-policy tests retain stale-version, absent-target, alias, actor-routing, and world-state assertions. The events and consumers remain. +- Run focused fs and observation-policy tests, relevant file-tool integration checks, source/built invariant-topology checks, build/hygiene, doc-sync, and lint. Do not replace the module with equivalent generic payload-validation machinery. + +## Risks + +Malformed trusted-plugin emissions lose this opt-in early diagnostic. The check's removal does not justify weakening validation of external data, nor removing other companions that compare lifecycle, durable history, or independently assembled values. If payload-format diagnostics are intentionally part of the companion policy, retain this module and clarify that exception instead. diff --git a/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.zh.md b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.zh.md new file mode 100644 index 0000000000..ba81baed5f --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-omit-fs-payload-invariant.zh.md @@ -0,0 +1,34 @@ +# Agent Note: 省略仅校验载荷的文件系统 invariant 配套模块 + +Status: proposed + +[English](2026-09-19-omit-fs-payload-invariant.md) | 中文 + +## 问题 + +[文件系统 invariant](../../../../packages/fs/fs/src/invariant.ts) 检查目标字符串非空、present 版本非空及观察值的判别标签。它只读取一次分发的载荷,不保留历史,也不与提供方、策略、文件系统或独立可变状态比较。其[测试](../../../../packages/fs/fs/tests/invariant.spec.ts) 直接构造格式错误的载荷。发布该检查需要配套模块、导出/构建配置、invariant 依赖、编译器引用和专用测试。 + +当前指导需要显式决策:[独立观察规则](../../implemented/simplification/2026-08-28-omit-unneeded-invariant-companions.zh.md) 要求能够独立分歧的观察值,而[运行时约定示例](../../implemented/architecture/2026-07-19-package-invariant-runtime-contracts.zh.md) 明确认可文件系统目标/版本有效性检查。后者的语义权威仍被较新的规则保留,因此不能仅凭时间先后解决冲突。 + +## 提案 + +将独立观察标准应用于这个具体配套模块,并删除它。事件生产方来自独立插件,但逐一检查单个载荷的格式,并没有比较它们的观察值。保留类型化文件系统事件和实际的[观察策略消费方](../../../../packages/fs/fs-observation-policy/src/index.ts),以及现有归属处的解析器、wire、读取、编辑和写入校验。 + +删除 48 行配套模块、55 行专用测试、`./invariant` 导出/发布项、仅供 invariant 使用的依赖和编译器引用。在 fs 的两个 README 中补充包特有的省略理由。实现本决策时修改较早的代表性检查行,保留其他语义示例及共享 invariant 注册机制。本提案获接受前不修改这些当前归属文档。 + +## 考虑过的替代方案 + +**将载荷校验保留为显式策略例外。** 它能提前发现第三方格式错误的事件,但这会有意扩大已声明的独立观察标准。提案倾向于在输入归属处校验,并将配套模块留给关系检查。 + +**添加第二个状态源以证明配套模块有必要。** 在没有具体缺失 invariant 的情况下否决。仅为保留此诊断而复制策略状态或暴露新 API,会增加维护负担。 + +## 验收标准 + +- 在当前归属 Agent Notes 中解决已指出的策略冲突;不将其宣称为已有共识的机械省略。 +- 不再保留配套源码、测试、导出、产物条目、仅供 invariant 使用的依赖或编译器引用;包拓扑检查接受有说明的省略。 +- 真实文件工具和观察策略测试保留过期版本、目标缺失、别名、执行方路由及外部状态断言。事件及其消费方保留。 +- 运行聚焦的 fs 与观察策略测试、相关文件工具集成检查、源码/构建产物 invariant 拓扑检查、build/hygiene、doc-sync(文档同步门禁)和 lint。不用等价的通用载荷校验机制替换该模块。 + +## 风险 + +来自受信任插件的格式错误事件会失去这项可选的早期诊断。删除该检查不构成削弱外部数据校验的理由,也不意味着可以删除比较生命周期、持久化历史或独立组装值的其他配套模块。如果载荷格式诊断本来就是配套模块策略的一部分,应保留模块并澄清该例外。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.i18n.yaml new file mode 100644 index 0000000000..46510688ef --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.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/proposed/simplification/2026-09-19-provider-only-instruction-reads.md +2026-09-19-provider-only-instruction-reads.md: 26d004c136cff8deb155007cf8d7743bc8bba95a +2026-09-19-provider-only-instruction-reads.zh.md: 82f3451f96578f1ee596bf9291a1a3c935d5f698 diff --git a/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.md b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.md new file mode 100644 index 0000000000..26d004c136 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.md @@ -0,0 +1,37 @@ +# Agent Note: Read instruction files only through a filesystem provider + +Status: proposed + +English | [中文](2026-09-19-provider-only-instruction-reads.zh.md) + +## Problem + +[Instruction discovery](../../../../packages/context/agent-instructions/src/files.ts) maintains provider and direct-Node paths for metadata probes, root-marker discovery, and bounded reads. `nodeStatFile`, `nodeTextChunks`, and optional provider/target fields support the latter. The exported `discoverBaselineInstructionFiles` wrapper selects it; `loadBaselineInstructions` permits it when callers omit a provider. + +Every repository production caller supplies a provider. The [plugin](../../../../packages/context/agent-instructions/src/index.ts) reads `ctx.get('fs')` and returns when absent; [reconciliation](../../../../packages/context/agent-instructions/src/state.ts) requires `FileSystem`. Direct-Node consumers are tests. Maintaining both paths therefore adds separate error and cancellation coverage without serving a shipped product path. + +## Proposal + +Require `FileSystem` throughout discovery and loading, including both exported wrappers and `findProjectRoot`. Remove `nodeStatFile`, `nodeTextChunks`, Node-only missing-path classification, the Node branch of `existsAsMarker`, and the `statFile` selector. Provider discovery supplies required targets; bounded reads consume those targets through `streamText`. + +Keep the plugin's missing-provider no-op and the pure `renderAgentInstructions` API. Preserve candidate precedence, source and rendered-output byte budgets, cancellation, symlink following, and error semantics: unavailable candidates cannot imply removal, while root-marker failures remain errors. The separate `skill-filesystem` owner retains its existing providerless behavior. + +Migrate direct helper tests to explicitly owned local or controlled providers. The [test suite](../../../../packages/context/agent-instructions/tests/agent-instructions.spec.ts) already mounts both. Preserve unique assertions and consolidate duplicate Node-mocking cases into provider coverage. Expected deletion is roughly 50–65 production lines before signature/documentation updates, plus redundant test machinery; measure the actual reduction during implementation. + +The [symlink decision](../../implemented/feature/2026-07-21-follow-instruction-symlinks.md) remains active because its accepted behavior survives. At implementation, update its references to the two implementations and the [package README](../../../../packages/context/agent-instructions/README.md), including bilingual counterparts. The [archived workspace-context note](../../archived/feature/2026-06-24-workspace-context.md) remains frozen; no existing note changes accompany this proposal. + +## Alternatives considered + +**Keep providerless convenience exports.** They let external callers load instructions without constructing a provider, but require a second I/O implementation that production bypasses. This proposal deliberately gives up that convenience; repository searches do not establish external non-use. + +**Construct a local provider implicitly.** This preserves the omitted argument while hiding filesystem selection and lifecycle ownership. Callers should supply the implementation they intend to use. + +## Acceptance criteria + +- This owner's discovery/read helpers require a provider and contain no direct-Node I/O fallback; providerless plugin composition still loads nothing. +- Focused tests preserve symlink, absence/unavailability, marker-error, budget, cancellation, resume, nested-touch, and compaction-restoration behavior. +- The workspace-context resume process expectation and `ptc-workspace-context` scenario retain their text and event order. Typecheck, affected builds, and documentation checks pass. + +## Risks + +External callers omitting the provider face an intentional pre-stable API change. Identify such requirements before implementation. Keep filesystem extension paths intact, and do not replace useful provider tests with a new convenience wrapper that recreates the removed fallback. diff --git a/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.zh.md b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.zh.md new file mode 100644 index 0000000000..82f3451f96 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-provider-only-instruction-reads.zh.md @@ -0,0 +1,37 @@ +# Agent Note: 仅通过文件系统提供方读取指令文件 + +Status: proposed + +[English](2026-09-19-provider-only-instruction-reads.md) | 中文 + +## 问题 + +[指令发现](../../../../packages/context/agent-instructions/src/files.ts)为元数据探测、根标记发现和有界读取维护了提供方与直接 Node 两条路径。`nodeStatFile`、`nodeTextChunks` 和可选的提供方/目标字段支持后者。导出的 `discoverBaselineInstructionFiles` 包装函数选择该路径;`loadBaselineInstructions` 则允许调用方通过省略提供方来使用它。 + +仓库中的每个生产调用方都传入提供方。[插件](../../../../packages/context/agent-instructions/src/index.ts)读取 `ctx.get('fs')`,缺失时直接返回;[协调逻辑](../../../../packages/context/agent-instructions/src/state.ts)要求传入 `FileSystem`。直接 Node 路径的消费方都是测试。因此,维护两条路径增加了独立的错误与取消覆盖,却没有服务于已交付的产品路径。 + +## 提案 + +在整个发现与加载链路中要求传入 `FileSystem`,包括两个导出的包装函数和 `findProjectRoot`。移除 `nodeStatFile`、`nodeTextChunks`、仅供 Node 使用的路径缺失分类、`existsAsMarker` 的 Node 分支以及 `statFile` 选择器。提供方发现过程给出必需的目标;有界读取通过 `streamText` 消费这些目标。 + +保留插件缺少提供方时不执行操作的行为,以及纯函数 `renderAgentInstructions` API。保留候选优先级、源文件与渲染输出的字节预算、取消、符号链接跟随和错误语义:候选不可用不能表示应移除已有内容,根标记失败仍是错误。独立的 `skill-filesystem` 所有者保留其现有的无提供方行为。 + +让直接调用辅助函数的测试改用显式管理生命周期的本地或受控提供方。[测试套件](../../../../packages/context/agent-instructions/tests/agent-instructions.spec.ts)已经挂载了这两类实现。保留独有断言,把重复的 Node mock 场景合并到提供方覆盖中。预计在更新签名和文档之前删除约 50–65 行生产源码,另加冗余测试机制;实施时测量实际减少量。 + +[符号链接决策](../../implemented/feature/2026-07-21-follow-instruction-symlinks.zh.md)所接受的行为继续存在,因此该说明保持现行状态。实施时,更新其中对两种实现的引用和[包 README](../../../../packages/context/agent-instructions/README.zh.md),包括双语对侧。[已归档的工作区上下文说明](../../archived/feature/2026-06-24-workspace-context.md)保持冻结;本提案不附带任何既有说明变更。 + +## 备选方案 + +**保留无提供方的便利导出。** 它们让外部调用方无需构造提供方便可加载指令,但也要求保留生产路径不使用的第二套 I/O 实现。本提案有意放弃这种便利;仓库搜索不能确定外部无人使用。 + +**隐式构造本地提供方。** 这会保留省略参数的调用方式,却隐藏文件系统选择和生命周期归属。调用方应传入它们打算使用的实现。 + +## 验收标准 + +- 本所有者的发现/读取辅助函数要求提供方,且不含直接 Node I/O 回退;无提供方的插件组合仍不加载任何内容。 +- 针对性测试保留符号链接、缺失/不可用、标记错误、预算、取消、恢复、嵌套访问和压缩(compaction)后恢复的行为。 +- 工作区上下文恢复的进程预期输出和 `ptc-workspace-context` 场景保持原有文本及事件顺序。类型检查、受影响构建和文档检查通过。 + +## 风险 + +省略提供方的外部调用方面临有意的稳定前 API 变更。实施前确认这类需求。保留文件系统扩展路径,也不要用重新创建已移除回退的新便利包装函数替换有用的提供方测试。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.i18n.yaml new file mode 100644 index 0000000000..6360d57daa --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.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/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.md +2026-09-19-prune-stream-visibility-helpers.md: e44716fe15eb0ff09020ff4417b1dd9f4e9c29f4 +2026-09-19-prune-stream-visibility-helpers.zh.md: 60d010f260a6cadc99a15bde164bb0717dd7502a diff --git a/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.md b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.md new file mode 100644 index 0000000000..e44716fe15 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.md @@ -0,0 +1,35 @@ +# Agent Note: Prune unused stream visibility helpers + +Status: proposed + +English | [中文](2026-09-19-prune-stream-visibility-helpers.zh.md) + +## Problem + +The [compact Assistant stream implementation](../../../../packages/llm/llm/src/assistant-stream.ts) exports five visibility queries: `isVisibleChunk`, `chunkHasVisibleText`, `runFirstVisibleTime`, `assistantStreamHasVisibleContent`, and `assistantStreamHasVisibleText`. Repository searches find no production caller outside that family. Its other consumers are the [unit tests](../../../../packages/llm/llm/tests/assistant-stream.spec.ts), package documentation, and the [record-reader decision](../../implemented/architecture/2026-09-06-embedded-stream-record-readers.md). The package root and published `./assistant-stream` entry expose the functions to external callers, whose usage this search cannot establish. + +The retained first-token reader has current consumers in [Session Stats](../../../../packages/session/session-stats/src/projection.ts) and [Trajectory](../../../../packages/client/ui-trajectory/src/client/trajectory-assistant-definition.ts). Their timing requirements do not require the separate whitespace-sensitive visibility classification. + +## Proposal + +Remove the five exported visibility queries and their exclusive private helpers, `hasNonWhitespace` and `blockIsVisible`. This deletes approximately 77 source lines, including local documentation, without adding replacement machinery. Retain all first-token, raw-chunk, text-joining, and assembly readers, the accumulator, and validating expansion. Preserve the direct and library-backed LLM adapters and their extension APIs. + +Remove dedicated visibility tests and only the obsolete assertions inside mixed reader tests. Keep the mixed fixtures and assertions that verify first-token timing, early exit, raw chunks, text joining, and assembly equivalence. + +The record-reader decision is only partially superseded: its allocation rationale and used readers remain current. When implementing this proposal, update that active note, the [package README](../../../../packages/llm/llm/README.md), and the [LLM subsystem page](../../../../docs/subsystems/llm-streaming.md) with their bilingual counterparts. Do not delete the owning note or alter archived records while adding this proposal. + +## Alternatives considered + +**Keep a complete reader family for external consumers.** This preserves convenient, tested visibility queries, but keeps public functions and dedicated tests without a demonstrated repository consumer. A named external requirement would justify retaining or reintroducing them. + +**Replace visibility queries with stream expansion.** There is no production caller to migrate. Adding replacements would retain an unused API and introduce the allocations the record readers avoid. + +## Acceptance criteria + +- The five names disappear from source exports and current API documentation; no production caller gains an expansion or replacement visibility query. +- Focused stream-reader, Session Stats, and Trajectory timing checks pass; mixed tests retain their unrelated assertions. +- Typecheck, affected published-entry builds, and documentation checks pass. Session formats, model input, transcript content, and first-token timing remain unchanged. + +## Risks + +This deliberately contracts exported pre-stable APIs. An external import may break even though repository consumers are absent. Refresh consumer evidence before implementation and assess any identified external requirement explicitly; do not claim ecosystem-wide non-use. diff --git a/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.zh.md b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.zh.md new file mode 100644 index 0000000000..60d010f260 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-prune-stream-visibility-helpers.zh.md @@ -0,0 +1,35 @@ +# Agent Note: 精简未使用的流可见性辅助函数 + +Status: proposed + +[English](2026-09-19-prune-stream-visibility-helpers.md) | 中文 + +## 问题 + +[紧凑 Assistant 流实现](../../../../packages/llm/llm/src/assistant-stream.ts)导出五个可见性查询:`isVisibleChunk`、`chunkHasVisibleText`、`runFirstVisibleTime`、`assistantStreamHasVisibleContent` 和 `assistantStreamHasVisibleText`。仓库搜索未找到这组函数之外的生产调用方。其余消费方是[单元测试](../../../../packages/llm/llm/tests/assistant-stream.spec.ts)、包文档和[记录读取器决策](../../implemented/architecture/2026-09-06-embedded-stream-record-readers.zh.md)。包根入口和发布的 `./assistant-stream` 入口向外部调用方暴露这些函数;本次搜索无法确定外部使用情况。 + +保留的首 token 读取器已有 [Session Stats](../../../../packages/session/session-stats/src/projection.ts) 和 [Trajectory](../../../../packages/client/ui-trajectory/src/client/trajectory-assistant-definition.ts) 消费方。它们的计时要求不依赖单独区分空白文本的可见性分类。 + +## 提案 + +移除这五个导出的可见性查询及其专用私有辅助函数 `hasNonWhitespace` 和 `blockIsVisible`。这会删除约 77 行源码(含局部文档),无需新增替代机制。保留所有首 token、原始分片、文本拼接和组装读取器,以及累加器和带校验的展开操作。保留直接实现和基于库实现的两个 LLM(大语言模型)适配器及其扩展 API。 + +移除专门的可见性测试;混合读取器测试只删除过时断言。保留验证首 token 计时、提前退出、原始分片、文本拼接和组装等价性的混合 fixture(测试前置数据)与断言。 + +记录读取器决策只被部分替代:其分配开销方面的理由和仍被使用的读取器继续有效。实施本提案时,更新该现行说明、[包 README](../../../../packages/llm/llm/README.zh.md) 和 [LLM 子系统页面](../../../../docs/subsystems/llm-streaming.zh.md)及其双语对侧。添加本提案时不删除所属说明,也不修改归档记录。 + +## 备选方案 + +**为外部消费方保留完整的读取器组。** 这能保留方便且经过测试的可见性查询,但也会在缺少已确认仓库消费方的情况下保留公共函数和专门测试。明确的外部需求可以成为保留或重新引入它们的理由。 + +**用流展开替代可见性查询。** 当前没有需要迁移的生产调用方。新增替代实现会继续保留未使用的 API,并引入记录读取器原本避免的分配开销。 + +## 验收标准 + +- 源码导出和现行 API 文档中不再包含这五个名称;生产调用方不新增展开操作或替代可见性查询。 +- 针对流读取器、Session Stats 和 Trajectory 计时的检查通过;混合测试保留无关断言。 +- 类型检查、受影响发布入口的构建和文档检查通过。Session 格式、模型输入、transcript(文本记录)内容和首 token 计时保持不变。 + +## 风险 + +这会有意收缩导出的稳定前 API。即使仓库中没有消费方,外部导入仍可能失效。实施前重新核对消费方证据,并明确评估发现的外部需求;不得宣称整个生态均未使用这些函数。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.i18n.yaml new file mode 100644 index 0000000000..3920961bcf --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.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/proposed/simplification/2026-09-19-python-sdk-directional-client.md +2026-09-19-python-sdk-directional-client.md: 287126d65cc9e81e240c2b18081b2935c107760a +2026-09-19-python-sdk-directional-client.zh.md: caf9b7c73a00b8865b6d189fe512f96afb20dad9 diff --git a/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.md b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.md new file mode 100644 index 0000000000..287126d65c --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.md @@ -0,0 +1,34 @@ +# Agent Note: Remove the Python SDK's unused reverse RPC direction + +Status: proposed + +English | [中文](2026-09-19-python-sdk-directional-client.zh.md) + +## Problem + +The [Python client](../../../../python/sdk/src/deepseek_harness/client.py) keeps an incoming-request queue, close-time wake-up, and `next_request`, `respond`, `respond_error`, and `notify` methods. The [SDK server](../../../../packages/sdk/server/src/server.ts) receives requests and emits notifications; it declares no server-originated request or client-notification handler. Searches across Python sources, examples, and runtime profiles found the reverse direction only in client implementation and [synthetic client tests](../../../../python/sdk/tests/test_client.py). The exported `IncomingRequest` model consequently has no supported runtime producer. + +This is a narrower continuation of the [directional JSON-RPC proposal](../../rejected/simplification/2026-07-19-make-jsonrpc-directional.md), whose rejection explicitly permits transport narrowing separately. Its completion redesign remains rejected. Its claim about the shared TypeScript transport is now inapplicable: the [Codex wire adapter](../../../../packages/subagent/subagent-codex/src/wire.ts) uses requests and notifications in both directions. + +## Proposal + +Remove the four Python methods, `_requests`, and `IncomingRequest` from the client, models, and exports. Retain an explicit guard for an unexpected frame containing both `id` and `method` before response matching, so a server request cannot settle an unrelated pending client request. Keep client requests, response validation, incoming notification subscriptions, and shutdown unchanged. + +Remove the dedicated synthetic reverse-request test. Change tests that send client notifications only to trigger fixture behavior to use a request and response instead; retain their filter-exception and concurrent-write assertions. This removes one queue and its lifetime, four public methods, one public model, and roughly three dozen source lines without adding a replacement transport. + +## Alternatives considered + +**Keep a generic Python peer for external plugins.** Custom runtimes could use the methods, but no SDK method describes their request ownership, cancellation, or delivery protocol. The proposal accepts this pre-stable API loss; a future bidirectional SDK feature must supply its actual method and lifecycle requirements. + +**Narrow the shared TypeScript transport too.** Rejected because the Codex adapter is a current bidirectional consumer. The shared implementation and its tests remain. + +## Acceptance criteria + +- Python sources and examples have no reverse-direction API or request queue; documentation and exports describe the retained client role. +- An unexpected server request reusing a pending client id cannot complete its waiter. Notification filtering, sibling delivery, final draining, malformed-frame handling, serialized writes, and shutdown still pass their existing tests. +- Prompt submission still returns the durable enqueue receipt; no per-prompt completion promise or response-based turn result is introduced. +- Run the Python client suite and installed-runtime SDK smoke and snapshot checks, plus documentation and lint checks. Preserve the TypeScript transport and released Session fixtures. + +## Risks + +External Python callers using custom runtime plugins lose these methods. Ignoring an unsupported request does not fulfill a hypothetical server's response expectation; this is deliberate withdrawal of that direction, not protocol parity. Revisit the proposal if a supported server-originated method lands before implementation. diff --git a/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.zh.md b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.zh.md new file mode 100644 index 0000000000..caf9b7c73a --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-python-sdk-directional-client.zh.md @@ -0,0 +1,34 @@ +# Agent Note: 删除 Python SDK 未使用的反向 RPC + +Status: proposed + +[English](2026-09-19-python-sdk-directional-client.md) | 中文 + +## 问题 + +[Python 客户端](../../../../python/sdk/src/deepseek_harness/client.py) 维护入站请求队列、关闭时的唤醒,以及 `next_request`、`respond`、`respond_error` 和 `notify` 方法。[SDK 服务端](../../../../packages/sdk/server/src/server.ts) 接收请求并发送通知,没有定义服务端主动发起的请求或客户端通知处理器。搜索 Python 源码、示例和运行时 profile 后,仅在客户端实现和[合成客户端测试](../../../../python/sdk/tests/test_client.py) 中发现反向通信。因此,导出的 `IncomingRequest` 模型没有受支持运行时的生产方。 + +这是[定向 JSON-RPC 提案](../../rejected/simplification/2026-07-19-make-jsonrpc-directional.zh.md) 的缩小范围续案;该提案的否决原因明确允许单独重提传输收缩。其完成语义重设计仍被否决。它对共享 TypeScript 传输的判断已不适用:[Codex wire 适配器](../../../../packages/subagent/subagent-codex/src/wire.ts) 在两个方向上都使用请求和通知。 + +## 提案 + +从客户端、模型和导出中删除四个 Python 方法、`_requests` 和 `IncomingRequest`。在匹配响应前,保留对同时含有 `id` 和 `method` 的意外帧的显式保护,避免服务端请求完成无关的待处理客户端请求。保持客户端请求、响应校验、入站通知订阅和关闭行为。 + +删除专门的合成反向请求测试。仅为触发 fixture(测试前置数据)行为而发送客户端通知的测试改用请求和响应,同时保留过滤器异常与并发写入断言。该变更删除一个队列及其生命周期、四个公共方法、一个公共模型和约三十多行源码,不增加替代传输实现。 + +## 考虑过的替代方案 + +**保留通用 Python 对等端供外部插件使用。** 自定义运行时可能使用这些方法,但没有 SDK 方法规定其请求所有权、取消或交付协议。提案接受这一稳定前 API 损失;未来双向 SDK 功能必须提供实际的方法与生命周期要求。 + +**同时收缩共享 TypeScript 传输。** 否决,因为 Codex 适配器是当前双向消费方。共享实现及其测试保留。 + +## 验收标准 + +- Python 源码和示例不再包含反向 API 或请求队列;文档和导出描述保留的客户端角色。 +- 复用待处理客户端 id 的意外服务端请求不能完成其等待方。通知过滤、同级交付、末尾排空、错误帧处理、串行写入和关闭仍通过现有测试。 +- 提交提示仍返回持久化入队回执;不引入单条提示的完成承诺或基于响应的轮次结果。 +- 运行 Python 客户端测试、已安装运行时的 SDK 冒烟与快照检查,以及文档和 lint 检查。保留 TypeScript 传输和已发布 Session fixture。 + +## 风险 + +使用自定义运行时插件的外部 Python 调用方会失去这些方法。忽略不支持的请求无法满足假想服务端的响应期待;这是有意撤回该方向,而非保持协议等价。如果受支持的服务端主动请求方法先于实现落地,需要重新评估提案。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.i18n.yaml new file mode 100644 index 0000000000..d11c6bed98 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.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/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.md +2026-09-19-retire-app-bin-boot-helpers.md: c67013bfae8569d0f750b3c8be5e56c57a2a66aa +2026-09-19-retire-app-bin-boot-helpers.zh.md: 5ef68ff3d8666e8b74d36c50eacbcf5048a4438a diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.md b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.md new file mode 100644 index 0000000000..c67013bfae --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.md @@ -0,0 +1,36 @@ +# Agent Note: Retire app-boot helpers used only by fixtures + +Status: proposed + +English | [中文](2026-09-19-retire-app-bin-boot-helpers.zh.md) + +## Problem + +[App boot](../../../../packages/boot/app-boot/src/index.ts) exports `resolveConfigPath`, including a basename-specific replay substitution, and `loadEnv`, which reads one optional `.env`. The supported [CLI launcher](../../../../apps/cli/src/bin.ts) uses `loadLayeredEnv`; [profile boot](../../../../apps/cli/src/profile-boot.ts) supplies an absolute path directly. Neither production path calls the older helpers. + +An exact-symbol search across packages, apps, and scripts finds ten `resolveConfigPath` calls in eight fixture drivers, all passing `undefined` for replay mode. The only non-unit `loadEnv` caller is the [Loader smoke fixture](../../../../packages/test-support/loader-smoke/tests/fixtures/headless-driver.ts). The [snapshot launcher](../../../../packages/test-support/session-snapshot/src/launcher.ts) separately owns replay patch selection. The old helpers consequently retain two public APIs, unused production replay policy, and dedicated tests for fixture-only needs. + +The [shared app-bin glue record](../../archived/simplification/2026-07-04-share-app-bin-boot-glue.md) explains the original shared-bin use. The active [single-launcher decision](../../implemented/architecture/2026-08-22-single-dsh-application-launcher.md) replaces those supported entry paths. This is partial supersession: `boot` and fail-loud handling still have owners, and the archived record remains frozen. + +## Proposal + +Delete `resolveConfigPath` and `loadEnv` from the production export. Use Node's `path.resolve` in the eight fixture drivers. Keep optional one-directory `.env` handling local to the sole fixture that needs it, including its absent-file and warning behavior; do not introduce a replacement production package. + +Remove helper-specific tests and update app-boot's package description, README pair, and `boot` JSDoc. Keep `boot`, `loadLayeredEnv`, shipped profile composition, and snapshot replay selection. The identified removal is 39 production source/JSDoc lines and about 73 dedicated test lines, less the small fixture-local environment handling and builtin imports; the estimate is not an implemented diff. + +## Alternatives considered + +**Keep public conveniences for low-level embedders.** They can be useful, but current fixtures request only path resolution and one optional file read. Maintaining a second production replay selector and obsolete app-bin guidance is disproportionate to those uses. + +**Replace every use with `loadLayeredEnv`.** Rejected because layered discovery, filtering, and precedence differ from reading one fixture-local `.env`. Sharing a name does not establish equivalent behavior. + +## Acceptance criteria + +- Exact-name searches find no live helper imports or calls. All ten path replacements remain absolute and select the same files. +- The sole environment-loading fixture preserves missing-file, present-file, and warning behavior; helper-only tests disappear without dropping retained boot coverage. +- Run focused app-boot and affected fixture-entry tests, including built entry checks where required, a shipped profile smoke, and a keyless replay scenario. +- Update README pairs and package/JSDoc descriptions; run build, relevant hygiene, typecheck, doc-sync, and lint. Add no compatibility aliases or second replay selector. + +## Risks + +Out-of-tree callers importing these pre-stable helpers must use the retained profile APIs or own their low-level path/environment policy. Accidentally switching the fixture to layered environment discovery would change its test inputs; preserve that distinction explicitly. diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.zh.md b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.zh.md new file mode 100644 index 0000000000..5ef68ff3d8 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-app-bin-boot-helpers.zh.md @@ -0,0 +1,36 @@ +# Agent Note: 删除仅供 fixture 使用的 app-boot 辅助函数 + +Status: proposed + +[English](2026-09-19-retire-app-bin-boot-helpers.md) | 中文 + +## 问题 + +[App boot](../../../../packages/boot/app-boot/src/index.ts) 导出 `resolveConfigPath`,其中包含按文件名替换重放配置的逻辑,以及读取单个可选 `.env` 的 `loadEnv`。受支持的 [CLI 启动器](../../../../apps/cli/src/bin.ts) 使用 `loadLayeredEnv`;[profile boot](../../../../apps/cli/src/profile-boot.ts) 直接提供绝对路径。这两条生产路径都不调用旧辅助函数。 + +在 packages、apps 和 scripts 中搜索精确符号,可找到八个 fixture(测试前置数据)驱动器中的十次 `resolveConfigPath` 调用,重放模式全部传入 `undefined`。唯一非单元测试的 `loadEnv` 调用方是 [Loader 冒烟 fixture](../../../../packages/test-support/loader-smoke/tests/fixtures/headless-driver.ts)。[快照启动器](../../../../packages/test-support/session-snapshot/src/launcher.ts) 单独拥有重放补丁选择。因此,旧辅助函数仅为 fixture 的需要保留了两个公共 API、生产中未使用的重放策略及专用测试。 + +[共享 app-bin 胶水代码记录](../../archived/simplification/2026-07-04-share-app-bin-boot-glue.md) 解释了最初的共享可执行入口用途。当前[单一启动器决策](../../implemented/architecture/2026-08-22-single-dsh-application-launcher.zh.md) 已替代这些受支持入口。这属于部分取代:`boot` 和明确失败处理仍有归属,归档记录保持冻结。 + +## 提案 + +从生产导出中删除 `resolveConfigPath` 和 `loadEnv`。八个 fixture 驱动器改用 Node 的 `path.resolve`。仅在需要它的 fixture 内保留读取单目录可选 `.env` 的处理,包括文件缺失与警告行为;不引入替代生产包。 + +删除辅助函数专用测试,并更新 app-boot 的包描述、README 配对及 `boot` JSDoc。保留 `boot`、`loadLayeredEnv`、随产品发布的 profile 组合和快照重放选择。已定位可删除 39 行生产源码/JSDoc 和约 73 行专用测试,需扣除少量 fixture 本地环境处理及内置模块导入;这是估算,尚非实现 diff。 + +## 考虑过的替代方案 + +**为底层嵌入方保留公共便利函数。** 它们可能有用,但当前 fixture 仅需要路径解析和单个可选文件读取。为这些用途维护第二套生产重放选择器及过时的 app-bin 指南,成本过高。 + +**将所有调用替换为 `loadLayeredEnv`。** 否决,因为分层发现、过滤和优先级不同于读取单个 fixture 本地 `.env`。名称相近不能证明行为等价。 + +## 验收标准 + +- 精确名称搜索不再发现有效的辅助函数导入或调用。十处路径替换仍为绝对路径并选择相同文件。 +- 唯一加载环境的 fixture 保持文件缺失、文件存在和警告行为;删除辅助函数专用测试时不丢失保留的 boot 覆盖。 +- 运行聚焦的 app-boot 和受影响 fixture 入口测试,包括所需的构建产物入口检查、随产品发布的 profile 冒烟,以及无密钥重放场景。 +- 更新 README 配对及包/JSDoc 描述;运行 build、相关 hygiene、typecheck、doc-sync(文档同步门禁)和 lint。不添加兼容别名或第二个重放选择器。 + +## 风险 + +导入这些稳定前辅助函数的仓库外调用方,需要改用保留的 profile API,或自行拥有底层路径与环境策略。意外将 fixture 改为分层环境发现会改变其测试输入;必须明确保留这一差别。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.i18n.yaml new file mode 100644 index 0000000000..625e054ecf --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.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/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.md +2026-09-19-retire-prompt-registry-change-event.md: 1103675525e30c7f6c345a1fe92f07cbd0bcce4a +2026-09-19-retire-prompt-registry-change-event.zh.md: a49df2eebad7134b7b038ee2e6ab54610bd4c635 diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.md b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.md new file mode 100644 index 0000000000..1103675525 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.md @@ -0,0 +1,35 @@ +# Agent Note: Retire the prompt registry change event + +Status: proposed + +English | [中文](2026-09-19-retire-prompt-registry-change-event.zh.md) + +## Problem + +[`SystemPrompt`](../../../../packages/core/system-prompt/src/index.ts) emits `system-prompt/change` when providers register or dispose. Repository searches find no executing product listener, but generated Host discovery advertises the event. Tests maintain notification counts and rollback after listener exceptions. This is a public extension with maintenance obligations, even without a first-party subscriber. + +The active [Remote event delivery decision](../../implemented/architecture/2026-08-10-remote-event-delivery.md) explicitly retains this extension despite having no shipped consumer. Per-step assembly predates that promise and serves a different purpose: rebuilding model input does not replace push observation of registry changes. + +## Proposal + +Retire `system-prompt/change` and accept the loss of prompt-registry push observation for installed and dynamically authored Host plugins. Remove its declaration, emitter, current documentation, generated discovery entries, and notification-specific tests. No currently supported product path requires this extension. + +Make [`ScopedLayers`](../../../../packages/core/scope/src/store.ts)'s constructor notification callback optional and omit it for `SystemPrompt`; do not supply a no-op callback. Remove the existing no-op arguments in [jobs-local](../../../../packages/jobs/jobs-local/src/index.ts) and [mcp-resources](../../../../packages/mcp/mcp-resources/src/index.ts) when updating this shared constructor, and update jobs-local's adjacent notification explanation. Preserve shared effects, action rollback, undo ordering, layer reclamation, and `tools/change` with its production consumers. Keep prompt-provider evaluation, scope shadowing, and assembly invariants. + +Implementation must amend the active Remote event delivery note to state that this proposal supersedes only its promise to retain `system-prompt/change`. Remove that event from the retained-extension statement and link the implemented retirement decision. Keep the Remote delivery note active and cross-linked: its forwarding policy and other extensions remain independently useful. Do not rewrite or archive that entire decision. + +## Alternatives considered + +**Keep the extension for future dashboards or plugins.** Push observation could support a real consumer, but none is identified in supported product paths. Retention preserves notification and listener-failure behavior that the package otherwise does not need. + +**Treat per-step assembly as proof of compatibility.** Rejected because model-input reconstruction and registry notifications are different behaviors. This proposal deliberately changes the extension promise rather than claiming the earlier reconstruction decision already removed it. + +## Acceptance criteria + +- Remove the event from source and current generated inventories, and amend the active retention promise in the implementation change. +- Remove notification-count and notification-failure tests; retain provider-membership, disposer, duplicate-registration, shadowing, and HMR coverage. Keep mixed tests' independent assertions. +- Run focused scope, tools, system-prompt, jobs-local, and mcp-resources tests, loop request-reconstruction coverage, a relevant keyless recording, catalog generation, typecheck, lint, and doc-sync. Prompt/log output remains unchanged. + +## Risks + +Installed plugins may depend on notifications or on listener exceptions rejecting registration. They lose both behaviors; repository searches cannot establish their absence. A future push consumer needs an explicit registration-observation requirement and ownership design before reintroducing an event. Source savings are small; the benefit is retiring the public notification and failure obligation. diff --git a/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.zh.md b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.zh.md new file mode 100644 index 0000000000..a49df2eeba --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-retire-prompt-registry-change-event.zh.md @@ -0,0 +1,35 @@ +# Agent Note: 停用提示词注册表变更事件 + +Status: proposed + +[English](2026-09-19-retire-prompt-registry-change-event.md) | 中文 + +## 问题 + +[`SystemPrompt`](../../../../packages/core/system-prompt/src/index.ts) 在提供方注册或 dispose(资源释放)时发出 `system-prompt/change`。仓库搜索未找到执行的产品监听者,但生成的 Host 发现目录会展示该事件。测试维护通知次数及监听者抛出异常后的回滚行为。即使没有第一方订阅者,它仍是具有维护义务的公开扩展。 + +活动的 [Remote 事件投递决策](../../implemented/architecture/2026-08-10-remote-event-delivery.zh.md) 明确保留了这一扩展,尽管没有随产品提供的消费方。逐步骤组装早于该承诺,且用途不同:重新构建模型输入不能替代注册表变更的推送观测。 + +## 提案 + +停用 `system-prompt/change`,接受已安装及动态编写的 Host 插件失去提示词注册表推送观测的代价。删除其声明、发出点、当前文档、生成的发现条目和通知专属测试。当前受支持的产品路径均不依赖此扩展。 + +将 [`ScopedLayers`](../../../../packages/core/scope/src/store.ts) 构造函数的通知回调改为可选,并让 `SystemPrompt` 省略它;不提供无操作回调。更新此共享构造函数时,同时删除 [jobs-local](../../../../packages/jobs/jobs-local/src/index.ts) 和 [mcp-resources](../../../../packages/mcp/mcp-resources/src/index.ts) 中现有的无操作实参,并更新 jobs-local 相邻的通知说明。保留共享 effect、操作回滚、撤销顺序、层回收,以及 `tools/change` 及其生产消费方。保留提示词提供方求值、作用域覆盖和组装 invariant。 + +实现时必须修订活动的 Remote 事件投递记录,说明本提案只取代其中保留 `system-prompt/change` 的承诺。从保留扩展的陈述中移除该事件,并链接到已实现的停用决策。让 Remote 投递记录保持活动并相互链接:其转发策略和其他扩展仍具有独立价值。不要重写或归档整个决策。 + +## 考虑过的替代方案 + +**为未来仪表盘或插件保留扩展。** 推送观测可能服务于真实消费方,但受支持的产品路径中尚未找到这样的消费方。保留它会维持这个包原本不需要的通知及监听者失败行为。 + +**将逐步骤组装视为兼容性证据。** 不采用,因为模型输入重建和注册表通知是不同的行为。本提案有意改变扩展承诺,而不声称早先的重建决策已经删除了它。 + +## 验收标准 + +- 从源代码和当前生成目录中删除该事件,并在实现变更中修订活动记录中的保留承诺。 +- 删除通知次数和通知失败测试;保留提供方成员关系、disposer、重复注册、作用域覆盖及 HMR(热模块替换)覆盖。保留混合测试中的独立断言。 +- 运行针对作用域、工具、系统提示词、jobs-local 和 mcp-resources 的测试、循环请求重建覆盖、相关无密钥录制回放、目录生成、类型检查、lint 和 doc-sync(文档同步门禁)。提示词和日志输出保持不变。 + +## 风险 + +已安装插件可能依赖通知,或依赖监听者异常使注册失败。这两种行为都会消失;仓库搜索无法确认此类插件不存在。未来的推送消费方需要先明确注册观测需求和所有权设计,才能重新引入事件。源代码节省不多;收益在于停用公开通知及其失败义务。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.i18n.yaml new file mode 100644 index 0000000000..bed94c3f36 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.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/proposed/simplification/2026-09-19-shell-env-key-declarations.md +2026-09-19-shell-env-key-declarations.md: 7b74e55e6b8602cb488d16040d57fe41d16e14da +2026-09-19-shell-env-key-declarations.zh.md: 03d7ed9fdee1c1181c529c2b2dd26ceb7c791ef2 diff --git a/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.md b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.md new file mode 100644 index 0000000000..7b74e55e6b --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.md @@ -0,0 +1,34 @@ +# Agent Note: Keep shell-environment declarations focused on key ownership + +Status: proposed + +English | [中文](2026-09-19-shell-env-key-declarations.zh.md) + +## Problem + +The [shell-environment registry](../../../../packages/shell/shell-env/src/index.ts) requires a description for every declared variable and exposes `list()` to enumerate it. Runtime collection uses only contributor identity, declared keys, and resolved values. [Bash](../../../../packages/shell/tool-bash/src/index.ts) and [PowerShell](../../../../packages/shell/tool-pwsh/src/index.ts) call `collect`; the [Web bundle](../../../../packages/bundle/web-app/src/index.ts) contributes `DSH_WEB_URL`. Searches found no fixed production caller of `list()` or consumer of its descriptions. + +The method is nevertheless discoverable through the [Cordis inspection provider](../../../../packages/extensions/tool-cordis/src/providers.ts), so this is an explicit API contraction, not unreachable-code removal. The [original identity-and-log-location record](../../archived/feature/2026-07-10-agent-session-identity-and-log-location.md) anticipated diagnostics and future prompt/UI consumers. The current TODO and [README limitation](../../../../packages/shell/shell-env/README.md) still describe an incomplete catalog that omits built-in variables. + +## Proposal + +Represent a contributor's declaration as an explicit readonly collection of keys. Remove description objects, `BashEnvVariable`, `BashEnvVariableInfo`, `list()`, description-only validation, and the exhaustive-catalog TODO. Update the Web contributor, README pair, and generated service/type declarations together. + +Keep `register`, `collect`, reserved keys, ownership conflicts, undeclared-output refusal, deterministic environment output, and effect disposal. The [PowerShell parity decision](../../implemented/feature/2026-08-02-pwsh-tool-bash-parity.md) continues to own the shared registry and both shell consumers. The proposal removes one public method, two metadata types, and their validation/enumeration tests; roughly 32 identified source lines disappear before the small key-membership adaptation. + +## Alternatives considered + +**Finish the diagnostics catalog.** That would add built-in metadata and a consumer capability without an identified current product requirement. The proposal instead gives up declarative environment descriptions and enumeration; actual shell environment values remain available through execution. + +**Keep descriptions after deleting `list()`.** Rejected because they would have no remaining reader while still burdening every contributor. Preserve the key ownership declaration independently of presentation metadata. + +## Acceptance criteria + +- Recheck fixed callers, recordings, generic inspection, and current product requirements before implementation; retain the API if an actual diagnostics consumer now needs it. +- Contributors declare keys without description objects. Duplicate names, reserved keys, cross-contributor conflicts, undeclared outputs, and disposal retain their behavior. +- Bash and PowerShell receive equivalent environment maps, including Web URL and Session identity; no secret-handling or ambient-environment policy changes. +- Run registry, Web contributor, and shell integration tests; regenerate and validate inspection catalogs and any affected recorded inspection output; update both READMEs and run typecheck, doc-sync, and lint. + +## Risks + +Model-written and external plugins can already discover and call `list()`. They lose enumeration without resolver execution and must change contributor declarations. This pre-stable API loss is acceptable only while the anticipated diagnostics capability remains unowned; `collect()` is not advertised as an equivalent diagnostic replacement. diff --git a/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.zh.md b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.zh.md new file mode 100644 index 0000000000..03d7ed9fde --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-shell-env-key-declarations.zh.md @@ -0,0 +1,34 @@ +# Agent Note: 让 shell 环境声明只负责键所有权 + +Status: proposed + +[English](2026-09-19-shell-env-key-declarations.md) | 中文 + +## 问题 + +[shell 环境注册表](../../../../packages/shell/shell-env/src/index.ts) 要求每个声明变量提供描述,并暴露 `list()` 枚举它。运行时收集仅使用贡献方身份、声明键和解析后的值。[Bash](../../../../packages/shell/tool-bash/src/index.ts) 与 [PowerShell](../../../../packages/shell/tool-pwsh/src/index.ts) 调用 `collect`;[Web 组合包](../../../../packages/bundle/web-app/src/index.ts) 贡献 `DSH_WEB_URL`。搜索未发现 `list()` 的固定生产调用方或其描述的消费方。 + +但该方法可通过 [Cordis 检查提供方](../../../../packages/extensions/tool-cordis/src/providers.ts) 发现,因此这是显式 API 收缩,而非删除不可达代码。[最初的身份与日志位置记录](../../archived/feature/2026-07-10-agent-session-identity-and-log-location.md) 预期它会服务于诊断以及未来提示/UI 消费方。当前 TODO 与 [README 限制](../../../../packages/shell/shell-env/README.zh.md) 仍描述一个未包含内置变量的不完整目录。 + +## 提案 + +将贡献方声明表示为显式只读键集合。删除描述对象、`BashEnvVariable`、`BashEnvVariableInfo`、`list()`、仅针对描述的校验,以及完整目录 TODO。同时更新 Web 贡献方、README 配对与生成的服务/类型声明。 + +保留 `register`、`collect`、保留键、所有权冲突、拒绝未声明输出、确定性的环境输出和 effect 释放。[PowerShell 对齐决策](../../implemented/feature/2026-08-02-pwsh-tool-bash-parity.zh.md) 继续拥有共享注册表及两个 shell 消费方。提案删除一个公共方法、两个元数据类型及其校验/枚举测试;在少量键成员判定适配前,已定位可删除约 32 行源码。 + +## 考虑过的替代方案 + +**补完诊断目录。** 这会在没有明确当前产品需求的情况下增加内置元数据及消费能力。提案选择放弃声明式环境描述和枚举;实际 shell 环境值仍可通过执行获得。 + +**删除 `list()` 后保留描述。** 否决,因为描述将没有剩余读取方,却仍给每个贡献方增加负担。键所有权声明应独立于展示元数据保留。 + +## 验收标准 + +- 实现前重新检查固定调用方、记录、通用检查与当前产品要求;若已有实际诊断消费方需要,则保留 API。 +- 贡献方声明键而无需描述对象。重复名称、保留键、跨贡献方冲突、未声明输出及释放保持原有行为。 +- Bash 与 PowerShell 获得等价的环境映射,包括 Web URL 和 Session 身份;不改变密钥处理或继承环境策略。 +- 运行注册表、Web 贡献方与 shell 集成测试;重新生成并校验检查目录及受影响的检查输出记录;更新两个 README,运行 typecheck、doc-sync(文档同步门禁)和 lint。 + +## 风险 + +模型编写的插件与外部插件已经能够发现和调用 `list()`。它们会失去不执行解析器的枚举能力,并需要修改贡献方声明。只有预期的诊断能力仍无归属时,这种稳定前 API 损失才可接受;不能将 `collect()` 宣称为等价诊断替代。 diff --git a/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.i18n.yaml b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.i18n.yaml new file mode 100644 index 0000000000..676a701835 --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.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/proposed/simplification/2026-09-19-trim-session-query-convenience-api.md +2026-09-19-trim-session-query-convenience-api.md: 1a3d558c9be5e16b5e9e84a59a9731b55174114c +2026-09-19-trim-session-query-convenience-api.zh.md: 63c3ae309edee8366eae4d5db10cc59f0b72e843 diff --git a/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.md b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.md new file mode 100644 index 0000000000..1a3d558c9b --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.md @@ -0,0 +1,35 @@ +# Agent Note: Trim unused SessionQuery convenience methods + +Status: proposed + +English | [中文](2026-09-19-trim-session-query-convenience-api.zh.md) + +## Problem + +[`SessionQueryEngine`](../../../../packages/session-query/session-query/src/index.ts) maintains `readSession`, `readTitle`, `readTitleSnapshot`, and `listEvents` without executing first-party product callers. Exact-name and call-site searches find internal delegation, tests, and generated discovery metadata. Current consumers use retained observations, batch titles, surface reads, and traces. The generated catalog exposes these methods to plugin authors but does not execute the advertised operations. + +These entry points add replay-validation and result-copying paths, wrappers, public types, and endpoint-specific tests. Their removal can reduce maintained API obligations without replacing the shared query implementation. + +## Proposal + +Remove the four methods, the unreferenced [`SessionLogSnapshot`](../../../../packages/session-query/session-query/src/types.ts) result type, and [`eventRecords`](../../../../packages/session-query/session-query/src/tracing.ts). Remove their imports and current documentation, including the `SessionLogSnapshot` type-equivalence block and explanatory paragraph in both subsystem pages. Remove its hand-maintained entry in the [type-equivalence manifest](../../../../scripts/type-equiv.manifest.json) and its `LINK_MAP` entry in the [catalog generator](../../../../scripts/gen-cordis-catalog.ts), then regenerate discovery metadata. The selected definitions occupy approximately eighty source lines before import and metadata cleanup; no replacement service is needed. + +Retain `filterEvents` and `_filterEvents`, together with their semantic extraction and filtering helpers. Retain `observeSession`, `readTitleSnapshots`, `readSurface`, `readEvent`, listing, search, and tracing. Preserve shared corpus resolution and its existing ownership and failure behavior. + +The [historical unified-query decision](../../archived/architecture/2026-07-23-unified-session-query-service.md) explains the retained single-service topology. This proposal removes selected convenience operations, not that topology. No active note is fully superseded; keep archived records frozen and link this narrower decision from affected current documentation. + +## Alternatives considered + +**Retain all documented methods for external callers.** This avoids migration for installed plugins, but keeps four APIs without a current product caller. The pre-stable API policy permits a deliberate removal with explicit migration costs. + +**Remove `filterEvents` too.** Rejected because its provider-independent literal substring scan differs from FTS token matching. The [SQLite query documentation](../../../../packages/session-query/session-query-sqlite/README.md) explicitly recommends this operation; removing it would withdraw a distinct query capability. + +## Acceptance criteria + +- Remove the four methods and orphan definitions from source, package READMEs, subsystem declarations, and generated catalogs; retain literal substring queries. +- Preserve live-source precedence, corruption refusal, cancellation, detached results, cold reads, and batch-title behavior through retained endpoints. Move relevant assertions from removed-method tests instead of deleting their shared guarantees; account for `readSession`'s additional replay validation. +- Run focused query, SQLite-query, tool-query, and affected context-reference tests, relevant keyless query recordings, catalog generation, typecheck, lint, and doc-sync. Released Session generations remain unchanged. + +## Risks + +Repository searches cannot enumerate installed or dynamically authored plugins. Such callers lose complete-log and lightweight-record convenience operations and must adopt retained APIs with their actual ownership and error semantics. A demonstrated consumer requiring a removed operation would justify reconsidering that operation separately. diff --git a/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.zh.md b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.zh.md new file mode 100644 index 0000000000..63c3ae309e --- /dev/null +++ b/.agents/notes/proposed/simplification/2026-09-19-trim-session-query-convenience-api.zh.md @@ -0,0 +1,35 @@ +# Agent Note: 精简未使用的 SessionQuery 便利方法 + +Status: proposed + +[English](2026-09-19-trim-session-query-convenience-api.md) | 中文 + +## 问题 + +[`SessionQueryEngine`](../../../../packages/session-query/session-query/src/index.ts) 维护了 `readSession`、`readTitle`、`readTitleSnapshot` 和 `listEvents`,但没有执行这些方法的第一方产品调用方。精确名称和调用点搜索只找到内部委托、测试和生成的发现元数据。当前消费方使用可保留的观测、批量标题、模型可见事件读取和追踪。生成的目录向插件作者展示这些方法,但不执行其中列出的操作。 + +这些入口增加了回放验证和结果复制路径、包装层、公开类型及入口专属测试。删除它们可以减少需要维护的 API 义务,无须替换共享查询实现。 + +## 提案 + +删除这四个方法、不再被引用的 [`SessionLogSnapshot`](../../../../packages/session-query/session-query/src/types.ts) 结果类型和 [`eventRecords`](../../../../packages/session-query/session-query/src/tracing.ts)。删除相关导入及当前文档,包括两个子系统页面中的 `SessionLogSnapshot` 类型等价代码块和说明段落。删除[类型等价 manifest](../../../../scripts/type-equiv.manifest.json) 中手工维护的条目,以及[目录生成器](../../../../scripts/gen-cordis-catalog.ts) 中的 `LINK_MAP` 条目,然后重新生成发现元数据。选定定义在清理导入和元数据之前约占八十行源代码;无须新增替代服务。 + +保留 `filterEvents` 和 `_filterEvents`,以及语义提取和过滤辅助函数。保留 `observeSession`、`readTitleSnapshots`、`readSurface`、`readEvent`、列举、搜索和追踪。保留共享会话集合解析及其现有所有权和失败行为。 + +[历史上的统一查询决策](../../archived/architecture/2026-07-23-unified-session-query-service.md) 解释了保留的单服务结构。本提案删除选定的便利操作,不改变该结构。没有活动记录被完全取代;保持归档记录冻结,并从受影响的当前文档链接到这一较窄的决策。 + +## 考虑过的替代方案 + +**为外部调用方保留所有已记录的方法。** 这样可以避免已安装插件迁移,但会保留四个没有当前产品调用方的 API。尚未稳定的 API 策略允许在明确迁移代价后有意删除它们。 + +**同时删除 `filterEvents`。** 不采用,因为其提供方无关的字面子串扫描不同于 FTS 的 token 匹配。[SQLite 查询文档](../../../../packages/session-query/session-query-sqlite/README.zh.md) 明确推荐该操作;删除它会撤销一项独立的查询能力。 + +## 验收标准 + +- 从源代码、包 README、子系统声明和生成目录中删除这四个方法及失去引用的定义;保留字面子串查询。 +- 通过保留的入口维持实时来源优先、损坏拒绝、取消、结果独立复制、冷读取和批量标题行为。将被删方法测试中的相关断言迁移出去,不删除其共享保证;明确处理 `readSession` 额外执行的回放验证。 +- 运行针对查询、SQLite 查询、查询工具及受影响的会话引用的测试,相关无密钥查询录制回放、目录生成、类型检查、lint 和 doc-sync(文档同步门禁)。已发布的 Session 代际文件保持不变。 + +## 风险 + +仓库搜索无法枚举已安装或动态编写的插件。这些调用方将失去完整日志和轻量事件记录的便利操作,必须按照保留 API 实际的所有权和错误语义迁移。若出现确实需要某个被删操作的消费方,可以单独重新考虑该操作。 diff --git a/.agents/skills/dsh-find-simplifications/SKILL.md b/.agents/skills/dsh-find-simplifications/SKILL.md index bce148ad18..53444db411 100644 --- a/.agents/skills/dsh-find-simplifications/SKILL.md +++ b/.agents/skills/dsh-find-simplifications/SKILL.md @@ -1,157 +1,67 @@ --- name: dsh-find-simplifications -description: 'Use when working in the deepseek-harness repo to find non-obvious simplification candidates, remove redundant comments or implementation-heavy documentation, write proposed Agent Notes or inline TODO/FIXME/XXX notes, audit or coalesce superseded Agent Notes, or fold worthwhile simplification ideas from another PR; especially for dead, duplicated, speculative, over-built, added-then-removed, or hand-rolled-where-a-dependency-exists surfaces.' +description: Find evidence-backed simplifications in DeepSeek Harness code, APIs, configuration, tests, and prose; write or consolidate proposals, identify small inline cleanups, or assess simplifications from another branch. Use for removing dead, duplicated, speculative, or unnecessarily maintained behavior and infrastructure. --- # Finding DeepSeek Harness Simplifications -This skill helps turn a broad "find things to simplify" request into evidence-backed Agent Notes that remove or collapse existing harness surface area. It is guidance, not a checklist: follow the code, keep judgment active, and prefer a few well-proven candidates over a pile of thin guesses. +Find changes that remove maintained obligations: APIs, representations, lifecycle states, configuration paths, dependencies, tests, or documentation. Prefer a few well-supported candidates over a count of deletions. This is guidance, not a checklist; keep the user's scope and distinguish a survey from permission to implement its proposals. -## Start With Repo Context +## Establish scope and constraints -- Read `AGENTS.md`, especially the pre-release stance and the conventions (including the tests-are-not-golden-truth and Agent Notes-are-not-golden-truth doctrines), plus [docs/defensive-patterns.md](../../../docs/defensive-patterns.md) and [docs/testing.md](../../../docs/testing.md). -- Skim [docs/architecture.md](../../../docs/architecture.md) before judging anything under `packages/`; simplifications that fight the service map or event taxonomy need extra evidence. -- Use the Agent Note tree and its [rules](../../notes/README.md) to understand intentional architecture. The most relevant implemented examples are [drop mutable session summary](../../notes/archived/simplification/2026-06-19-drop-mutable-session-summary.md), [handle-based session persistence](../../notes/implemented/architecture/2026-08-27-handle-based-session-persistence.md), [JSONL-only first-party Session persistence](../../notes/implemented/simplification/2026-08-30-jsonl-only-session-persistence.md), [capability seams](../../notes/implemented/architecture/2026-06-13-capability-seams.md), and the twin-adapter Agent Notes. -- Treat dual LLM adapters as intentional by default. Session persistence is different: JSONL is the sole first-party provider, while the backend-neutral service remains available to out-of-tree providers. Do not propose deleting an LLM twin or the persistence seam as "low effort" unless the user explicitly overrides that constraint. Removing an unused method or hook inside a protected seam can still be valid if it does not collapse the protected design. +Read `AGENTS.md`, [architecture](../../../docs/architecture.md) before judging packages, [defensive patterns](../../../docs/defensive-patterns.md), and [testing policy](../../../docs/testing.md). Consult the relevant active Agent Notes for intentional decisions; use the [note rules](../../notes/README.md) for new records. Archived notes are historical examples, not current authority: never inspect, verify, or repair their outbound links. -## What Counts As A Strong Candidate +The two LLM adapters are intentional. JSONL is the sole first-party Session persistence provider, while the backend-neutral Service Definition supports out-of-tree providers. Do not propose deleting an LLM twin or the persistence seam unless the user explicitly overrides that constraint. Unused members within a protected design remain candidates when their removal preserves its purpose. -A strong simplification removes, folds, or demotes something real and has clear evidence that the current design costs more than it buys: +For broad requests, divide independent domains among subagents: loop and persistence; model/tool assembly; Host, Client, and SDKs; subprocess and execution providers; composition, scripts, tests, and documentation. Give each agent a bounded domain and require consumer evidence and rejected alternatives. Inspect substantial production machinery as well as obvious unused symbols; do not stop after the first promising deletion. -- A public method, event, config knob, registry notification, helper, package, durable event, or test artifact has no production consumer. -- Tests or docs are the only consumers, and the behavior they pin is not load-bearing. -- Two representations mirror the same fact, especially across durable session events and transient `agent/*` events. -- A seam has methods every implementation must support but no consumer uses. -- A separate package exists only for test/demo/support code and adds publish or dependency overhead. -- A feature implements speculative product generality: multi-session/session-load, background job rosters, live registry invalidation, mid-turn steering, tool-owned UI rendering, and similar designs with no product owner. -- An invariant, rollback path, set of expected outputs, or special-case test exists only to protect an unused API. -- Hand-rolled code reimplements what a well-maintained external package or a Node builtin at the engine floor already provides, and the swap would delete the implementation plus its dedicated tests ([dependency policy](../../notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.md)). -- The simplified behavior may differ slightly, but the new behavior is still reasonable and easier to explain. +## Search for removable obligations -Thin candidates are not enough for an Agent Note: deleting one typo, running `knip` once, removing an intentionally documented backend/adapter, or flagging "this looks complex" without call-site proof. +Use these questions to guide discovery. Read the relevant section of [historical patterns](references/historical-patterns.md) when a candidate needs calibration; the examples illustrate decisions, not a current deletion inventory. -### Audit invariant companions +- **Does a declared feature have a complete effect path?** Trace producer, transformations, provider or endpoint support, and observable result. A field copied everywhere may still have no setter, no reader, or only implementations that reject it. Search constructors and discriminant emitters as well as callers. +- **Which distinctions change a consumer's action?** Several internal states may require one model-facing status or one usable identifier. Keep internal distinctions that control authorization, residency, durability, or ownership; remove public distinctions that only invite an unusable choice. +- **Could a smaller explicit behavior remove the subsystem?** Fixed intervals, caller-supplied time zones, or reported activation failure can eliminate generalized calendars, persisted defaults, or automatic rollback. Name the capability given up and the machinery deleted. A production caller makes this a behavior decision, not an automatic rejection; implementation must remain within the user's authorization. +- **Can a consumer read the authoritative value when needed?** Look for copied histories, promotion ledgers, invalidation events followed by reads, and feature caches beside a shared projection stream. Derivation or reuse may delete subscriptions, retained data, stale-response handling, and recovery paths together. Establish the required time of observation first. +- **Is composition being mistaken for policy?** Optional service presence, a provider method, or a sibling tool can express availability without deciding deployment behavior. Explicit configuration or a caller-intent operation may remove registries and dependency checks. Preserve distinct operations when their ownership or completion timing differs. +- **What owns the complete maintenance cost?** Trace pass-through configuration, duplicate application trees, demo launchers used by products, resolver-only workspaces, and installation helpers with their own upgrade lifecycle. Compare the entire removed system with the replacement, including residual glue; moving complexity or adding a gate to keep duplicate definitions equal does not remove it. -Treat an invariant companion as useful only when it compares independently produced observations that can diverge. Remove empty installers and checks that merely inspect service presence, plugin metadata, fixed examples, or the result of calling the same mutation they claim to verify. For every omission, remove the export, build entry, invariant-only compiler reference or dependency, and companion-only test, then record the package-specific reason in both package READMEs. Keep a companion when it compares distinct event producers, durable history, or independently mutable data, even if the package also validates inputs synchronously. +## Prove reachability and the trade-off -## Survey Broadly +Start with `rg`, then read the matches. Search exact symbols, property reads and writes, discriminants, event and wire strings, config keys, package names, and both `.method(` and `method(` forms. Tests and declarations can show a contract without proving a shipped producer or consumer. -Use parallel subagents when the user asks for breadth or many candidates. Give each agent a domain and require evidence, not guesses. Useful domains: +Include `packages/*/*/src`, `apps/`, `python/`, runtime scripts, shipped profiles and overlays, package manifests and exports, loader resolution, generated runtime assets, and installed-package consumers. Classify examples and fixtures by their actual entry point rather than directory name. Follow generated catalogs to their consumers: a catalog used by model-written plugin mounts is a dynamic product API, while a documentation-only listing is not a fixed caller. Public third-party extension paths can be intentional despite zero repository call sites. -- Agent loop and session log: turn/step boundaries, steering, abort/cancel, durable events, replay, load/resume. -- ACP automation and human UI APIs: prompt settlement and teardown on the protocol side; transcript rendering and interaction state on the UI side. -- LLM/tools/system prompt: stream/generate APIs, assemblers, registries, tool schema defaults, presentation hooks. -- Bash and tool execution: foreground/background split, job ownership, output spill files, executor methods. -- Packages/examples/scripts/tests: package splits, static inventories, redundant snapshot expected outputs, support packages. +For each candidate, record the current owner, effective producer/consumer path, what disappears, what remains, and the strongest reason to retain it. Distinguish: -If subagents are unavailable, simulate the same breadth yourself. Do not let the first good candidate stop the survey. +- removal of unreachable or unread behavior; +- a narrower public or product behavior with an explicit loss; +- a protected obligation or insufficient evidence. -Start with the largest production-code deltas. A broad simplification audit that stops after obvious unused symbols can miss the files where duplicated lifecycle or defensive machinery carries most of the cost. +Reject a candidate when it breaks a retained obligation, merely relocates the same complexity, or has no meaningful reduction. Read rejection reasons at the level of the proposed change: a stale inventory or a mixed proposal's rejected behavior does not settle every independent item. Refresh the evidence before re-proposing one. Small local improvements belong in actionable `TODO`/`FIXME`/`XXX` comments under the [urgency rules](../../../docs/development.md), not standalone design records. -## Simplify Prose With The Code +## Preserve ownership and failure semantics -Treat comments and documentation as maintained surface area. Apply [dsh-prose-standard](../dsh-prose-standard/SKILL.md) when a survey includes prose. +For copies, freezes, validators, and callback captures, name the value's origin, next owner, and trust boundary. Typed same-process calls ordinarily borrow readonly values; parsers, config loaders, queues, model/tool JSON, durable files, workers, processes, and wire decoders own or validate their inputs. Hostile-getter or callback-replacement tests do not establish a requirement by themselves. A frozen root does not prove its descendants immutable, and equal ids do not prove object identity. -- Delete comments that restate code or explain behavior owned elsewhere; keep required local contracts. -- Keep docs at their owning level; omit implementation details and rare cases unless they change a maintained contract. +For asynchronous machinery, map each promise, flag, cancellation path, disposer, and reservation to its owner and transition. Collapse mechanisms only when they express the same fact. Preserve synchronous publication and rollback, callback containment, first-terminal-outcome arbitration, worker/process ownership, and dispose-to-quiescence where required. Durable start/end markers can record real facts even when transcript renderers ignore them; dropping interrupted work is a capability loss, not redundant-log cleanup. -## Audit Trust And Lifecycle Boundaries +An invariant companion is justified by comparing independently produced observations that can diverge. Checks of service presence, plugin metadata, fixed examples, or the same mutation's return value do not qualify. Removing a companion includes its export, build entry, invariant-only compiler references, dependencies, and tests; record the package-specific omission reason in both READMEs. Keep checks comparing independent event producers, durable history, or mutable data. -For every defensive copy, freeze, validator, and callback capture, name where the value came from and who owns it next. Same-process typed service/plugin calls ordinarily borrow readonly values; parsers, config loaders, queues, model/tool JSON, durable files, workers, processes, and wire decoders own or validate their data. Tests built around hostile getters, fake typed objects, callback replacement, or mutation after a same-process handoff are evidence of a potentially speculative contract, not automatic justification for keeping it. +## Replace infrastructure only for a net reduction -For complex asynchronous code, draw the ownership graph and map each sentinel, readiness promise, cancellation path, disposer, and state flag to a distinct owner or transition. When several mechanisms mirror the same liveness or settlement fact, propose one transaction or lifecycle controller instead. Preserve separate machinery where it protects synchronous publication and rollback, callback containment, first-terminal-outcome arbitration, worker/process ownership, or dispose-to-quiescence. +Follow the [dependency policy](../../notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.md). Search existing dependencies and Node builtins at the engine floor before adding a package. Identify the exact implementation and dedicated tests the replacement deletes, its maintenance and transitive cost, and every residual behavior the glue must preserve. -## Hand-Rolled Code Versus A Dependency +Exercise the mismatches most likely to defeat the replacement: protocol truncation, cancellation and teardown, configured bounds, deterministic test clocks, platform packaging, and source versus built entry points. A library that covers framing but requires rebuilding the same framing to enforce a size limit is not a simplification. An accepted edge-behavior change belongs in the proposal and relevant tests. Do not re-prove a dependency's generic specification while omitting tests for the harness-specific shim. -Introducing a dependency is a valid simplification move, not a policy exception: the [dependency policy](../../notes/implemented/process/2026-07-26-dependencies-over-hand-rolling.md) owns the bar. When surveying, ask of protocol parsers, framers, retry/backoff loops, glob matchers, diff engines, and similar infrastructure: does a well-maintained npm package or a Node builtin at the repo's engine floor already do this? +## Record, consolidate, and validate -Prove a dependency-swap candidate like any other, plus: +Use [dsh-prose-standard](../dsh-prose-standard/SKILL.md) when prose is in scope. Remove code-restating or remotely owned explanations while preserving local behavior, timing, ownership, and failure obligations. Update affected READMEs, JSDoc, model-visible catalogs, configuration, snapshots, and generated files with their owning change. -- Read the hand-rolled implementation and name the exact surface the package covers; residual semantics the package does not cover count against the swap and stay in the Agent Note. -- Check the package's health honestly (maintenance, adoption, transitive footprint) and prefer builtins when the engine floor has them. -- Check the Agent Note tree first: schemastery, vendored Cordis, the twin adapters, and other recorded seams are settled — a swap that collapses one needs to beat the recorded rationale, not just cite the policy. -- Weigh net deletion: implementation plus dedicated tests plus docs, minus the glue that remains. A wrapper that relocates the same complexity is not a win. +A substantial proposal uses the mandatory note skeleton: `Problem`, `Proposal`, `Alternatives considered`, `Acceptance criteria`, and `Risks`. Include concrete consumer evidence, the removed maintenance cost, the capability given up, and observable acceptance conditions. An implemented decision uses the [implemented format](../../notes/README.md#the-body-skeleton) instead. Update an existing owner when the decision is the same; do not create duplicate notes to preserve candidate counts. -## Prove Or Reject Each Candidate +Every new note requires a scoped supersession check through [dsh-archive-agent-notes](../dsh-archive-agent-notes/SKILL.md). That workflow owns retention, consolidation, triplet deletion, and frozen archive mechanics. A code survey does not imply a repository-wide note audit. Preserve partial supersessions and current durable, wire, compatibility, or rejected-alternative obligations. -For every symbol or behavior, classify consumers before writing: +When folding another branch, compare its independent diff against the target base, port only supported non-overlapping proposals, and consolidate overlapping rationale. Closing another PR requires authorization or clear ownership of that housekeeping. -- Production corpus: `packages/*/src`, `examples/*/src`, `examples/**/*.yml`, runtime scripts, and loader/config paths. -- Non-production corpus: tests, README/docs, Agent Notes, snapshots, generated expected outputs, and comments. -- Ambiguous corpus: examples and scripts that may be product smoke paths. Inspect usage before classifying. - -Use `rg` first. Good searches include the exact symbol, event name, package name, config key, method name with both `.name(` and `name(`, and any wire strings. Then read the call sites, public interfaces, dynamic event names, tests, docs, and Cordis loader paths. - -Reject or downgrade a candidate when: - -- A production caller exists and the simplification would be a feature decision rather than a cleanup. -- The API is explicitly justified by an implemented Agent Note or a hard-won defensive pattern, and the new evidence does not beat that reason. -- The removal would force unrelated churn without actually reducing the public API or required behavior. -- The idea is correct but tiny. Add a targeted TODO/FIXME/XXX instead, using the urgency semantics in [docs/development.md](../../../docs/development.md). - -## Coalesce Superseded Agent Notes - -Audit the Agent Note tree when the user asks to reduce or coalesce it, or when the simplification being implemented makes an owning note obsolete. Do not expand every code-simplification survey into a repository-wide note audit. - -Use [`dsh-archive-agent-notes`](../dsh-archive-agent-notes/SKILL.md) for retention judgment and archive mechanics. Implemented notes that only describe small UI adjustments or purely mechanical changes are deleted directly; other completed notes with historical decision value but little future guidance move as frozen triplets to `archived/{kind}`; proposed notes are never archived; rejected notes that no longer prevent a tempting mistake are deleted. Do not edit an archived note while simplifying current prose or code. - -Follow the deletion rule in the [Agent Note rules](../../notes/README.md#when-to-write-one); do not duplicate or weaken it here. For each candidate chain: - -1. Identify the current owner from shipped code, configuration, generated catalogs, package docs, newer Agent Notes, and inbound links; dates and titles are discovery hints, not proof. -2. Classify the old note as fully or partially superseded. Any surviving behavior, current contract, durable format, compatibility obligation, or independently current rejected alternative makes it partial. Rationale that can be transferred to the current owner does not by itself make supersession partial. -3. For full supersession, move every unique rationale, alternative, consequence, shipped verification evidence, and named coverage gap into the current owner. An inventory that only describes deleted implementation mechanics is not one of those decision facts. -4. Repair every inbound link, then delete the English note, Chinese counterpart, and consistency record together. -5. Search exact filenames, symbols, config keys, event names, and wire strings after the edit. Keep partial supersessions cross-linked and current. - -An added-then-removed feature is a common full-supersession case. Let the removal note own the history only when the feature is absent from production code, configuration, schemas, durable or wire formats, migration, and compatibility behavior; no current documentation presents it as available; and no test exercises it as supported behavior. Removal rationale and tests that enforce absence may remain. Preserve why the feature originally existed, why that motivation no longer justified it, alternatives to full removal, the capability given up, conditions for reintroduction, and evidence that removal is complete. Old tests and implementation mechanics that verified only the deleted behavior are not current verification evidence. - -Reject consolidation when the removal is only one transport, default, implementation, or presentation of a feature; when persisted data or compatibility handling survives; or when the removal note does not yet carry enough rationale to prevent accidental reintroduction. A current negative design decision may legitimately need its own note even though the removed implementation is gone. - -## Write The Agent Note - -Create one file per durable proposal under `.agents/notes///yyyy-mm-dd-topic.md`, following the lifecycle and classification rules in `.agents/notes/README.md`. Keep prose paragraphs on one physical line and use relative Markdown links. - -Prefer this structure, adjusting when the idea needs it: - -- `# Agent Note: ` -- `Status: proposed` -- `## Problem`: name the current API, cite the relevant files, and state the consumer evidence. Separate production callers from tests/docs. -- `## Proposal`: say exactly what to remove, fold, demote, or rehome. Include tests, docs, READMEs, JSDoc, event-taxonomy, snapshot, and generated-file cleanup when relevant. -- `## Why not keep it?` or `## What we give up`: make the strongest counterargument legible. -- `## Acceptance criteria`: observable end state and gates. -- `## Risks`: public API changes, behavior changes, future product wants, and why the tradeoff is still reasonable. - -Be concrete enough that an implementing PR can follow the trail. Avoid vague "simplify this package" Agent Notes. When a proposal overlaps an existing Agent Note, consolidate the useful details into the existing one rather than creating a duplicate. - -## Inline TODO Notes - -Use inline TODO/FIXME/XXX only for small, local cleanups that are clearly useful but not durable design decisions. Keep them short and actionable: - -- Name the smell with a stable tag, e.g. `TODO(double-default)` or `XXX(unused-default)`. -- Explain why it is safe to revisit and what action would simplify it. -- Do not add TODOs for speculative complaints or for behavior that needs an Agent Note-level decision. - -## When Folding Another PR Or Branch - -Diff the sibling branch against `origin/master`, not against the current PR branch, so you see its independent contribution. For each item: - -- Port non-overlapping Agent Notes or TODOs that meet the quality bar. -- Consolidate overlapping material into the existing Agent Note that owns the topic. -- Do not port duplicate or lower-confidence proposals just to preserve the count. -- Update the PR body so reviewers see the true candidate count and scope. -- Close the duplicate PR only when the user asked you to, or when you clearly own that housekeeping. - -## Validation And PR Hygiene - -For docs-only Agent Note work, run at least `pnpm run doc-sync`, `pnpm run lint`, and `git diff --check`. For code comments or skill changes, also run the relevant validator when one exists. Select any other evidence from the outgoing diff; the pre-push hook contributes typecheck only. - -When opening or updating a PR, summarize: - -- How many Agent Notes and inline notes were added, consolidated, retained as partial supersessions, or deleted. -- The main areas surveyed. -- What was intentionally excluded. -- Which checks passed. - -For each consolidation group, name the old and current owners, state the evidence for full supersession, and explain why deletion is safe. If an added-then-removed scan finds no qualifying note, report that result and the representative partial cases retained. - -Use a draft PR while the survey is still expanding; mark ready only when the candidate set, review responses, and validation are settled. +For docs-only Agent Note work, run `pnpm run doc-sync`, `pnpm run lint`, and `git diff --check`; for skill or comment edits, include the applicable validator. Select other checks through [dsh-pre-push-checks](../dsh-pre-push-checks/SKILL.md). Report the surveyed areas, supported candidates, meaningful rejections or deferrals, notes added/consolidated/retained/removed, and commands actually run. Use a draft PR while the survey is expanding; do not describe an unverified search as exhaustive. diff --git a/.agents/skills/dsh-find-simplifications/references/historical-patterns.md b/.agents/skills/dsh-find-simplifications/references/historical-patterns.md new file mode 100644 index 0000000000..f5f91342e4 --- /dev/null +++ b/.agents/skills/dsh-find-simplifications/references/historical-patterns.md @@ -0,0 +1,45 @@ +# Historical simplification patterns + +Use these examples to calibrate a candidate whose value is not established by an unused-symbol search. They describe recorded decisions, not current removal opportunities. Archived sources are frozen snapshots: read the cited note itself, never follow or repair its outbound links. Verify current owners and released-data obligations before applying a pattern. + +## Require a complete effect path + +A declaration, serializer branch, and test can form convincing-looking support without an effective feature. Trace both ends: something must produce the value, and an implementation must honor it. The [producerless-variants decision](../../../notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md) removed reserved union members and cache hints without emitters. The [inert-request-knobs decision](../../../notes/archived/simplification/2026-07-04-drop-inert-request-knobs.md) distinguished knobs rejected by every adapter from working request fields available to hooks. Deletion included declarations, forwarding, rejection-only tests, and generated documentation. + +Zero fixed callers is weaker evidence than unreachability. The [skill-registration rejection](../../../notes/rejected/simplification/2026-07-12-prune-unused-skill-registry-api.md) preserves a deliberate third-party registration path. For catalogued services, inspect generic plugin invocation and returned values before calling them dead. A working extension point and a field no provider can honor require different verdicts. + +## Reduce distinctions where consumers decide + +Map every public variant to the consumer action it enables. The [model agent-availability decision](../../../notes/implemented/simplification/2026-09-15-model-agent-availability-and-team-targets.md) gives models one usable Team target and projects multiple residency states to the same availability, while internal routing retains Session identity and residency. The [capability-neutral sandbox context](../../../notes/archived/simplification/2026-07-31-capability-neutral-sandbox-policy-context.md) replaces two approximate capability registries with truthful conditional policy wording; exact tool availability remains in tool schemas. The gain includes registration methods, disposal state, invalidation, and combination tests. + +Do not erase distinct durable facts merely because one renderer ignores them. The [durable step-boundary rejection](../../../notes/rejected/simplification/2026-06-20-drop-durable-step-boundaries.md) retains explicit start and completion facts needed for empty failed steps, crash repair, and inspection. Simplify the projection only when the underlying distinction remains necessary. + +## Trade general behavior for a smaller explicit promise + +A used feature can still be an expensive way to satisfy the required outcome. The [fixed-rate Schedule decision](../../../notes/archived/simplification/2026-08-09-bounded-fixed-rate-schedule.md) gives up calendar recurrence and missed-occurrence replay, removing a parser, evaluator, cross-record gate, durable variants, and backlog states. The [non-transactional Loader decision](../../../notes/implemented/simplification/2026-09-09-nontransactional-loader.md) gives up automatic plugin rollback while keeping failure reporting and consumer-owned activation checks. Moving generic rollback to another package would retain its cost. + +State the loss as clearly as the deletion. The [interrupted-turn truncation rejection](../../../notes/rejected/simplification/2026-06-20-truncate-interrupted-turns.md) rejects a simpler recovery algorithm because an unfinished turn can contain substantial real work. Convenience, smaller unions, or fewer tests alone do not justify losing required data or behavior. A survey can propose the trade-off without implying permission to implement it. + +## Make assumptions explicit at their consuming operation + +Look for a local default that has acquired shared storage, synchronization, or confirmation machinery. The [explicit Schedule time-zone decision](../../../notes/implemented/simplification/2026-08-09-explicit-schedule-time-zone.md) keeps browser facts on the originating request and requires an explicit zone in the scheduling operation, removing Session defaults and cross-tab conflict state. The [injected-content decision](../../../notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.md) leaves framing with the caller and removes envelope controls threaded through unrelated layers. Both reduce the number of owners that must interpret one assumption. + +Do not move a requirement past the place that must enforce it. The [Host-only Remote input-validation decision](../../../notes/implemented/simplification/2026-09-15-host-only-remote-input-validation.md) removes duplicate Client schema execution but retains Host validation before lookup and business invocation, plus local arity and Context binding checks. Its documented cost is later malformed-input failure and the loss of Client parsing as accidental redaction. + +## Derive at use or reuse an existing delivery owner + +For each cache or event subscription, ask when the consumer needs the value and whether an authoritative source already retains it. [Feedback telemetry](../../../notes/archived/simplification/2026-08-06-buffer-free-feedback-telemetry.md) reads the canonical Session prefix at feedback time, deleting a continuously copied pre-feedback buffer and its listeners. [Workspace recency](../../../notes/implemented/simplification/2026-09-10-derived-workspace-recency.md) sorts current summaries instead of persisting promotion history; manual ordering remains independent user state. [Web subagent projections](../../../notes/implemented/simplification/2026-09-08-web-subagent-catalog-projections.md) reuse a shared stream and projection store, removing feature notifications, repeated reads, and a second membership cache. + +The timing promise determines whether this works. Feedback-time redaction differs from capture-time redaction; manual placement cannot be derived from activity timestamps; an initial historical read may remain necessary when a stream baseline is absent. Name such residual obligations instead of declaring all caches redundant. + +## Remove accidental composition owners + +Inspect actual launch and resolution paths before trusting names such as demo, support, or example. The [shared-base-config decision](../../../notes/archived/simplification/2026-07-29-shared-base-config-overlays.md) removes duplicate compositions and pass-through settings; actual Loader behavior determines overlay placement. The [owner-local profiles and guides decision](../../../notes/archived/simplification/2026-08-24-owner-local-profile-tests-and-guides.md) removes a resolver-only workspace by assigning tests, guides, and shipped assets to their owners. The [merged subagent service decision](../../../notes/archived/simplification/2026-07-26-merge-subagent-control-service.md) uses explicit deployment policy instead of inferring it from provider or sibling-tool presence, while preserving optional dependencies internally. + +A smaller package count is not sufficient. Separate caller intents may have different ownership and completion timing; a retained Service Definition may serve independent providers. Prove the replacement's real composition and dependency behavior, and account for all remaining configuration and lifecycle glue. + +## Use rejected experiments to test parity claims + +The [SSE parser replacement](../../../notes/archived/simplification/2026-07-26-eventsource-parser-for-deepseek-sse.md) deletes generic framing and its conformance tests while retaining the provider-specific termination shim and documenting stricter truncated-tail behavior. In contrast, the [timer-promises rejection](../../../notes/rejected/simplification/2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.md) records that a nominally equivalent builtin defeated deterministic fake-clock tests for a small deletion. The [dependency-swap audit](../../../notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.md) distinguishes replaceable generic code from configured bounds, security rules, lifecycle ownership, and deployment behavior a library does not implement. + +A past rejection is a scoped falsifier, not a permanent package blacklist. Revisit it only with new evidence addressing the failed premise, and measure the implementation, glue, tests, dependencies, and supported behavior together.