universal-dev-standards 6.10.0 → 6.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/bin/uds.js +2 -0
  2. package/bundled/ai/standards/open-work-tracking.ai.yaml +216 -0
  3. package/bundled/core/open-work-tracking.md +333 -0
  4. package/bundled/locales/zh-CN/CHANGELOG.md +29 -3
  5. package/bundled/locales/zh-CN/CLAUDE.md +1 -1
  6. package/bundled/locales/zh-CN/README.md +2 -2
  7. package/bundled/locales/zh-CN/SECURITY.md +1 -1
  8. package/bundled/locales/zh-CN/docs/CHEATSHEET.md +2 -1
  9. package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +52 -5
  10. package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +6 -3
  11. package/bundled/locales/zh-TW/CHANGELOG.md +29 -3
  12. package/bundled/locales/zh-TW/CLAUDE.md +1 -1
  13. package/bundled/locales/zh-TW/README.md +2 -2
  14. package/bundled/locales/zh-TW/SECURITY.md +1 -1
  15. package/bundled/locales/zh-TW/core/open-work-tracking.md +255 -0
  16. package/bundled/locales/zh-TW/docs/CHEATSHEET.md +2 -1
  17. package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +52 -5
  18. package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +6 -3
  19. package/bundled/locales/zh-TW/integrations/claude-code/README.md +14 -5
  20. package/package.json +1 -1
  21. package/src/commands/check.js +253 -21
  22. package/src/commands/config.js +15 -9
  23. package/src/commands/init.js +24 -3
  24. package/src/commands/update.js +311 -47
  25. package/src/core/manifest.js +39 -1
  26. package/src/flows/init-flow.js +9 -1
  27. package/src/generators/layered-claudemd.js +13 -4
  28. package/src/i18n/messages.js +3 -3
  29. package/src/installers/integration-installer.js +13 -6
  30. package/src/installers/manifest-installer.js +4 -0
  31. package/src/reconciler/actual-state-scanner.js +29 -2
  32. package/src/reconciler/desired-state-calculator.js +51 -2
  33. package/src/reconciler/diff-engine.js +19 -3
  34. package/src/reconciler/plan-executor.js +17 -16
  35. package/src/utils/hasher.js +61 -5
  36. package/src/utils/integration-generator.js +239 -28
  37. package/src/utils/marker-locator.js +140 -0
  38. package/src/utils/reference-sync.js +53 -1
  39. package/standards-registry.json +19 -7
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  source: ../../CHANGELOG.md
3
- source_version: 6.10.0
4
- translation_version: 6.10.0
5
- last_synced: 2026-09-16
3
+ source_version: 6.12.0
4
+ translation_version: 6.12.0
5
+ last_synced: 2026-09-24
6
6
  status: current
7
7
  ---
8
8
 
@@ -17,6 +17,32 @@ status: current
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [6.12.0] - 2026-09-25
21
+
22
+ ### 新增
23
+
24
+ - **新标准 `open-work-tracking`——`deferred-item-exit` 的下游一半。** `deferred-item-exit` 要求被推迟的条目离开原文件、走向可追溯的出口,但刻意不规定出口的承载处;条目进入承载处之后,没有任何规则防止承载处本身腐坏。本标准以 16 条要求(OWT-001~016)补上:低摩擦的记录点(必填字段至多两个)、每个等待中的条目旁写明解除条件、可推导的字段由生成而非手写、以内容证明"最新"而非可随手改的时间戳、覆盖率数字要写出它看不到什么,以及每轮结束时报告未完成工作但**从不阻挡**的检查点。最后一点刻意与挂在同一事件、会阻挡的 `turn-completion-integrity` 相反;标准内附对照表,避免采用者把两者接成同一件事。其中两个数字门槛标明为初始判断、非测量结果。
25
+
26
+ ## [6.11.0] - 2026-09-18
27
+
28
+ ### 修复
29
+
30
+ - **`uds update --plan`/`--apply` 对整合文件永远不会收敛:即使刚跑完 `--apply`、文件内容与生成器会生成的内容逐字节相同,仍会显示 `Migrate Block: N`。** `diffIntegrations` 对任何带有 UDS 标记的整合文件都无条件产生 `migrate_block` 动作——"我们一律更新整合文件,因为内容是动态生成的"——因为 desired state 从未带有可比对的哈希(`hash: null`,注释说"生成后才计算",但从未真正算过)。desired-state calculator 现在会用 `--apply` 自己会用的同一条路径(`buildToolIntegrationConfig` + `generateIntegrationContent`)生成整合文件内容,并只对 UDS 区块算哈希,让 `diffIntegrations` 能像其他每个类别一样分辨"内容已经相符"与"内容不同",哈希相符时报告 `unchanged` 而非 `migrate_block`。一份区块真的过期的文件(手动编辑过,或由旧版 CLI 生成)仍会照旧产生 `migrate_block`。生成失败(例如 registry 解不出某个工具)时回退为修正前的无条件行为,不会让计划崩溃。
31
+ - **`uds check` 可能在同一次运行里对同一个整合文件打印两条互相矛盾的"已引用"宣告。** `standardsReferenced`("已引用 {count}/{total} 项标准")扫描整个整合文件正文——标准名称在任何地方被提到都算。`standardsNotReferenced`("未引用的标准(可选):")只看结构化的 `Reference:`/`参考:` 行。一个标准在文件散文中被提到、却没有列在任何 `Reference:` 行上,会在同一次运行里同时满足第一条宣告、又落在第二条宣告里——同一个词("已引用"/"引用"),量测的是两件不同的事,读起来像矛盾。三语的第二条消息都已改写成精确描述它实际检查的内容(没有出现在 `Reference:`/`参考:` 行),取代原本笼统的"未引用"宣告。
32
+ - **单纯的 `uds update --plan` 与 `uds check` 从未提示 Skills 或 Commands 版本落后最新 UDS 发行版。** 版本落后只由 `uds update --plan --skills`/`--plan --commands` 计算——一般的协调 `--plan`(不带范围标志)调用的是另一个从未触及这件事的函数,`uds check` 则完全没有对等的检查。用户跑纯粹的 `--plan` 或 `check` 时,看到的是一份干净的报告,尽管 Skills 落后了一整个小版本,也没有任何提示说带范围的 plan、或 `uds update --skills` 有事可做。两者现在都会在任何已安装的 Skills 或 Commands 版本落后时,打印简短的"`<工具>`(`<位置>`):v旧 → v新"提示,并附上修复命令。这比照既有的顶层"Version: X → Y ⚠"行,而非整合区块完整性检查(XSPEC-418 R1):落后最新版是用户更新前的常态,不是像 UDS 区块被修改/丢失那样的合规缺陷,因此不会让 `uds check --ci` 失败。
33
+ - **6.10.0 的死链接修正(P2)把一条写着 6.0.0 之前文件名的引用直接删掉,而不是改写它,还可能留下一个悬空的逗号。** `resolveStandardReferences` 比对一行 `Reference:` 的 stem 时只查 manifest 已安装清单,从未查过 `STANDARD_ID_MAPPING`(conversion-rules.js)——这正是 `yaml-generator.js` 别处已在用、记录"旧文件名 → 现行 id"的对照表。一行写着旧文件名 `.standards/commit-message-guide.md` 而项目其实装了 `commit-message` 的引用,看起来和一个项目刻意不装、已停用的 UDS 标准一模一样,于是被整行删掉,而不是改写成 `.standards/commit-message.ai.yaml`。另外,删掉一项引用后的逗号清理只处理了尾部逗号、重复逗号、逗号前多余空格,没处理"一行里第一项引用被删掉、逗号紧贴在冒号后面"的状况(`Reference:, .standards/other.ai.yaml`)。整段改写为"拆项 → 解析或舍弃 → 重新 join",取代在原地修补被删字符串周围标点的做法。
34
+ - **被 6.10.0 `resolveStandardReferences` 缺陷删掉的主要标准引用,即使套用上面的修正也不会自己回来。** 把删除动作留下的悬空逗号清掉,修好的只是那一行的标点,不是把被删掉的项目带回来——像"## 提交讯息标准"这样的 UDS 模板段落活在 UDS 标记之外,一旦某一项被删掉,就没有任何东西会重新生成那段内容。针对这个特定情境新增一个范围刻意收窄的自动修复机制:当一行的标题与某个 UDS 模板标题完全相同(`RULE_TEMPLATES` 出货的任一语言版本),而且该模板的主要引用(它自己"`Reference:`"/"`參考:`"行上的第一个 `.standards/...` 项)不在文件那一行里,且该标准确实已安装,就会把它补回该行最前面——行内其他内容(项目自有条目、options 文件、既有顺序)原样不动,不会补回任何次要模板条目,用户自己写的段落(任何其他标题)一律不碰。此修复是幂等的。只修复 6.10.0 那次删除造成的问题,不尝试修复由无关手动编辑造成的引用损坏。
35
+ - **单纯的 `uds update` 从未修复上面 Q1 缺陷留下的坏掉的 `integrationConfigs[file].categories`——只有 `--sync-refs` 会。** 一份已经带着 `categories: []`(来自较旧、有缺陷的 `--sync-refs` 运行)的 manifest,会在之后每一次单纯的 `uds update --yes` 都维持坏掉:该命令自己的整合同步步骤会写 `integrationBlockHashes`,却完全不会读取 `integrationConfigs`,所以没有任何东西修正它——而下一次 `uds check --restore-missing` 就会用那份坏掉的存储配置重建整合文件,再次悄悄漏掉段落。`uds update` 现在会用 `--sync-refs` 同样的方式(`calculateCategoriesFromStandards`)修复空的或无法识别的 `categories` 值,而已经有效的列表维持原样不动,让单纯的 update 不会每次都变成完整的重新同步。
36
+ - **`uds update --sync-refs`/`--integrations-only`/`uds check --migrate`/`uds config` 可能悄悄把 `manifest.version` 降级,同一条同步路径还会在一份正常的 3.4.0 manifest 上算出空的分类集合。** 五个写入点写死了一个较旧的 schema 版本字面值(`'3.1.0'`/`'3.2.0'`/`'3.3.0'`),而不是 CLI 当前的 schema 版本(`3.4.0`)——对一份已经是最新版的 manifest 执行上述任一命令,都会把版本写回旧的。另外,`calculateCategoriesFromStandards`(`--sync-refs` 用来决定 CLAUDE.md/AGENTS.md 该含哪些段落的函数)用文件名查每个标准,但 3.4.0 manifest 存的是纯 stem(`commit-message`,而非 `commit-message.ai.yaml`)——每次查询都落空,分类集合变成空的,下一次 `--sync-refs`(或 `--restore-missing` 重建)就会重新生成一份完全漏掉反幻觉/commit-message/code-review 段落的文件。两者现在都在同一个真实来源处修复:一个共用的 `bumpManifestVersion` 辅助函数,只会让 manifest 版本朝最新前进,不会倒退;以及同文件里别处已在用、支持 stem 的分类查找(`categoryForStandard`)。这让分类计算恢复成 `--sync-refs` 在 6.10.0 之前的算法——依实际已安装的标准计算,而非固定列表——所以完整重新生成(`--sync-refs`、`--integrations-only`,或单纯的 `uds update`)现在会写出每一个有模板、且背后有已安装标准的段落(目前 9 段),而不只是全新 `uds init` 播种的那 3 段;对一个已经有完整段落的项目做纯区块更新则不受影响。
37
+ - **一句单纯提到 UDS 标记文字的句子,可能被误认成真正的区块边界,导致从那句话到真正 END 标记之间的所有内容——包含采用者自己的内容——都被删除(v3.5.0–6.10.0)。** 每一个定位标记的调用点都直接用 `content.indexOf('<!-- UDS:STANDARDS:START -->')`/`.indexOf('...:END -->')`,这会匹配到文件中任何位置出现的标记文字:一句逐字引用标记语法来解释它的句子(本项目自己的 CLAUDE.md 就是这样做),或代码区块里含有它的示例,都和真正的边界无从分辨。这影响了所有四条会重新生成整合文件 UDS 区块的写入路径:`uds update --integrations-only`、`uds update --apply` 的 `migrate_block` reconciler 路径、`uds update --sync-refs`,以及 `uds check --restore`(XSPEC-418 R6 让它也会恢复受损的 UDS 区块)。标记现在只在(去除首尾空白后)独占一整行、且那一行不在 fenced code block(``` / ~~~)内时才算数;所有调用点现在都经过同一个共用的 `locateMarkerBlock` 辅助函数,并以静态扫描守卫测试强制执行,避免未来的调用点又退回直接用 `indexOf`/`includes`。含有两组真正标记对的文件(损坏,或手动编辑出错)不再被猜测——每条写入路径都会拒绝执行并列出两个标记所在行号,`uds check` 也会明确报告这个状态,不再并入"已修改"或"找不到标记"。
38
+ - **`uds check --ci` 可能画面上打印整合区块的 ✗,结尾却仍宣称项目符合标准并以退出码 0 收尾。** `checkIntegrationBlocksIntegrity` 的检查结果(区块被修改/丢失/UDS 标记被移除)算出来也打印出来了,却在最终判定被丢弃——判定只看标准文件完整性。若你的 CI 一直对某个 CLAUDE.md/GEMINI.md 等文件的 UDS 区块实际上已被移除或改动的项目显示绿灯,那就是这个缺陷;`--ci` 现在会正确地失败,直到区块被恢复(`uds update --integrations-only`)或项目以其他方式恢复同步为止。交互式 `uds check`(不加 `--ci`)不受影响——仍以退出码 0 收尾,不中断一般使用。(XSPEC-418 R1)
39
+ - **整合文件(CLAUDE.md、CLAUDE.local.md、AGENTS.md 等)同时被整份内容与 UDS 区块两套哈希追踪,两套检查在同一次运行里可能互相矛盾。** 全新 `uds init` 从不为这些文件记录整份哈希,但 `uds update --integrations-only` 会——跑过一次之后,用户在 UDS 区块**外**的任何修改(正是 marker-based update 承诺保留的自定义内容)都会让 `uds check --ci` 报 `CLAUDE.md(已修改)` 并退出码 1,而同一次输出里自己的区块完整性检查却说区块完好。另外,`uds check --restore` 正确地重写了损坏的区块(保留区块外内容,没有数据丢失),却只更新了整份哈希,从未更新区块哈希——于是下一次 check 对一个刚被正确恢复的区块报 `CLAUDE.md(UDS 区块已修改)`。整合文件现在不再写入 `fileHashes`(只写入本来就只追踪区块的 `integrationBlockHashes`)——走查了所有写入点,不只最初报告的两处,包括 `--apply`/`--plan` 的 reconciler 路径与 `--sync-refs`;已有 manifest 里这类文件残留的整份哈希,会在下一次 `uds update`(或 `uds check --restore`/`--migrate`)时被移除,区块哈希保留。`uds check --restore` 恢复整合文件后,现在会把区块哈希更新为实际写入的内容。已用一份真实采用者的 manifest(恰好带有这个残留字段)验证:同一份输入,修正前 `uds check --ci` 退出码 1,修正后退出码 0。后续复核另发现两个缺口,一并修掉:`uds check --restore` 过去对受损的 UDS 区块完全无作用——它靠的是 `fileStatus`,而那完全由 `fileHashes` 构建,已不含整合文件,于是它悄悄恢复了 0 个文件而区块仍是坏的;`--restore` 现在也会恢复被判定为「已修改」或「标记丢失」的区块(不动区块外内容,`--restore-missing` 行为不变)。另外,因为上面新增的清除逻辑只挂在写入路径,已有 manifest 里残留的整份哈希若不曾跑过写入,纯 `check` 永远没有机会清掉它——标准文件完整性检查现在也会在读取时跳过同时被 `integrationBlockHashes` 追踪的键,让未跑过 `update` 的已有项目也能报告干净。(XSPEC-418 R6)
40
+
41
+ ### 新增
42
+
43
+ - **`uds init --claude-target <project|local>` 与 `uds update --claude-target <project|local>`:在已有团队 `CLAUDE.md` 的仓库里个人采用 UDS。** 过去 UDS 的 Claude Code 集成一律写入 `CLAUDE.md`——团队共用、会进版本控制的文件——没有任何改写目标的方式。在已有团队 `CLAUDE.md` 的仓库里个人采用 UDS 的用户,只能手动把 UDS 区块移到 `CLAUDE.local.md`(Claude Code 原生支持、紧接在 `CLAUDE.md` 之后读入的文件),而从那一刻起 `check`/`update`/`uninstall` 全都报告错误,或悄悄写回团队文件——包括在例行孤儿清理中把移动后文件自己的哈希当作"孤儿"删除。
44
+ `uds init` 的 `--claude-target local` 从一开始就把集成内容写进 `CLAUDE.local.md`;团队的 `CLAUDE.md` 完全不会被动到。`uds update --claude-target <project|local>` 则让**已有**安装不必重装就能切换目标:从旧文件移除 UDS 区块(保留写在里面的其他内容;若旧文件在移除后只剩 UDS 内容则整个删除,与 `uninstall` 既有规则一致)、写入新目标、并更新 manifest,不论新目标是否已存在手动移过去的区块。`check`、`update`(含 `--integrations-only`/`--force`)与孤儿哈希清理现在都经同一个函数解出工具的实际目标文件,不再各自假设默认值——从未使用 `--claude-target` 的项目完全不受影响:manifest 只有在选择 `local` 时才会多出 `integrationTargets` 字段。`--claude-target` 不影响 `AGENTS.md`;若不想让它进版本控制,一样要自己通过 `.git/info/exclude` 排除。UDS 不会自动把 `CLAUDE.local.md` 写进 `.gitignore`——请自行加入——且因为它未受版本控制,只存在于创建它的那个 git worktree。详见 [CLI-INIT-OPTIONS.md](docs/CLI-INIT-OPTIONS.md)("Claude Code 集成目标文件"一节)。(XSPEC-418 R2–R4)
45
+
20
46
  ## [6.10.0] - 2026-09-16
21
47
 
22
48
  ### 修复
@@ -14,7 +14,7 @@ status: current
14
14
 
15
15
  Universal Development Standards 是一个语言无关、框架无关的文件化标准框架。它提供:
16
16
 
17
- - **核心规范** (`core/`):152 个基础开发标准
17
+ - **核心规范** (`core/`):153 个基础开发标准
18
18
  - **AI 技能** (`skills/`):用于 AI 辅助开发的 Claude Code 技能
19
19
  - **CLI 工具** (`cli/`):用于采用标准的 Node.js CLI
20
20
  - **整合** (`integrations/`):各种 AI 工具的配置
@@ -15,7 +15,7 @@ status: current
15
15
 
16
16
  > **语言**: [English](../../README.md) | [繁體中文](../zh-TW/README.md) | 简体中文
17
17
 
18
- **版本**: 6.10.0 | **发布日期**: 2026-09-16 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
18
+ **版本**: 6.12.0 | **发布日期**: 2026-09-25 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
19
19
 
20
20
  语言无关、框架无关的软件项目文档标准。通过 AI 原生工作流,确保不同技术栈之间的一致性、质量和可维护性。
21
21
 
@@ -76,7 +76,7 @@ npx universal-dev-standards init
76
76
  <!-- UDS_STATS_TABLE_START -->
77
77
  | 类别 | 数量 | 说明 |
78
78
  |----------|-------|-------------|
79
- | **核心标准** | 152 | 通用开发准则 |
79
+ | **核心标准** | 153 | 通用开发准则 |
80
80
  | **AI Skills** | 55 | 互动式技能 |
81
81
  | **斜线命令** | 51 | 快速操作 |
82
82
  | **CLI 命令** | 23 | 项目设置与维护 |
@@ -13,7 +13,7 @@ status: current
13
13
  <!-- UDS_SUPPORTED_VERSIONS_START -->
14
14
  | 版本 | 支持状态 |
15
15
  |------|--------|
16
- | 6.10.0 | ✅ 最新正式版 |
16
+ | 6.12.0 | ✅ 最新正式版 |
17
17
  | < 6.0.0 | ❌ 已终止支持 |
18
18
  <!-- UDS_SUPPORTED_VERSIONS_END -->
19
19
 
@@ -1,6 +1,6 @@
1
1
  # UDS 速查表
2
2
 
3
- > Quick reference for all UDS features | Last updated: 2026-09-14
3
+ > Quick reference for all UDS features | Last updated: 2026-09-23
4
4
 
5
5
  **Language**: [English](../../../docs/user/CHEATSHEET.md) | [繁體中文](../../zh-TW/docs/CHEATSHEET.md) | 简体中文
6
6
 
@@ -260,6 +260,7 @@
260
260
  | `mutation-testing` | Mutation testing evaluates test suite effectivenes |
261
261
  | `no-cicd-deployment` | No-CI/CD Deployment Strategy |
262
262
  | `observability-standards` | Observability Standards |
263
+ | `open-work-tracking` | The deferred-item-exit standard requires that a de |
263
264
  | `packaging-standards` | This standard defines a Recipe-based packaging fra |
264
265
  | `performance-standards` | This standard defines comprehensive guidelines for |
265
266
  | `pii-classification` | PII Classification and Handling Standards |
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  source: ../../../docs/CLI-INIT-OPTIONS.md
3
- source_version: 3.5.1
4
- translation_version: 3.5.1
5
- last_synced: 2026-01-15
3
+ source_version: 3.5.2
4
+ translation_version: 3.5.2
5
+ last_synced: 2026-09-18
6
6
  status: current
7
7
  ---
8
8
 
@@ -10,8 +10,8 @@ status: current
10
10
 
11
11
  > **语言**: [English](../../../docs/CLI-INIT-OPTIONS.md) | [简体中文](../../zh-TW/docs/CLI-INIT-OPTIONS.md) | 简体中文
12
12
  >
13
- > **版本**: 3.5.0
14
- > **最后更新**: 2026-01-09
13
+ > **版本**: 3.5.2
14
+ > **最后更新**: 2026-09-18
15
15
 
16
16
  本文档详细说明 `uds init` 命令的每一个选项,包含使用情境、影响范围和建议选择。
17
17
 
@@ -835,8 +835,49 @@ uds init --experimental
835
835
  | 不生成 AGENTS.md | `--no-agents-md` | 跳过 AGENTS.md 生成 |
836
836
  | 强制执行 Hooks | `--with-hooks` | 安装强制执行 hooks(commit-msg、security、logging) |
837
837
  | 内容布局 | `--content-layout` | 内容布局(`flat`、`layered`)- 默认:`flat` |
838
+ | Claude Code 目标文件 | `--claude-target` | Claude Code 集成内容要写到哪里:`project`(`CLAUDE.md`,默认)或 `local`(`CLAUDE.local.md`) |
838
839
  | 模式(已弃用) | `-m, --mode` | 安装模式(skills, full)- 请改用 `--skills-location` |
839
840
 
841
+ ### Claude Code 集成目标文件(`--claude-target`)
842
+
843
+ UDS 默认把 Claude Code 内容写进 `CLAUDE.md`——团队共用、会进版本控制的那个文件。
844
+ 若你是在一个**已有团队 `CLAUDE.md`** 的仓库里**个人采用** UDS,改用
845
+ `--claude-target local`:UDS 会改写入 `CLAUDE.local.md`,这是
846
+ [Claude Code 原生支持](https://code.claude.com/docs/en/memory.md)、
847
+ 紧接在 `CLAUDE.md` 之后读入的文件,且完全不动团队的文件。
848
+
849
+ ```bash
850
+ # 在有团队 CLAUDE.md 的仓库里个人采用
851
+ uds init -y --claude-target local
852
+ ```
853
+
854
+ 使用前有三件事要知道:
855
+
856
+ 1. **要自己把它加进 gitignore。** UDS 不会写 `.gitignore` 或
857
+ `.git/info/exclude`——请自行把 `CLAUDE.local.md` 加进其中一个,
858
+ 否则它会像任何新文件一样被提交。
859
+ 2. **只存在于创建它的那个 worktree。** 因为(你 gitignore 之后)它是未受版本控制的文件,
860
+ 在某个 `git worktree` 创建的 `CLAUDE.local.md` 在同一个仓库的另一个 worktree
861
+ 里看不到——每个 worktree 有自己的工作目录,未受版本控制的文件不会在 worktree 之间共享。
862
+ 若你使用多个 worktree,需要在每一个里分别执行
863
+ `uds init --claude-target local`(或下方的 `uds update --claude-target local`)。
864
+ 3. **`AGENTS.md` 不受影响。** `--claude-target` 只改变 Claude Code 内容要写到哪里。
865
+ 若 `--agents-md` 生成了通用的 `AGENTS.md` 摘要,它仍照常写进 `AGENTS.md`;
866
+ 若也不想让它进版本控制,一样要自己排除(例如通过 `.git/info/exclude`)。
867
+
868
+ 已经用默认目标文件装好了,想不重装就切换?`uds update` 支持同一个标志:
869
+
870
+ ```bash
871
+ # 把已有安装的 Claude Code 内容从 CLAUDE.md 移到 CLAUDE.local.md
872
+ uds update --claude-target local
873
+
874
+ # 移回去
875
+ uds update --claude-target project
876
+ ```
877
+
878
+ 这会从旧文件移除 UDS 区块(保留你自己写在里面的其他内容)、写进新文件,并更新
879
+ manifest——之后 `uds check` 校验的是新目标文件,不是旧的。
880
+
840
881
  ### 完整 CLI 示例
841
882
 
842
883
  ```bash
@@ -876,6 +917,12 @@ uds init -y --output-lang traditional-chinese --locale zh-cn
876
917
 
877
918
  # PHP 项目
878
919
  uds init -y --lang php --framework fat-free
920
+
921
+ # 在有团队 CLAUDE.md 的仓库里个人采用
922
+ uds init -y --claude-target local
923
+
924
+ # 之后把已有安装切换到 CLAUDE.local.md,不需要重装
925
+ uds update --claude-target local
879
926
  ```
880
927
 
881
928
  ---
@@ -1,7 +1,7 @@
1
1
  # UDS 功能参考手册
2
2
 
3
3
  > Universal Development Standards - 完整功能文档
4
- > Auto-generated | Last updated: 2026-09-14
4
+ > Auto-generated | Last updated: 2026-09-23
5
5
 
6
6
  **Language**: [English](../../../docs/reference/FEATURE-REFERENCE.md) | [繁體中文](../../zh-TW/docs/FEATURE-REFERENCE.md) | 简体中文
7
7
 
@@ -14,10 +14,10 @@
14
14
  3. [技能](#skills) (55)
15
15
  4. [代理](#agents) (5)
16
16
  5. [工作流程](#workflows) (5)
17
- 6. [核心规范](#core-standards) (152)
17
+ 6. [核心规范](#core-standards) (153)
18
18
  7. [脚本](#scripts) (59)
19
19
 
20
- **Total Features: 350**
20
+ **Total Features: 351**
21
21
 
22
22
  ---
23
23
 
@@ -54,6 +54,7 @@
54
54
  | `--no-agents-md` | Skip AGENTS.md generation |
55
55
  | `--with-hooks` | Install enforcement hooks declared by the installed standards |
56
56
  | `--content-layout` | Content layout (flat, layered) [default: flat] |
57
+ | `--claude-target` | Claude Code integration target: project (default, writes CLAUDE.md) or local (writes CLAUDE.local.md — not committed to git; gitignore it yourself) |
57
58
  | `-y, --yes` | Use defaults, skip interactive prompts |
58
59
  | `-E, --experimental` | Enable experimental features (methodology) |
59
60
  | `--force` | Bypass UDS source-repo self-adoption guard (DEC-044 / XSPEC-071) |
@@ -155,6 +156,7 @@
155
156
  | `--force` | Force update all files, ignoring hash comparison |
156
157
  | `--prune` | Delete .standards/ files UDS wrote but no longer ships (listed without this flag; never touches files UDS did not write) |
157
158
  | `--rollback` | Rollback to the most recent backup |
159
+ | `--claude-target` | Switch an existing install to a different Claude Code integration target: project (CLAUDE.md) or local (CLAUDE.local.md) — moves the UDS block, keeps your content, no reinstall |
158
160
  | `--locale` | Override locale for skills install (zh-tw, zh-cn, en); also reads .uds/install.yaml + UDS_LOCALE env |
159
161
 
160
162
  ### `uds skills`
@@ -514,6 +516,7 @@
514
516
  | `mutation-testing` | 1.1.0 | Mutation testing evaluates test suite effectiveness by injecting artificial bugs |
515
517
  | `no-cicd-deployment` | - | |
516
518
  | `observability-standards` | 1.0.0 | |
519
+ | `open-work-tracking` | 1.0.0 | The deferred-item-exit standard requires that a deferred item leave its document |
517
520
  | `packaging-standards` | 1.1.0 | This standard defines a Recipe-based packaging framework that enables user proje |
518
521
  | `performance-standards` | 1.2.0 | This standard defines comprehensive guidelines for software performance engineer |
519
522
  | `pii-classification` | 1.1.0 | **Status**: Active | **Updated**: 2026-06-19 | |
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  source: ../../CHANGELOG.md
3
- source_version: 6.10.0
4
- translation_version: 6.10.0
5
- last_synced: 2026-09-16
3
+ source_version: 6.12.0
4
+ translation_version: 6.12.0
5
+ last_synced: 2026-09-24
6
6
  status: current
7
7
  ---
8
8
 
@@ -17,6 +17,32 @@ status: current
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [6.12.0] - 2026-09-25
21
+
22
+ ### 新增
23
+
24
+ - **新標準 `open-work-tracking`——`deferred-item-exit` 的下游一半。** `deferred-item-exit` 要求被延後的項目離開原文件、走向可追溯的出口,但刻意不規定出口的承載處;東西進了承載處之後,沒有任何規則防止承載處本身腐壞。本標準以 16 條要求(OWT-001~016)補上:低摩擦的記錄點(必填欄位至多兩個)、每個等待中的項目旁寫明解除條件、可推導的欄位由產生而非手寫、以內容證明「最新」而非可隨手改的時間戳、覆蓋率數字要寫出它看不到什麼,以及每輪結束時回報未完成工作但**從不阻擋**的檢查點。最後一點刻意與掛在同一事件、會阻擋的 `turn-completion-integrity` 相反;標準內附對照表,避免採用者把兩者接成同一件事。其中兩個數字門檻標明為初始判斷、非量測結果。
25
+
26
+ ## [6.11.0] - 2026-09-18
27
+
28
+ ### 修正
29
+
30
+ - **`uds update --plan`/`--apply` 對整合檔永遠不會收斂:即使剛跑完 `--apply`、檔案內容與產生器會產生的內容逐位元組相同,仍會顯示 `Migrate Block: N`。** `diffIntegrations` 對任何帶有 UDS 標記的整合檔都無條件產生 `migrate_block` 動作——「我們一律更新整合檔,因為內容是動態產生的」——因為 desired state 從未帶有可比對的雜湊(`hash: null`,註解說「產生後才計算」,但從未真的算過)。desired-state calculator 現在會用 `--apply` 自己會用的同一條路徑(`buildToolIntegrationConfig` + `generateIntegrationContent`)產生整合檔內容,並只對 UDS 區塊算雜湊,讓 `diffIntegrations` 能像其他每個類別一樣分辨「內容已經相符」與「內容不同」,雜湊相符時回報 `unchanged` 而非 `migrate_block`。一份區塊真的過期的檔案(手動編輯過,或由舊版 CLI 產生)仍會照舊產生 `migrate_block`。產生失敗(例如 registry 解不出某個工具)時回退成修正前的無條件行為,不會讓計畫當掉。
31
+ - **`uds check` 可能在同一次執行裡對同一個整合檔印出兩則互相矛盾的「已參考」宣告。** `standardsReferenced`(「{count}/{total} 項標準已參考」)掃描整個整合檔本文——標準名稱在任何地方被提到都算。`standardsNotReferenced`(「未參考的標準(選用):」)只看結構化的 `Reference:`/`參考:` 行。一個標準在檔案散文中被提到、卻沒有列在任何 `Reference:` 行上,會在同一次執行裡同時滿足第一則宣告、又落在第二則宣告裡——同一個詞(「已參考」/「參考」),量測的是兩件不同的事,讀起來像矛盾。三語的第二則訊息都已改寫成精確描述它實際檢查的內容(沒有出現在 `Reference:`/`參考:` 行),取代原本籠統的「未參考」宣告。
32
+ - **單純的 `uds update --plan` 與 `uds check` 從未提示 Skills 或 Commands 版本落後最新 UDS 釋出版。** 版本落後只由 `uds update --plan --skills`/`--plan --commands` 計算——一般的調和 `--plan`(不帶範圍旗標)呼叫的是另一個從未碰觸這件事的函式,`uds check` 則完全沒有對等的檢查。使用者跑純粹的 `--plan` 或 `check` 時,看到的是一份乾淨的報告,儘管 Skills 落後了一整個小版本,也沒有任何提示說帶範圍的 plan、或 `uds update --skills` 有事可做。兩者現在都會在任何已安裝的 Skills 或 Commands 版本落後時,印出簡短的「`<工具>`(`<位置>`):v舊 → v新」提示,並附上修復指令。這比照既有的頂層「Version: X → Y ⚠」列,而非整合區塊完整性檢查(XSPEC-418 R1):落後最新版是使用者更新前的常態,不是像 UDS 區塊被修改/遺失那樣的合規缺陷,因此不會讓 `uds check --ci` 失敗。
33
+ - **6.10.0 的死連結修正(P2)把一則寫著 6.0.0 之前檔名的參考直接刪掉,而不是改寫它,還可能留下一個懸空的逗號。** `resolveStandardReferences` 比對一行 `Reference:` 的 stem 時只查 manifest 已安裝清單,從未查過 `STANDARD_ID_MAPPING`(conversion-rules.js)——這正是 `yaml-generator.js` 別處已在用、記錄「舊檔名 → 現行 id」的對照表。一行寫著舊檔名 `.standards/commit-message-guide.md` 而專案其實裝了 `commit-message` 的參考,看起來和一個專案刻意不裝、已停用的 UDS 標準一模一樣,於是被整行刪掉,而不是改寫成 `.standards/commit-message.ai.yaml`。另外,刪掉一項參考後的逗號清理只處理了尾端逗號、重複逗號、逗號前多餘空白,沒處理「一行裡第一項參考被刪掉、逗號緊貼在冒號後面」的狀況(`Reference:, .standards/other.ai.yaml`)。整段改寫成「拆項 → 解析或捨棄 → 重新 join」,取代在原地修補被刪字串周圍標點的作法。
34
+ - **被 6.10.0 `resolveStandardReferences` 缺陷刪掉的主要標準參考,即使套用上面的修正也不會自己回來。** 把刪除動作留下的懸空逗號清掉,修好的只是那一行的標點,不是把被刪掉的項目帶回來——像「## 提交訊息標準」這樣的 UDS 範本段落活在 UDS 標記之外,一旦某一項被刪掉,就沒有任何東西會重新產生那段內容。針對這個特定情境新增一個範圍刻意收窄的自動補回機制:當一行的標題與某個 UDS 範本標題完全相同(`RULE_TEMPLATES` 出貨的任一語言版本),而且該範本的主要參考(它自己「`Reference:`」/「`參考:`」行上的第一個 `.standards/...` 項)不在檔案那一行裡,且該標準確實已安裝,就會把它補回該行最前面——行內其他內容(專案自有項目、options 檔、既有順序)原樣不動,不會補回任何次要範本項目,使用者自己寫的段落(任何其他標題)一律不碰。此修復是冪等的。只修復 6.10.0 那次刪除造成的問題,不嘗試修復由無關手動編輯造成的參考損壞。
35
+ - **單純的 `uds update` 從未修復上面 Q1 缺陷留下的壞掉 `integrationConfigs[file].categories`——只有 `--sync-refs` 會。** 一份已經帶著 `categories: []`(來自較舊、有缺陷的 `--sync-refs` 執行)的 manifest,會在之後每一次單純的 `uds update --yes` 都維持壞掉:該指令自己的整合同步步驟會寫 `integrationBlockHashes`,卻完全不會讀取 `integrationConfigs`,所以沒有任何東西修正它——而下一次 `uds check --restore-missing` 就會用那份壞掉的儲存設定重建整合檔,再次悄悄漏掉段落。`uds update` 現在會用 `--sync-refs` 同樣的方式(`calculateCategoriesFromStandards`)修復空的或無法辨識的 `categories` 值,而已經有效的清單維持原樣不動,讓單純的 update 不會每次都變成完整的重新同步。
36
+ - **`uds update --sync-refs`/`--integrations-only`/`uds check --migrate`/`uds config` 可能悄悄把 `manifest.version` 降版,同一條同步路徑還會在一份正常的 3.4.0 manifest 上算出空的分類集合。** 五個寫入點寫死了一個較舊的 schema 版本字面值(`'3.1.0'`/`'3.2.0'`/`'3.3.0'`),而不是 CLI 目前的 schema 版本(`3.4.0`)——對一份已經是最新版的 manifest 執行上述任一指令,都會把版本寫回舊的。另外,`calculateCategoriesFromStandards`(`--sync-refs` 用來決定 CLAUDE.md/AGENTS.md 該含哪些段落的函式)用檔名查每個標準,但 3.4.0 manifest 存的是純 stem(`commit-message`,而非 `commit-message.ai.yaml`)——每次查詢都落空,分類集合變成空的,下一次 `--sync-refs`(或 `--restore-missing` 重建)就會重新產生一份完全漏掉反幻覺/commit-message/code-review 段落的檔案。兩者現在都在同一個真實來源處修復:一個共用的 `bumpManifestVersion` 輔助函式,只會讓 manifest 版本朝最新前進,不會倒退;以及同檔案裡別處已在用、支援 stem 的分類查找(`categoryForStandard`)。這讓分類計算恢復成 `--sync-refs` 在 6.10.0 之前的算法——依實際已安裝的標準計算,而非固定清單——所以完整重新產生(`--sync-refs`、`--integrations-only`,或單純的 `uds update`)現在會寫出每一個有範本、且背後有已安裝標準的段落(目前 9 段),而不只是全新 `uds init` 播種的那 3 段;對一個已經有完整段落的專案做純區塊更新則不受影響。
37
+ - **一句單純提到 UDS 標記文字的句子,可能被誤認成真正的區塊邊界,導致從那句話到真正 END 標記之間的所有內容——包含採用者自己的內容——都被刪除(v3.5.0–6.10.0)。** 每一個定位標記的呼叫點都直接用 `content.indexOf('<!-- UDS:STANDARDS:START -->')`/`.indexOf('...:END -->')`,這會比對到檔案中任何位置出現的標記文字:一句逐字引用標記語法來解釋它的句子(本專案自己的 CLAUDE.md 就是這樣做),或程式碼區塊裡含有它的範例,都和真正的邊界無從分辨。這影響了所有四條會重新產生整合檔 UDS 區塊的寫入路徑:`uds update --integrations-only`、`uds update --apply` 的 `migrate_block` reconciler 路徑、`uds update --sync-refs`,以及 `uds check --restore`(XSPEC-418 R6 讓它也會還原受損的 UDS 區塊)。標記現在只在(去除前後空白後)獨占一整行、且那一行不在 fenced code block(``` / ~~~)內時才算數;所有呼叫點現在都經過同一個共用的 `locateMarkerBlock` 輔助函式,並以靜態掃描守衛測試強制執行,避免未來的呼叫點又退回直接用 `indexOf`/`includes`。含有兩組真正標記對的檔案(損壞,或手動編輯出錯)不再被猜測——每條寫入路徑都會拒絕執行並列出兩個標記所在行號,`uds check` 也會明確回報這個狀態,不再併入「已修改」或「找不到標記」。
38
+ - **`uds check --ci` 可能畫面上印出整合區塊的 ✗,結尾卻仍宣稱專案符合標準並以結束碼 0 收尾。** `checkIntegrationBlocksIntegrity` 的檢查結果(區塊被修改/遺失/UDS 標記被移除)算出來也印出來了,卻在最終判定被丟棄——判定只看標準檔完整性。若你的 CI 一直對某個 CLAUDE.md/GEMINI.md 等檔案的 UDS 區塊實際上已被移除或改動的專案顯示綠燈,那就是這個缺陷;`--ci` 現在會正確地失敗,直到區塊被復原(`uds update --integrations-only`)或專案以其他方式恢復同步為止。互動式 `uds check`(不加 `--ci`)不受影響——仍以結束碼 0 收尾,不中斷一般使用。(XSPEC-418 R1)
39
+ - **整合檔(CLAUDE.md、CLAUDE.local.md、AGENTS.md 等)同時被整份內容與 UDS 區塊兩套雜湊追蹤,兩套檢查在同一次執行裡可能互相矛盾。** 全新 `uds init` 從不替這些檔案記錄整份雜湊,但 `uds update --integrations-only` 會——跑過一次之後,使用者在 UDS 區塊**外**的任何修改(正是 marker-based update 承諾保留的自訂內容)都會讓 `uds check --ci` 報 `CLAUDE.md(已修改)` 並結束碼 1,而同一次輸出裡自己的區塊完整性檢查卻說區塊完好。另外,`uds check --restore` 正確地重寫了損壞的區塊(保留區塊外內容,沒有資料遺失),卻只更新了整份雜湊,從未更新區塊雜湊——於是下一次 check 對一個才剛被正確還原的區塊報 `CLAUDE.md(UDS 區塊已修改)`。整合檔現在不再寫進 `fileHashes`(只寫進本來就只追蹤區塊的 `integrationBlockHashes`)——走訪了所有寫入點,不只原始回報的兩處,包含 `--apply`/`--plan` 的 reconciler 路徑與 `--sync-refs`;既有 manifest 裡這類檔案殘留的整份雜湊,會在下一次 `uds update`(或 `uds check --restore`/`--migrate`)時被移除,區塊雜湊保留。`uds check --restore` 還原整合檔後,現在會把區塊雜湊更新成實際寫入的內容。已用一份真實採用者的 manifest(恰好帶有這個殘留欄位)驗證:同一份輸入,修正前 `uds check --ci` 結束碼 1,修正後結束碼 0。後續複核另發現兩個缺口,一併修掉:`uds check --restore` 過去對受損的 UDS 區塊完全無作用——它靠的是 `fileStatus`,而那完全由 `fileHashes` 建構,已不含整合檔,於是它悄悄還原了 0 個檔案而區塊仍是壞的;`--restore` 現在也會還原被判定為「已修改」或「標記遺失」的區塊(不動區塊外內容,`--restore-missing` 行為不變)。另外,因為上面新增的清除邏輯只掛在寫入路徑,既有 manifest 裡殘留的整份雜湊若不曾跑過寫入,純 `check` 永遠沒有機會清掉它——標準檔完整性檢查現在也會在讀取時略過同時被 `integrationBlockHashes` 追蹤的鍵,讓未跑過 `update` 的既有專案也能回報乾淨。(XSPEC-418 R6)
40
+
41
+ ### 新增
42
+
43
+ - **`uds init --claude-target <project|local>` 與 `uds update --claude-target <project|local>`:在已有團隊 `CLAUDE.md` 的 repo 裡個人採用 UDS。** 過去 UDS 的 Claude Code 整合一律寫入 `CLAUDE.md`——團隊共用、會進版控的檔案——沒有任何改寫目標的方式。在已有團隊 `CLAUDE.md` 的 repo 裡個人採用 UDS 的使用者,只能手動把 UDS 區塊搬到 `CLAUDE.local.md`(Claude Code 原生支援、緊接在 `CLAUDE.md` 之後讀入的檔案),而從那一刻起 `check`/`update`/`uninstall` 全都回報錯誤,或悄悄寫回團隊檔案——包含在例行孤兒清理中把搬移後檔案自己的雜湊當「孤兒」刪掉。
44
+ `uds init` 的 `--claude-target local` 從一開始就把整合內容寫進 `CLAUDE.local.md`;團隊的 `CLAUDE.md` 完全不會被動到。`uds update --claude-target <project|local>` 則讓**既有**安裝不必重裝就能切換目標:從舊檔移除 UDS 區塊(保留寫在裡面的其他內容;若舊檔在移除後只剩 UDS 內容則整個刪除,與 `uninstall` 既有規則一致)、寫入新目標、並更新 manifest,不論新目標是否已存在手動搬過去的區塊。`check`、`update`(含 `--integrations-only`/`--force`)與孤兒雜湊清理現在都經同一個函式解出工具的實際目標檔,不再各自假設預設值——從未使用 `--claude-target` 的專案完全不受影響:manifest 只有在選擇 `local` 時才會多出 `integrationTargets` 欄位。`--claude-target` 不影響 `AGENTS.md`;若不想讓它進版控,一樣要自己透過 `.git/info/exclude` 排除。UDS 不會自動把 `CLAUDE.local.md` 寫進 `.gitignore`——請自行加入——且因為它未受版控,只存在於建立它的那個 git worktree。詳見 [CLI-INIT-OPTIONS.md](docs/CLI-INIT-OPTIONS.md)(「Claude Code 整合目標檔」一節)。(XSPEC-418 R2–R4)
45
+
20
46
  ## [6.10.0] - 2026-09-16
21
47
 
22
48
  ### 修正
@@ -14,7 +14,7 @@ status: current
14
14
 
15
15
  Universal Development Standards 是一個語言無關、框架無關的文件化標準框架。它提供:
16
16
 
17
- - **核心規範** (`core/`):152 個基礎開發標準
17
+ - **核心規範** (`core/`):153 個基礎開發標準
18
18
  - **AI 技能** (`skills/`):用於 AI 輔助開發的 Claude Code 技能
19
19
  - **CLI 工具** (`cli/`):用於採用標準的 Node.js CLI
20
20
  - **整合** (`integrations/`):各種 AI 工具的配置
@@ -15,7 +15,7 @@ status: current
15
15
 
16
16
  > **語言**: [English](../../README.md) | 繁體中文 | [简体中文](../zh-CN/README.md)
17
17
 
18
- **版本**: 6.10.0 | **發布日期**: 2026-09-16 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
18
+ **版本**: 6.12.0 | **發布日期**: 2026-09-25 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
19
19
 
20
20
  語言無關、框架無關的軟體專案文件標準。透過 AI 原生工作流,確保不同技術堆疊之間的一致性、品質和可維護性。
21
21
 
@@ -76,7 +76,7 @@ npx universal-dev-standards init
76
76
  <!-- UDS_STATS_TABLE_START -->
77
77
  | 類別 | 數量 | 說明 |
78
78
  |----------|-------|-------------|
79
- | **核心標準** | 152 | 通用開發準則 |
79
+ | **核心標準** | 153 | 通用開發準則 |
80
80
  | **AI Skills** | 55 | 互動式技能 |
81
81
  | **斜線命令** | 51 | 快速操作 |
82
82
  | **CLI 指令** | 23 | 專案設定與維護 |
@@ -13,7 +13,7 @@ status: current
13
13
  <!-- UDS_SUPPORTED_VERSIONS_START -->
14
14
  | 版本 | 支援狀態 |
15
15
  |------|--------|
16
- | 6.10.0 | ✅ 最新正式版 |
16
+ | 6.12.0 | ✅ 最新正式版 |
17
17
  | < 6.0.0 | ❌ 已終止支援 |
18
18
  <!-- UDS_SUPPORTED_VERSIONS_END -->
19
19
 
@@ -0,0 +1,255 @@
1
+ ---
2
+ source: ../../../core/open-work-tracking.md
3
+ source_version: 1.0.0
4
+ translation_version: 1.0.0
5
+ last_synced: 2026-09-23
6
+ source_hash: 8382d3f518a9
7
+ status: current
8
+ ---
9
+
10
+ # 開放工作追蹤標準
11
+
12
+ > **Language**: [English](../../../core/open-work-tracking.md) | 繁體中文
13
+
14
+ **版本**: 1.0.0
15
+ **最後更新**: 2026-09-23
16
+ **適用**: 任何跨越一個以上工作階段承載工作、有可能在階段之間遺失項目的專案
17
+ **範圍**: universal
18
+
19
+ ---
20
+
21
+ ## 目的
22
+
23
+ 延後項目出口標準(deferred-item-exit)要求延後項目離開文件、抵達一個可追蹤的出口,
24
+ 但刻意不規定那個出口長什麼樣、也不規定項目抵達之後什麼東西防止它腐壞。
25
+ **本標準是那個下游的一半**:假設一個承載開放工作的地方已經存在,
26
+ 它自己必須具備什麼性質才不會慢慢變得不可信。見 [deferred-item-exit](deferred-item-exit.md)。
27
+
28
+ 三種不同的「工作不見了」的方式,常被塞進同一份沒有分別的清單,而**這個合併本身就是失敗的一部分**——
29
+ 一份想同時接住三者的清單,通常一個都接不好:
30
+
31
+ | 症狀 | 背後的問題 | 需要的機制 |
32
+ |---|---|---|
33
+ | 工作進行中冒出新項目,沒有低摩擦的地方可以記下它 | 項目有時效性,等到方便記錄時已經忘了 | 一個便宜到不會打斷當前工作的收件點 |
34
+ | 某項目因等待別的事件而暫停 | 「等待中」若沒有記錄解除條件,與「被忘記」無法分辨 | 與等待一起記錄的解除條件 |
35
+ | 已規劃的項目還沒動工,時間過去 | 沒有時鐘的項目會無聲腐爛——沒有東西會再指向它 | 一個門檻,或一次被迫的定期檢視,讓它重新浮現 |
36
+
37
+ 下面每一條要求都對應這張表的一列,或對應本標準設計當天觀察到的四個失效之一
38
+ (見〈[證據與校準](#證據與校準)〉)。**沒有任何一個機制被規定**——
39
+ 理由與 [deferred-item-exit](deferred-item-exit.md) 對自己出口的約束相同(DEC-049:
40
+ UDS 定義必須成立的關係,維持它的機制由採用層選擇)。
41
+
42
+ ---
43
+
44
+ ## 本標準的寫法,以及為什麼這樣寫
45
+
46
+ **讀下面任何一條要求之前先讀這一段。它拘束它們全部。**
47
+
48
+ UDS 定義**活動**,採用層負責**編排**(DEC-049)。一份寫成工作流協定、檔案格式、
49
+ 或特定工具設定的標準屬於採用層,不屬於這裡——這與 [deferred-item-exit](deferred-item-exit.md)
50
+ 受的約束相同,只是套用在下游一層。
51
+
52
+ | 這裡容許——**what** | 這裡不容許——**how** |
53
+ |---|---|
54
+ | 收件點欄位數必須具備的性質 | 收件點是哪個 app、檔案或工單系統 |
55
+ | 等待項目與解除條件之間必須存在的關係 | 輪詢那個條件的排程器或機器人 |
56
+ | 「這是最新的」這句宣稱必須從什麼可被證明 | 具體用哪個雜湊函式、diff 工具或 CI 供應商 |
57
+ | 一個回報數字與它看不到的部分之間的關係 | 儀表板版面或報告範本 |
58
+ | 控制權交回人的那一點存在一個確認點,且它永不阻斷 | 用什麼 hook 系統、shell 或 cron 實作它 |
59
+
60
+ **直說它的後果**:本標準**不附帶任何閘門**。它只說一個承載開放工作的地方必須具備什麼性質;
61
+ 有沒有東西在檢查,是採用專案的決定——[OWT-014](#要求) 與 [OWT-015](#要求)
62
+ 存在的目的,是讓那個決定沒辦法被默默做掉。
63
+
64
+ ---
65
+
66
+ ## 不變量
67
+
68
+ **一個承載開放工作的地方,必須:(1)不要求分類就能收下新項目、(2)為每一個標為等待中的項目記下解除條件、
69
+ (3)對任何有可靠來源可推導的欄位改用生成、(4)回報還剩什麼時同時揭露看不到什麼、
70
+ (5)在控制權從 agent 交回人的那一刻被檢視——而且那個檢視不能讓回合失敗。**
71
+
72
+ ---
73
+
74
+ ## 要求
75
+
76
+ | ID | 要求 | 嚴重度 |
77
+ |---|---|---|
78
+ | **OWT-001** | 新項目的收件點必填欄位不得超過兩個。分類、優先級、負責人一律是 triage 時的動作,不得成為輸入門檻 | error |
79
+ | **OWT-002** | 標為等待中的項目,同時記下在等什麼與什麼事件視為解除 | error |
80
+ | **OWT-003** | 能從版控、規格標記、或 CI 結果完整推導的欄位,一律生成,不手寫 | error |
81
+ | **OWT-004** | 生成區段的「最新」宣稱能從它所本的內容證明(例如來源雜湊),不靠一個人可編輯的日期 | error |
82
+ | **OWT-005** | 「內容可證明最新」與「日期宣稱最新、內容未驗證」回報為兩個相異狀態。合併為單一通過即不滿足 OWT-004 | error |
83
+ | **OWT-006** | 任何「還有 N 項」的數字,旁邊同時印出看得見多少來源、看不見多少來源。看不見的部分不被讀成零 | error |
84
+ | **OWT-007** | 開放工作摘要出現在控制權從 agent 交回人的那一刻——不只是掛在 session 開始、CI、或追蹤文件被編輯時 | error |
85
+ | **OWT-008** | 開放工作摘要自己的結束路徑,不論輸入為何(含「還有很多項」)都不改變回合的結果 | error |
86
+ | **OWT-009** | 摘要與一道阻斷式檢查掛同一個回合結束事件時,摘要的輸出排在阻斷判決之前 | warning |
87
+ | **OWT-010** | 判定項目是等待中、未分類、還是已丟棄,來自承載庫自定義的結構欄位,不只靠掃描散文措辭 | error |
88
+ | **OWT-011** | 以措辭啟發式補充結構欄位時,明示其涵蓋率未知,其乾淨結果不回報為「沒有漏掉」 | warning |
89
+ | **OWT-012** | 超過宣告門檻仍未分類的項目,在開放工作摘要裡被個別點名,不被合併進一個總數 | error |
90
+ | **OWT-013** | 項目從承載庫移除而未變成規格、追蹤項目、或任何其他具名去向時,帶一句理由。沒有理由的移除與靜默刪除無法分辨 | error |
91
+ | **OWT-014** | 本標準的每一條要求都可表述為 artefact 之間可判定的關係。不能如此表述的要求不得進入本標準 | error |
92
+ | **OWT-015** | 被提出作為本標準任一要求之證據的檢查,已被觀察到對一個刻意違反該要求的樣本回報失敗。從未紅過的檢查不是可採信的證據 | error |
93
+ | **OWT-016** | 本標準各要求所引用的任何窗口或閾值,載明來歷,或標為未校準 | warning |
94
+
95
+ ---
96
+
97
+ ## 收件幾乎不能有成本
98
+
99
+ **OWT-001** 之所以存在,是因為多一個必填欄位的收件點,量測到的結果是**不被使用**。
100
+ 這不是假想的摩擦——它是「工作進行中冒出新想法,記下它要跟正在做的事搶時間」這個情境的具體形狀。
101
+ 在**輸入當下**就要求分類、優先級或負責人,是在賭「正在被打斷的人願意付那個成本」,
102
+ 而這個賭注輸的次數比贏的多;一個沒有人用的收件點不是收件點,是一張表單。
103
+
104
+ 分類(決定項目屬於哪裡)是另一個、之後才做的動作。**OWT-012** 與 **OWT-013**
105
+ 規範分類永遠不來時會發生什麼:項目不准永遠隱形地待著,也不准無理由地消失。
106
+
107
+ ---
108
+
109
+ ## 沒有解除條件的等待項目,是戴著狀態標籤的遺忘項目
110
+
111
+ **OWT-002** 指出「暫停中、有東西會讓它回來」與「暫停中、永遠、只是貼了一個讓它看起來不像永遠的標籤」
112
+ 之間的差別。解除條件應盡可能是**機器看得見的**——一個日期、一個會出現的識別字、一個檔案存在——
113
+ 讓項目有機會自己跳出來,而不是依賴某個人記得它存在。真的找不到機器看得見的條件時,
114
+ 仍然要求一個人看得懂的條件;**OWT-002 不要求自動化,只要求那個條件被記下來這件事本身**。
115
+
116
+ ---
117
+
118
+ ## 戳比事實好寫,而只讀戳的檢查分不出兩者
119
+
120
+ 這是 DEX-006 在另一個 artefact 上點名的同一種失敗,只是換了一層。DEX-006 那邊,
121
+ 識別字的存在被誤讀成它指向的出口是對的;這裡,**生成區段的時間戳很新,被誤讀成內容是新的**——
122
+ 而這兩者分歧的方式,對任何只比較日期的檢查是隱形的:
123
+
124
+ - 戳比內容舊:拿戳跟檔案自己的修改紀錄一比就抓到,微不足道。
125
+ - 戳**比內容新**,而內容本身已經過期:**隱形**,因為「戳是新的」正是一次正確對帳看起來的樣子。
126
+
127
+ **OWT-004** 要求「這是最新的」這句宣稱可以從內容本身被證明——例如儲存一份該區段
128
+ 是從哪個來源生成的雜湊、放在區段旁邊,這樣不比對內容也能偵測到不一致,
129
+ 不必信任「最後動手改日期的人也真的對過帳」。**OWT-005** 要求「內容可證明是最新的」
130
+ 與「日期這麼說、內容未驗證」永遠不共用同一個通過/失敗位元,理由與 DEX-005/DEX-006
131
+ 要求延後項目出口做同一件事相同:一個被回報成通過的未知,比一個被回報成未知的未知更糟,
132
+ 因為後者還找得到。
133
+
134
+ ---
135
+
136
+ ## 涵蓋率必須聲明自己的盲區
137
+
138
+ **OWT-006** 要求任何「還有 N 項」的數字旁邊,同時印出它看得見多少來源、看不見多少來源——
139
+ 不是因為預期看不見的數字會是零,而是因為讀者分不出「涵蓋率 11.7%,而且有 386 項
140
+ 對這個數字完全隱形」與「涵蓋率 11.7% 就是全貌」,除非分母被印在旁邊。
141
+ 一個沒有聲明盲區的涵蓋率數字,預設會被讀成完整——而那個預設正是這條要求要防的失效。
142
+
143
+ ---
144
+
145
+ ## 確認點是一份報告,不是一道閘門
146
+
147
+ **turn-completion-integrity**([TCI](turn-completion-integrity.md))與本標準的 OWT-007–OWT-009
148
+ 都掛在同一個事件——agent 的回合結束、控制權交回人類的那一刻——而它們被刻意設計成
149
+ **行為相反**。把兩者接到同一個事件卻不理解為什麼不同,會產出「擋在一件幾乎永遠為真的事情上的
150
+ 確認點」,或是「被誤認成閘門的報告」,兩者都不對:
151
+
152
+ | | [turn-completion-integrity](turn-completion-integrity.md) | 本標準(OWT-007–009) |
153
+ |---|---|---|
154
+ | 它在看什麼 | agent 自己最後一則訊息,看有沒有一個第一人稱承諾被說出口又被放棄 | 承載庫裡的任何項目,看有沒有沒解除條件的、沒出口的、或過門檻還沒分類的 |
155
+ | 預設狀態 | 罕見——只在那則訊息裡明確做了承諾又被丟下時才觸發 | 常見——「還有工作沒做完」幾乎永遠為真 |
156
+ | 違反時會怎樣 | 擋住回合結束,直到承諾被解決或說明卡在誰身上 | 永不阻斷。只能回報(OWT-008) |
157
+ | 為什麼行為相反 | 它在看的事件本身夠稀少,擋在它上面不會把耐性用完 | TCI 自己的規則已經寫出這裡不能做成閘門的理由:**「一個在每個回合都為真的閘門會被關掉,關掉之後它什麼都不保護」**(TCI R4)。開放工作非空幾乎永遠為真,所以這個確認點被設計成永不保留控制權 |
158
+ | 兩者掛同一事件時的順序 | — | 先回報(OWT-009),所以即使那個回合隨後被 TCI 擋下,它的輸出仍然可見 |
159
+
160
+ ---
161
+
162
+ ## 錨點:走訪結構,不走訪措辭
163
+
164
+ 判定一個項目是等待中、未分類、還是已丟棄,要**讀承載庫自己描述那個狀態的結構欄位**——
165
+ 一個狀態欄、一個型別化標記、一個小節標題——與 [deferred-item-exit](deferred-item-exit.md)
166
+ 的 DEX-007 要求走訪文件結構而非措辭來找延後項目是同一個道理。**OWT-010** 要求那個結構欄位
167
+ 存在,並且是真相的主要來源。
168
+
169
+ 一次自由文字措辭掃描(「含有『等待』這個詞」)可以正當地補充結構欄位——
170
+ 它能抓到那些寫進散文、從沒真的填進結構欄位的項目。但它繼承了 [class-level-fix](class-level-fix.md)
171
+ 對任何列舉清單指出的同一個限制:**它正確到下一個成員用清單沒預料到的寫法出現為止。**
172
+ **OWT-011** 要求它的涵蓋率明示為未知,且禁止它跑出乾淨結果就被回報成「沒有漏掉」。
173
+
174
+ ---
175
+
176
+ ## 一條無法被檢查的要求,不是這裡的要求
177
+
178
+ **OWT-014** 是對本標準自身內容的約束,與 [deferred-item-exit](deferred-item-exit.md) 的
179
+ DEX-003 扮演的角色相同。上面每一條都指名了 artefact 與它們之間可被判定的關係。
180
+ 一個本標準在意、卻無法這樣措辭的性質,會被排除在表格之外,而不是被寫成一條無法執行的期望。
181
+ 舉一例:「收件點真的有被使用」正是 OWT-001 存在要保護的結果,但那是一句關於人類長期行為的宣稱,
182
+ 不是某個時間點上 artefact 之間可判定的關係——所以它以散文形式出現在這裡,
183
+ 作為 OWT-001 存在的**理由**,而不是一條有編號的要求。
184
+
185
+ ### 一支從未紅過的檢查
186
+
187
+ **OWT-015** 原封不動地延續 [deferred-item-exit](deferred-item-exit.md) 的 DEX-004:
188
+ **一支從未失敗過的檢查,與一支不可能失敗的檢查,輸出一模一樣。** 在一支被宣稱為上面
189
+ 任一要求之證據的檢查,被觀察到「對一個刻意違反該要求的樣本回報失敗」之前,
190
+ 它的通過只是「有東西跑過」的證據,不是「要求成立」的證據。產生這份證據的程序、
191
+ 以及為何必須逐條而非整體進行,此處不複述——見 [class-level-fix](class-level-fix.md)
192
+ 與 [verification-evidence](verification-evidence.md)。
193
+
194
+ ### 閾值必須帶著來歷
195
+
196
+ **OWT-016** 延續 DEX-009:一個沒有來歷的閾值,是一個沒有人能評估要不要改的閾值。
197
+ 本標準自己的兩個數字閾值在下方〈[證據與校準](#證據與校準)〉裡照此標示,而非被斷言為已定案。
198
+
199
+ ---
200
+
201
+ ## 反模式
202
+
203
+ | 反模式 | 為什麼會失敗 |
204
+ |---|---|
205
+ | 三個以上必填欄位的收件表單 | 可量測地不再被使用;那份摩擦由正在打斷自己工作的人承擔 |
206
+ | 「之後再看」而沒有解除條件 | 與被忘記無法分辨;沒有東西會讓它回來 |
207
+ | 手動輸入、重複 git 或 CI 已知資訊的狀態 | 兩個擁有者,其中一個永遠不會被更新 |
208
+ | 沒有內容證明的「最後對過帳」日期 | 內容真的被重新核對過,跟日期只是被打上去,看起來一模一樣 |
209
+ | 「還有 47 項」而不寫分母 | 預設被讀成完整;看不見的大多數被誤讀成「都做完了」 |
210
+ | 確認點掛在 shell 啟動而不是回合結束 | 只要沒人剛好開新 shell,它就持續漂移 |
211
+ | 確認點擋住回合結束、理由是「還有工作沒做完」 | 每個回合都會觸發;永遠為真的閘門會被關掉,關掉之後什麼都不保護 |
212
+ | 分類狀態只靠散文措辭判讀 | 正確到某個項目用清單沒預料到的方式寫出來為止 |
213
+ | 項目從承載庫裡無聲消失 | 與一個弄丟它的 bug 無從分辨 |
214
+
215
+ ---
216
+
217
+ ## 什麼在執行本標準
218
+
219
+ **UDS 側沒有任何東西在執行,而這件事是被記錄的,不是被暗示的。** UDS 陳述一個承載開放工作的地方
220
+ 必須滿足的關係;有沒有東西去判定它,依上面的[寫法約束](#本標準的寫法以及為什麼這樣寫),
221
+ 是採用專案的決定——與 [deferred-item-exit](deferred-item-exit.md) 對自己出口劃的界線相同。
222
+
223
+ 本標準做的事,是讓那個決定顯形:OWT-014 保證這裡每一條**能**被判定,OWT-015 固定
224
+ 「一次判定要算數需要什麼」,OWT-005/OWT-011 固定「一次不完整的判定容許印出什麼」。
225
+
226
+ ---
227
+
228
+ ## 證據與校準
229
+
230
+ 本標準的形狀來自一個採用專案在標準草擬**同一天**做出並實跑的觀察(XSPEC-427,2026-09-23):
231
+ 一個收件點、一支帶自測臂的摘要腳本、一個掛在回合結束的 hook,當天第一次建立並執行。
232
+ **寫下這段文字時,那個參考實作只有幾小時大、只有一個使用者、只在一個 repo 跑過。**
233
+ 它在此被引用,僅作為要求形狀的出處,**絕不作為下面具體閾值的驗證**。
234
+
235
+ - **OWT-001 的「不超過兩個欄位」**與**OWT-012 的「過了宣告的門檻」**(在原始觀察中以兩週為例)
236
+ 依 OWT-016 是**初始判斷,不是量測結果**——兩個欄位跟三個欄位、兩週跟四週的未分類門檻,
237
+ 目前都沒有對照比較過。
238
+ - 依實際使用情況重新校準這兩個數字、或將其中任一個降級為專案特定指引,是採用專案自己的決定
239
+ 與自己的時程——本標準不承諾這件事,如同它不附帶閘門一樣。
240
+
241
+ ---
242
+
243
+ ## 與其他標準的關係
244
+
245
+ - [deferred-item-exit](deferred-item-exit.md) — 同一個形狀的上游一半:DEX 要求延後項目離開文件、
246
+ 抵達可追蹤的出口,並刻意不規定出口的載體。本標準接手**出口存在之後**的事,
247
+ 要求那個載體自己不要變成下一份東西會不見的文件。
248
+ - [turn-completion-integrity](turn-completion-integrity.md) — 掛在同一個事件(回合結束)
249
+ 上,且被設計成行為相反:TCI 擋在一個罕見、明確的被放棄承諾上;本標準的確認點
250
+ (OWT-007–OWT-009)永不阻斷,因為它在看的條件幾乎永遠為真。見〈[對照表](#確認點是一份報告不是一道閘門)〉。
251
+ - [class-level-fix](class-level-fix.md) — OWT-011 揭露的措辭清單限制的通則形式,
252
+ 也是 OWT-015 所要求「非空跑證據」程序的來源。
253
+ - [verification-evidence](verification-evidence.md) — OWT-015 所依賴的 exit code
254
+ 與證據有效性推理的來源;也是 OWT-006/OWT-011 的部分涵蓋例外該被登記的地方,
255
+ 而不是揭露一次就放著。
@@ -1,6 +1,6 @@
1
1
  # UDS 速查表
2
2
 
3
- > Quick reference for all UDS features | Last updated: 2026-09-14
3
+ > Quick reference for all UDS features | Last updated: 2026-09-23
4
4
 
5
5
  **Language**: [English](../../../docs/user/CHEATSHEET.md) | 繁體中文 | [简体中文](../../zh-CN/docs/CHEATSHEET.md)
6
6
 
@@ -260,6 +260,7 @@
260
260
  | `mutation-testing` | Mutation testing evaluates test suite effectivenes |
261
261
  | `no-cicd-deployment` | No-CI/CD Deployment Strategy |
262
262
  | `observability-standards` | Observability Standards |
263
+ | `open-work-tracking` | The deferred-item-exit standard requires that a de |
263
264
  | `packaging-standards` | This standard defines a Recipe-based packaging fra |
264
265
  | `performance-standards` | This standard defines comprehensive guidelines for |
265
266
  | `pii-classification` | PII Classification and Handling Standards |