Merge remote-tracking branch 'origin/master' into nih-imp-execa

# Conflicts:
#	.agents/notes/rejected/simplification/2026-07-26-dependency-swaps-rejected-by-nih-audit.i18n.yaml
#	apps/web/tests/scaffold.ts
#	packages/session-persistence/session-checkpoint-policy/tests/crash-recovery.e2e.ts
#	packages/support/acp-snapshot/README.i18n.yaml
This commit is contained in:
Tianyi Cui
2026-07-27 06:31:17 +08:00
665 changed files with 11055 additions and 7377 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-06-11-api-extractor-reports.md: f110bfe3353e65442f218336aca3e9d492ac2341
2026-06-11-api-extractor-reports.zh.md: 8cb7353e10a8811b20ccd539de15f8e06b76e6ae
2026-06-11-api-extractor-reports.md: 03f512992fe87ea3d0f8d51a1772ce1ec89a5c0d
2026-06-11-api-extractor-reports.zh.md: a8180124c5e5402dce3c28c1bd8c54219d5b68fc

View File

@@ -4,7 +4,7 @@ Status: proposed
English | [中文](2026-06-11-api-extractor-reports.zh.md)
> Split out from the original "Doc-sync and API reports" Agent Note (2026-06-11). Parts 1-2 (doc-block typechecking, event-taxonomy verification) shipped — see [doc-sync enforcement](../../implemented/process/2026-06-11-doc-sync-enforcement.md). This is the deferred part 3, kept as a standalone proposal.
> Split out from the original "Doc-sync and API reports" Agent Note (2026-06-11). Parts 1-2 (doc-block typechecking, event-taxonomy verification) shipped — see [doc-sync enforcement](../../archived/process/2026-06-11-doc-sync-enforcement.md). This is the deferred part 3, kept as a standalone proposal.
## Problem

View File

@@ -4,7 +4,7 @@ Status: proposed
[English](2026-06-11-api-extractor-reports.md) | 中文
> 从最初的「doc-sync(文档同步门禁)与 API 报告」Agent Note(agent 决策记录)中拆出(首次提出于 2026-06-11)。第 1 至第 2 部分(文档块类型检查、事件分类体系校验)已交付,见 [doc-sync 强制](../../implemented/process/2026-06-11-doc-sync-enforcement.md)。本文是被推迟的第 3 部分,作为独立提案保留。
> 从最初的「doc-sync(文档同步门禁)与 API 报告」Agent Note(agent 决策记录)中拆出(首次提出于 2026-06-11)。第 1 至第 2 部分(文档块类型检查、事件分类体系校验)已交付,见 [doc-sync 强制](../../archived/process/2026-06-11-doc-sync-enforcement.md)。本文是被推迟的第 3 部分,作为独立提案保留。
## 问题

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.md: 1a012aeabc7f9445127d6b8edcbe2f72e62f0eba
2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.zh.md: 742d2c5ee8573c9b2bdf555c938c83dd6ea9f999
2026-07-26-remove-packed-session-fixture-migrator.md: 0a29ef98828ac07d291392d637b0508937c9a9a6
2026-07-26-remove-packed-session-fixture-migrator.zh.md: 64b994855a7e92d5b0922884b6c66df1b82b6d90

View File

@@ -0,0 +1,38 @@
# Agent Note: Remove the packed-session fixture branch migrator
Status: proposed
English | [中文](2026-07-26-remove-packed-session-fixture-migrator.zh.md)
## Problem
The repository's default writers and snapshot check keep session fixtures in the canonical packed-row layout. `pnpm run migrate:packed-session-fixtures` remains alongside that permanent enforcement only so in-flight branches carrying older fixture edits can merge current `master` and mechanically converge without re-recording model output.
Once every such branch is merged, closed, or already canonical, the write command and its branch-convergence instructions have no continuing owner. Keeping a mutation command after its transition ends adds a second apparent maintenance path beside the permanent read-only snapshot check.
## Proposal
Remove the temporary `scripts/migrate-packed-session-fixtures.ts` CLI and the root `migrate:packed-session-fixtures` package command after a live inventory confirms that no open pull request still needs to convert session-format JSONL. Remove the transitional command links from the testing policy, the ACP snapshot README, and the implemented packed-row Agent Note in the same change; replace the command-specific remediation text in `scripts/session-fixture-layout.snapshot.ts` with command-independent canonical-layout guidance.
Retain `scripts/session-fixture-layout.ts`, its unit tests, and `scripts/session-fixture-layout.snapshot.ts`. They define and enforce the permanent canonical layout; only the branch-facing writer is temporary.
Before removing the command, each affected branch merges the current `master`, runs the migrator once, commits the resulting fixture-only rewrite separately, and verifies that the repository-wide snapshot layout check passes. Closed or superseded branches require no migration.
## Alternatives considered
**Keep the command indefinitely.** This makes old fixture conversion convenient, but it leaves a repository-wide mutation tool after the only known migration window closes. The read-only gate already supplies the durable behavior and diagnostic.
**Remove the canonicalization module with the CLI.** The module is not transition residue: snapshot CI uses it to discover future fixtures, decode mixed physical records, and compare them with the canonical packed representation. Removing it would also remove enforcement.
**Delete the command immediately when packed rows reach `master`.** Older open branches would then need ad hoc scripts or manual snapshot regeneration after retargeting, increasing conflict risk and making decoded-event preservation harder to review.
## Acceptance criteria
- A live open-PR inventory finds no branch with session-format JSONL changes that still depends on the temporary migration command.
- The temporary CLI, root package command, every branch-convergence link, and the command-specific gate diagnostic are absent; the permanent canonicalizer, unit tests, and snapshot check remain.
- `pnpm run test:snapshot`, `pnpm run doc-sync`, lint, and whitespace validation pass without the temporary command.
- Current documentation describes only the packed default and permanent canonical-layout enforcement.
## Risks
An incomplete open-branch inventory could strand a contributor with a large unpacked fixture conflict after the command disappears. The removal therefore depends on live pull-request evidence, not elapsed time. Retaining the command too long has a smaller operational cost but obscures which mechanism is permanent.

View File

@@ -0,0 +1,38 @@
# Agent Note: 移除打包会话 fixture 分支迁移器
Status: proposed
[English](2026-07-26-remove-packed-session-fixture-migrator.md) | 中文
## 问题
仓库的默认写入器和快照检查会使会话 fixture(测试前置数据)保持规范打包行布局。在永久强制机制之外仍保留 `pnpm run migrate:packed-session-fixtures`,唯一原因是让携带旧版 fixture 改动的在途分支可以合并当前 `master`,并在不重新录制模型输出的情况下通过机械转换收敛。
一旦每个此类分支均已合并、关闭或符合规范,写入命令及其分支收敛指引便不再有持续维护者。过渡结束后继续保留会修改仓库内容的命令,会在永久只读快照检查旁增加第二条看似有效的维护路径。
## 提案
最新清单确认不再有任何开放 PR(Pull Request)需要转换会话格式 JSONL 后,移除临时 CLI `scripts/migrate-packed-session-fixtures.ts`,以及根包(package)提供的 `migrate:packed-session-fixtures` 命令。在同一变更中,移除测试政策、ACP 快照 README 和已实现打包行 Agent Note(agent 决策记录)中指向该过渡命令的链接,并将 `scripts/session-fixture-layout.snapshot.ts` 中仅适用于该命令的修复指引替换为与具体命令无关的规范布局指引。
保留 `scripts/session-fixture-layout.ts`、其单元测试和 `scripts/session-fixture-layout.snapshot.ts`。它们定义并强制执行永久规范布局;只有面向分支的写入器是临时机制。
移除命令前,每个受影响分支都要合并当前 `master`,运行一次迁移器,单独提交由此产生的仅 fixture 重写,并验证仓库级快照布局检查通过。已关闭或被取代的分支无需迁移。
## 曾考虑的替代方案
**无限期保留该命令。** 这会让旧 fixture 转换更方便,但也会在唯一已知迁移窗口关闭后,留下一个仓库级写入工具。只读门禁已经提供可长期保留的行为与诊断。
**随 CLI 一同移除规范布局转换模块。** 该模块不是过渡残留:快照 CI 使用它发现未来 fixture、解码混合物理记录,并与规范打包表示进行比较。移除该模块也会移除强制机制。
**打包行进入 `master` 后立即删除命令。** 较旧的开放分支在重新定向后,只能使用临时脚本或手动重新生成快照,这会增加冲突风险,也会让解码事件保真度更难评审。
## 验收标准
- 最新开放 PR 清单未发现任何仍依赖临时迁移命令处理会话格式 JSONL 改动的分支。
- 临时 CLI、根包命令、所有分支收敛链接与仅适用于该命令的门禁诊断均不存在;永久规范布局转换器、单元测试和快照检查仍然保留。
- `pnpm run test:snapshot`、`pnpm run doc-sync`、lint 和空白校验在没有临时命令的情况下通过。
- 当前文档仅描述打包默认值和永久规范布局强制机制。
## 风险
若开放分支清单不完整,命令消失后,贡献者可能会受困于大规模非打包 fixture 冲突。因此,移除操作取决于实时 PR 证据,而不是经过的时间。保留命令过久的运维成本较低,但会模糊哪一种机制才是永久机制。

View File

@@ -1,37 +0,0 @@
# Agent Note: Use node:timers/promises for hand-rolled cancellable sleeps
Status: proposed
English | [中文](2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.zh.md)
## Problem
Three packages hand-roll promise-wrapped timers that the `node:timers/promises` builtin already provides, while other packages (`dsh-llm-mock-server` `pause()`, `dsh-lsp-local`, `dsh-acp-snapshot`) already use the builtin — so the hand-rolled copies are also a consistency gap:
- `packages/llm/llm-retry/src/index.ts` `cancellableDelay()` (~14 lines): `new Promise` + `setTimeout` + manual abort-listener add/remove, resolving `true` on elapse and `false` on abort, consumed once for the backoff wait.
- `packages/workflow/workflow-workerthread/src/host.ts` `sleep()` (~7 lines): promise-wrapped unref'd `setTimeout` used as the dispose-grace bound.
- `packages/pty/pty-local/src/session.ts` `delay()` (~4 lines): bare promise-wrapped `setTimeout` used in polling/teardown waits.
## Proposal
Replace all three with `import { setTimeout } from 'node:timers/promises'`:
- llm-retry: `try { await setTimeout(delayMs, undefined, { signal }); /* retry */ } catch { /* abort → fail */ }` — with a signal, the promise rejects only with the abort error, and a pre-aborted signal rejects immediately; behavior is identical, including timer clearing on abort. The empty `catch` names the abort rejection per the repo's empty-catch rule.
- workflow-workerthread: `setTimeout(ms, undefined, { ref: false })` — exact semantics including not holding the event loop open.
- pty-local: `import { setTimeout as delay } from 'node:timers/promises'` — identical signature, call sites unchanged.
No dedicated tests pin the helpers themselves; the packages' behavior suites keep passing.
## Alternatives considered
- **`p-timeout`/`p-defer` style packages.** Rejected: the builtin covers both call sites exactly; an external package for a one-line await is negative-net.
- **Leave them.** Rejected only weakly — the cost is small, but the repo already uses the builtin idiom elsewhere, and two hand-rolled variants of a builtin invite a third.
## Acceptance criteria
- None of the three packages defines a promise-wrapped `setTimeout` helper; all import from `node:timers/promises`.
- The `llm-retry`, `workflow-workerthread`, and `pty-local` test suites pass unchanged (behavioral parity).
## Risks
Essentially none: no model-visible output, no platform concerns, no new dependency. The llm-retry rewrite changes a boolean-returning helper into try/catch control flow — a local readability judgment the implementing PR makes.

View File

@@ -1,37 +0,0 @@
# Agent Note: 用 node:timers/promises 替代手写的可取消休眠
Status: proposed
[English](2026-07-26-builtin-timer-promises-for-hand-rolled-sleeps.md) | 中文
## 问题
三个包(package)手写了 promise 包装的定时器,而 `node:timers/promises` 内置模块早已提供同等能力;其他包(`dsh-llm-mock-server` 的 `pause()`、`dsh-lsp-local`、`dsh-acp-snapshot`)已经在使用该内置模块,因此这些手写副本同时也是一处一致性缺口:
- `packages/llm/llm-retry/src/index.ts` 的 `cancellableDelay()`(约 14 行):`new Promise` + `setTimeout` + 手动添加/移除 abort 监听器,计时走完时 resolve 为 `true`、被中止时 resolve 为 `false`,仅在退避等待处消费一次。
- `packages/workflow/workflow-workerthread/src/host.ts` 的 `sleep()`(约 7 行):promise 包装、已 unref 的 `setTimeout`,用作 dispose(资源释放)宽限的时间上界。
- `packages/pty/pty-local/src/session.ts` 的 `delay()`(约 4 行):朴素的 promise 包装 `setTimeout`,用于轮询与拆除等待。
## 提案
用 `import { setTimeout } from 'node:timers/promises'` 替换这三处实现:
- llm-retry:`try { await setTimeout(delayMs, undefined, { signal }); /* retry */ } catch { /* abort → fail */ }`。传入 signal 后,该 promise 只会以 abort 错误拒绝,已提前中止的 signal 则立即拒绝;行为完全一致,包括中止时清除定时器。按仓库的空 catch 规则,这个空 `catch` 注明其吞下的是 abort 拒绝。
- workflow-workerthread:`setTimeout(ms, undefined, { ref: false })`,语义完全等价,包括不会让事件循环保持存活。
- pty-local:`import { setTimeout as delay } from 'node:timers/promises'`,签名完全相同,调用点无需改动。
没有专属测试固定这些辅助函数本身;各包的行为测试套件继续通过。
## 曾考虑的替代方案
- **`p-timeout`/`p-defer` 一类的包。** 不予采纳:内置模块恰好精确覆盖这些调用点;为一行 await 引入外部包是负收益。
- **维持现状。** 不予采纳,但理由较弱:成本确实很小,但仓库其他地方已经在用这一内置惯用法,而同一内置能力存在两个手写变体,就会招来第三个。
## 验收标准
- 这三个包都不再各自定义 promise 包装的 `setTimeout` 辅助函数,而是都从 `node:timers/promises` 导入。
- `llm-retry`、`workflow-workerthread` 与 `pty-local` 的测试套件原样通过(行为等价)。
## 风险
基本没有风险:不涉及模型可见的输出,没有平台顾虑,也不新增依赖。llm-retry 的改写把一个返回布尔值的辅助函数变成 try/catch 控制流,这是一项局部可读性判断,由实施 PR(Pull Request)裁量。

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-26-consolidate-gate-scripts-on-existing-deps.md: 2b6c2f80b4fc3d3bf818b6789b5f40bb7a61b654
2026-07-26-consolidate-gate-scripts-on-existing-deps.zh.md: b20a5bd9ba1661321721c0c9d62de8dc63ec645b
2026-07-26-consolidate-gate-scripts-on-existing-deps.md: 0bf32e01ea407e2718f8ec39ca962587a37df9cc
2026-07-26-consolidate-gate-scripts-on-existing-deps.zh.md: ba9f157a61ffdc415acf9b2a61857026fc2c8bf1

View File

@@ -35,4 +35,4 @@ No new dependency is needed anywhere; every replacement is an existing devDep or
## Risks
- Behavioral deltas on pathological markdown: mdast honors tilde/indented fences the regex scanners ignored, so `doc-typecheck`'s opt-out ratio could shift if any stray fence shape exists in the docs tree; verify by running `doc-sync` before/after.
- `parseArgs` keeps the last value of a duplicated option instead of erroring and consumes a `--`-prefixed next token as a value; both are dev-tool edge cases the tests don't pin.
- `parseArgs` keeps the last value of a duplicated option instead of erroring — a dev-tool edge case the tests don't pin. (Strict mode still rejects a `--`-prefixed token where a value is expected, matching the current parsers.)

View File

@@ -35,4 +35,4 @@ Status: proposed
## 风险
- 病态 markdown 上的行为差异:mdast 会承认正则扫描器忽略的波浪线围栏和缩进围栏,因此如果文档树中存在任何零散的此类围栏形态,`doc-typecheck` 的 opt-out 比例可能变化;应在改动前后分别运行 `doc-sync` 加以验证。
- `parseArgs` 对重复出现的选项保留最后一个值而不报错,还会把下一个以 `--` 开头的 token 当作值消费;这两种情况都是测试未固定的开发工具边缘用例。
- `parseArgs` 对重复出现的选项保留最后一个值而不报错——一个测试未固定的开发工具边缘用例。(严格模式下,需要取值处遇到以 `--` 开头的 token 仍会拒绝,与现有解析器行为一致。)