universal-dev-standards 6.13.0 → 6.14.0-beta.1

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 (30) hide show
  1. package/bundled/ai/standards/open-work-tracking.ai.yaml +69 -4
  2. package/bundled/ai/standards/turn-completion-integrity.ai.yaml +14 -7
  3. package/bundled/core/open-work-tracking.md +111 -8
  4. package/bundled/core/turn-completion-integrity.md +58 -11
  5. package/bundled/hooks/check-turn-completion-agy.mjs +147 -0
  6. package/bundled/locales/zh-CN/CHANGELOG.md +29 -3
  7. package/bundled/locales/zh-CN/README.md +1 -1
  8. package/bundled/locales/zh-CN/SECURITY.md +2 -1
  9. package/bundled/locales/zh-CN/core/turn-completion-integrity.md +46 -13
  10. package/bundled/locales/zh-CN/docs/CHEATSHEET.md +4 -1
  11. package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +9 -8
  12. package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +9 -6
  13. package/bundled/locales/zh-TW/CHANGELOG.md +29 -3
  14. package/bundled/locales/zh-TW/README.md +1 -1
  15. package/bundled/locales/zh-TW/SECURITY.md +2 -1
  16. package/bundled/locales/zh-TW/core/open-work-tracking.md +88 -9
  17. package/bundled/locales/zh-TW/core/turn-completion-integrity.md +46 -13
  18. package/bundled/locales/zh-TW/docs/CHEATSHEET.md +4 -1
  19. package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +9 -8
  20. package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +9 -6
  21. package/package.json +1 -1
  22. package/src/commands/init.js +15 -2
  23. package/src/commands/uninstall.js +1 -1
  24. package/src/commands/update.js +23 -12
  25. package/src/installers/hooks-installer.js +89 -2
  26. package/src/reconciler/desired-state-calculator.js +84 -1
  27. package/src/reconciler/plan-executor.js +34 -1
  28. package/src/uninstallers/hook-uninstaller.js +107 -4
  29. package/src/utils/integration-generator.js +97 -19
  30. package/standards-registry.json +8 -8
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * UDS Hook: Turn Completion Integrity — Antigravity CLI (agy) adapter
4
+ *
5
+ * Runs when the agent is about to stop. Blocks when the agent's final message
6
+ * states a first-person commitment to a next action that the turn then ended
7
+ * without taking.
8
+ *
9
+ * Contract (Antigravity CLI Stop hook — https://antigravity.google/docs/hooks/,
10
+ * fetched 2026-09-29, and OBSERVED against a real session the same day: agy
11
+ * 1.2.12 on PC15, `agy -p`, evidence kept in dev-platform
12
+ * cross-project/ops/evidence/agy-stop-hook-2026-09-29/):
13
+ * config — <repo>/.agents/hooks.json (or ~/.gemini/config/hooks.json). The
14
+ * file maps a hook NAME to its events:
15
+ * {"<name>": {"Stop": [{"type":"command","command":"...","timeout":N}]}}
16
+ * There is no `hooks` wrapper key and no `hooks[]` nesting around the
17
+ * handler, unlike Claude Code / Codex. `timeout` is in seconds.
18
+ * stdin — JSON with artifactDirectoryPath, conversationId, error,
19
+ * executionNum (from 0), fullyIdle, modelName, terminationReason,
20
+ * transcriptPath, workspacePaths. 🔴 It carries NEITHER the final
21
+ * message NOR the human's message: both come from the transcript.
22
+ * transcript — JSONL, one record per line with source / type / content:
23
+ * the human's message = source USER_EXPLICIT, type USER_INPUT,
24
+ * content wrapped in <USER_REQUEST>…</USER_REQUEST>
25
+ * and followed by <ADDITIONAL_METADATA> etc.
26
+ * the model's reply = source MODEL, type PLANNER_RESPONSE
27
+ * a `continue` reason = source SYSTEM, type SYSTEM_MESSAGE
28
+ * output — {"decision":"continue","reason":"..."} restarts the loop (the
29
+ * reason reaches the model); anything else lets it stop. This
30
+ * adapter writes "{}" on every allow path so stdout is always
31
+ * valid JSON.
32
+ *
33
+ * 🔴 The human's last message is taken from USER_EXPLICIT/USER_INPUT ONLY.
34
+ * This hook's own `continue` reason is written back into the transcript as a
35
+ * SYSTEM_MESSAGE; reading "any non-MODEL record" as the human would take the
36
+ * hook's own text for the human's words (R11, same family as the Claude Code
37
+ * block-message echo). Filtering by `source` is the guard; the SELF_ECHO check
38
+ * below is a second, weaker one.
39
+ *
40
+ * 🔴 agy runs the hook with the working directory set to `.agents/`, not the
41
+ * project root (measured 2026-09-29, agy 1.2.12), and silently lets a hook that
42
+ * fails to start through — hence the installed command `node ../scripts/hooks/...`.
43
+ * Nothing here or in the engine reads process.cwd(): packs load relative to the
44
+ * module, state lives under ~/.uds (or UDS_TURN_COMPLETION_STATE_DIR), and the
45
+ * transcript path from stdin is absolute. Tests run the adapter from `.agents/`.
46
+ *
47
+ * At the moment the hook runs, the transcript ALREADY holds the model's final
48
+ * reply (observed, single turn, no tool calls). This is the opposite of Claude
49
+ * Code, where it does not (see check-turn-completion.mjs). Not verified: multi-
50
+ * turn, turns with tool calls, fullyIdle:false, a non-empty `error`, interactive
51
+ * mode. If the final reply is not yet in the transcript in one of those cases,
52
+ * this adapter would judge the previous reply — see the standard's Supported
53
+ * harnesses section.
54
+ *
55
+ * No `executionNum > 0` loop guard is used (unlike stop_hook_active on the
56
+ * other adapters): whether executionNum resets between turns in a long
57
+ * interactive session is unverified, and a guard that never resets is a delayed
58
+ * off switch. The engine's cooldown and rolling window (R6) bound the loop.
59
+ *
60
+ * Judgement (packs, cooldown, rolling window, self-echo) lives in
61
+ * turn-completion/engine.mjs and is shared with every other adapter.
62
+ *
63
+ * Usage: node check-turn-completion-agy.mjs (reads stdin)
64
+ * node check-turn-completion-agy.mjs --self-test
65
+ * node check-turn-completion-agy.mjs --languages
66
+ *
67
+ * @see core/turn-completion-integrity.md
68
+ */
69
+ import { readFileSync } from 'node:fs';
70
+ import { decide, isSelfEcho, runSelfTest, printLanguages } from './turn-completion/engine.mjs';
71
+
72
+ /**
73
+ * The human's words inside a USER_INPUT record: the text between
74
+ * <USER_REQUEST> and </USER_REQUEST>. Everything after the closing tag
75
+ * (<ADDITIONAL_METADATA>, <USER_SETTINGS_CHANGE>, ...) is system-added and is
76
+ * dropped. A record with no tag is taken whole (defensive: a different agy
77
+ * version may not wrap it).
78
+ */
79
+ export function unwrapUserRequest(content) {
80
+ if (typeof content !== 'string') return '';
81
+ const m = content.match(/<USER_REQUEST>([\s\S]*?)<\/USER_REQUEST>/);
82
+ if (m) return m[1].trim();
83
+ const open = content.indexOf('<USER_REQUEST>');
84
+ if (open !== -1) {
85
+ // opening tag without a close: take what follows, up to the next system block
86
+ const rest = content.slice(open + '<USER_REQUEST>'.length);
87
+ const next = rest.search(/<(ADDITIONAL_METADATA|USER_SETTINGS_CHANGE|SYSTEM_MESSAGE)>/);
88
+ return (next === -1 ? rest : rest.slice(0, next)).trim();
89
+ }
90
+ return content.trim();
91
+ }
92
+
93
+ /**
94
+ * Last model reply and last human message in an agy transcript_full.jsonl.
95
+ * Unparseable lines are skipped; a read failure throws to the caller.
96
+ */
97
+ export function lastMessages(transcriptPath) {
98
+ let assistant = '';
99
+ let user = '';
100
+ for (const line of readFileSync(transcriptPath, 'utf8').split('\n')) {
101
+ if (!line.trim()) continue;
102
+ let ev;
103
+ try { ev = JSON.parse(line); } catch { continue; }
104
+ if (!ev || typeof ev.content !== 'string') continue;
105
+ if (ev.source === 'MODEL' && ev.type === 'PLANNER_RESPONSE') {
106
+ if (ev.content.trim()) assistant = ev.content;
107
+ } else if (ev.source === 'USER_EXPLICIT' && ev.type === 'USER_INPUT') {
108
+ const text = unwrapUserRequest(ev.content);
109
+ if (text && !isSelfEcho(text)) user = text;
110
+ }
111
+ }
112
+ return { assistant, user };
113
+ }
114
+
115
+ async function main() {
116
+ let out = {};
117
+ try {
118
+ const raw = readFileSync(0, 'utf8');
119
+ const data = JSON.parse(raw);
120
+ if (data && typeof data === 'object' && typeof data.transcriptPath === 'string' && data.transcriptPath) {
121
+ const { assistant, user } = lastMessages(data.transcriptPath);
122
+ const verdict = await decide({
123
+ sessionId: data.conversationId,
124
+ assistantText: assistant,
125
+ userText: user,
126
+ });
127
+ if (verdict.fire) out = { decision: 'continue', reason: verdict.reason };
128
+ }
129
+ } catch {
130
+ /* R5: fail open — stdout stays valid JSON, the agent stops */
131
+ }
132
+ process.stdout.write(JSON.stringify(out));
133
+ }
134
+
135
+ const arg = process.argv[2];
136
+ if (arg === '--self-test') {
137
+ process.exit((await runSelfTest('turn-completion-agy')) ? 0 : 1);
138
+ } else if (arg === '--languages') {
139
+ await printLanguages();
140
+ } else {
141
+ try {
142
+ await main();
143
+ } catch {
144
+ // R5, belt and braces — see check-turn-completion-codex.mjs.
145
+ process.stdout.write('{}');
146
+ }
147
+ }
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  source: ../../CHANGELOG.md
3
- source_version: 6.13.0
4
- translation_version: 6.13.0
5
- last_synced: 2026-09-27
3
+ source_version: 6.14.0-beta.1
4
+ translation_version: 6.14.0-beta.1
5
+ last_synced: 2026-09-29
6
6
  status: current
7
7
  ---
8
8
 
@@ -17,6 +17,32 @@ status: current
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [6.14.0-beta.1] - 2026-09-29
21
+
22
+ > **测试版**——以 `npm install -g universal-dev-standards@beta` 安装。要测什么、如何退回正式版:[docs/PRE-RELEASE.md](../../docs/PRE-RELEASE.md)。
23
+ >
24
+ > **已知限制(2026-09-29 把安装包装进全新项目实测发现):** Antigravity CLI 的关卡**只有**在“**全新**项目、且已经有 `.agents/AGENTS.md`”时,由 `uds init --with-hooks` 装上(init 靠这个文件判断项目在用 Antigravity)。既有项目执行 `uds update` **不会**补装,而 `uds init` 不能对同一个项目跑第二次。因此这个测试版里,既有项目拿不到 agy 关卡;预计下一版修正。
25
+
26
+ ### Added
27
+
28
+ - **`open-work-tracking` 1.1.0:在 OWT-016 之后新增三条要求——意图与进度分开存放、意图被修改要留痕、下一步要点名对象。** OWT-017(warning):承载一件工作之目标、验收条件或限制的载体,不同时承载它的进度或下一步,以遍历各载体的结构判定、绝不看文件名,所以更新进度不必碰目标。OWT-018(error):对该意图的每次修改都留下改了什么、谁核可、为什么的记录;没有核可者的修改在 OWT-007 交回点被列出、不得静默,且列出永不阻断(OWT-008)。OWT-019(warning):「下一步」字段点名文件路径、测试名称、命令或需求编号之一,只有动词不算;这个检查判断有没有点名对象,不判断句子写得好不好。严重度的理由写在标准里。标准也记下对促成本次修改之提示词刻意**不**采纳的部分——那是用户转贴、作者不明、没有实现的文字,只借了设计形状:以手写状态文件当状态真相(会过期,而戳比过期内容新是隐形的)、固定的开工仪式(由各代理工具设置,且会变成没有任何 artefact 检查判定得了的要求)。新增 `scripts/check-open-work-tracking.mjs`,是这三条要求的参考判定程序,作为 OWT-015 证据而非闸门提供(UDS 仍不设闸门,也没有接进 `pre-release-check.sh`):`next-action` 报告「点名且已找到/点名但未找到/未点名」,`revision` 比对两个版本(或一个文件对 `--base <git rev>`)的验收/目标/限制区段并要求一条新增且完整的记录、把没有核可者的修改列给交回点,`separation` 检查没有任何载体同时装着两者。它判定前先跑自己的自测臂、判定不了时 exit 2(不是 0),并写明自己判定不了的事——记录是否诚实描述了修改、被点名的对象是否正确。**每次跑测试都被观察到会红:**测试套件复制该脚本、改它的源码文字,要求对真脚本通过的断言对 17 个突变版失败(每条要求的永远通过与永远失败、每个辨认分支逐一关掉、旧记录被当成新记录、不完整的记录被接受)。**未校准(OWT-016):标题词汇、命令清单、扩展名清单与编号样式都是初始判断,不是量测**——例如 `已知限制` 会被读成限制区段;采用者应传入自己的编号样式。在真实历史上重放,它报告 XSPEC-436 的验收条件有变动而没有修订记录,以及 dev-platform 工作记录里一条未点名的下一步。
29
+
30
+ - **`turn-completion-integrity` 1.5.0:Antigravity CLI(`agy`)现已支持,依据是真实会话观察到的契约。** 这份标准过去写 agy「尚未支持」,因为它的 Stop hook 契约还没被观察过(R3:不对未经观察的契约出适配层)。2026-09-29 已观察(agy 1.2.12、`agy -p`、单轮、无工具调用),适配层 `scripts/hooks/check-turn-completion-agy.mjs` 建立在那次实跑的产出上,而不只是文档:hook 传入数据只有 `transcriptPath`,所以最后一条回复取最后一条 `MODEL`/`PLANNER_RESPONSE`,人的消息取最后一条 `USER_EXPLICIT`/`USER_INPUT`(从 `<USER_REQUEST>` 内取出,后面的系统区块丢掉)。`SYSTEM_MESSAGE` 记录绝不当成人说的话——agy 会把这个 hook 自己的 `continue` 理由写回成这种记录,读成人的话会让 R9 叫停豁免失效。拦截是 `{"decision":"continue","reason":...}`,放行是 `{}`,所有失败路径都放行。`uds init --with-hooks` 在选了 Google Antigravity 时写入 `.agents/hooks.json`(遇到无法解析的 `hooks.json` 不覆盖),`uds uninstall` 只移除 UDS 自己的 handler、保留用户其他 hook。**已验证范围:单轮、无工具调用、`agy -p`。未验证:多轮、含工具调用的回合、交互模式、`fullyIdle: false`、`error` 非空、`.agents/hooks.json` 是否需要已登记的 Antigravity 项目、以及工作目录是否永远是 `.agents/`**——标准、适配层与安装输出都写明了这一点。**同日实测:agy 执行 hook 时的工作目录是 `.agents/`(不是项目根目录),且对启动失败的 hook 静默放行,所以安装的命令是 `node ../scripts/hooks/check-turn-completion-agy.mjs`。**
31
+
32
+ ## [6.13.1] - 2026-09-28
33
+
34
+ > **修补版**:修复 6.13.0 暴露的两个“以 `uds update` 升级既有项目”的缺陷(繁中的提交消息语言段落变成英文;AGENTS.md 被改写成另一种格式且少了“这是索引”提醒),并新增一道发版前检查,实际从上一个正式版升级一次。**若你已用 `uds update` 升到 6.13.0,请在升级至 6.13.1 后再执行一次 `uds update`**,以还原那些段落。
35
+
36
+ ### 新增
37
+
38
+ - **`scripts/check-upgrade-fidelity.sh`,已接入 `pre-release-check.sh` 第 24 步:每次发版前跑一次真实的跨版本 `uds update` 升级检查。** 上面修复的两个缺陷有同一个共同形状——只有"既有项目、已经被上一个正式版更新过,再对更新版执行 `uds update`/`uds update --apply`"时才会发作——而 pre-release-check.sh 其余 31 步与 CI 全都没抓到,因为没有任何一步做真正的跨版本升级:`uds init` 是全新跑一次(没有东西可以回归);`uds update` 对照的 bundled registry 版本又跟 manifest 已记录的版本相同,会在走到出问题的那段代码前就提前返回。此检查用真实、已发布在 npm 上的上一个正式版建立三种项目形状(对应三个真的踩到这两个缺陷的项目),分别用一般 `uds update -y` 与 `uds update --apply` 让待检查的 CLI 升级,并断言:UDS 标记区块外的内容永不改变;区块内只允许一次真实升级该有的标准清单/数量变化;CLAUDE.md 的提交消息语言标题逐字不变(不是"有出现"就算过);"这只是索引"的提醒存在;一般 update 与 `--apply` 对"该用哪个生成器"意见一致;连续两次 `--apply`,第二次不再有任何变化。npm 连不上或上一版从未发布时**直接失败**(结束码 2,不是跳过)——这个检查唯一的价值就是跑一次真实的发布版,没有它却悄悄回报通过,正是要堵住的那个盲点重新打开。已双向验证:用 `--cli="npx -y universal-dev-standards@6.13.0"` 重现了上面两个缺陷(CLAUDE.md 语言被换掉、AGENTS.md 生成器被换掉),并打印出实际差异;本机开发版 CLI(已套用 commit `e1524872` 与 `8373207d`)在三种形状上全部干净通过。
39
+
40
+ ### 修复
41
+
42
+ - **一般(非 `--apply`)的 `uds update -y` 会把项目 CLAUDE.md 里繁体中文的提交消息标题悄悄换成英文版,`--plan --integrations-only` 的预演差异也可能忽略项目的显示语言设置。** `updateCommand` 主流程与其 `--plan` 预演各自独立地只用 `output_language`/`commit_language`(提交消息语言)推导集成区块的内容语言,完全忽略 `display_language`(`uds init` 与 reconciler 一直用来决定"你想读哪种语言"的设置)。一个以 `display_language: zh-tw` 与 `output_language: bilingual` 安装的项目——一种常见组合——因此从 `init` 拿到正确的"## 提交訊息語言"标题(繁体),却在下一次一般 `uds update` 拿到"## Commit Message Language",丢掉了原本正确的语言选择。已对两个真实采用者(asiaostrich-telemetry-server、EngramGraph)从 6.12.0 升到 6.13.0 实测验证。此缺陷早于 6.13.0 就存在(自 2026-03-25 的 commit `ad555d41` 起),且在 `uds update` 对一个已是最新版的项目执行时完全隐形——因为那种情况下它在走到这段代码前就提前返回——只有在真正跨版本升级时才会发作,这正是它看起来像 6.13.0 新回归的原因。`buildToolIntegrationConfig`(`--apply`/reconciler 使用)在 2026-09-16 已修好正确的推导逻辑;现在剩下的两个调用点都改用新增的 `resolveIntegrationLanguage(manifest)` 共用同一份逻辑。新增的回归测试对着真实临时项目与真正的生成器(无 mock)重现了确切的缺陷,另有一支静态守卫测试,只要那段旧的内嵌推导在 CLI 源码任何地方重新出现就会变红。
43
+ - **`uds update --apply`(reconciler)只要项目曾经由 `generateAgentsMd` 写出过 AGENTS.md,就会把它整份改写成完全不同、opencode 样式的文档——即使是在刚跑完 `uds init` 后紧接着的第一次 `--apply`,其他什么都没改也一样。** `desired-state-calculator.js` 的 `calculateIntegrations` 会把 `manifest.integrations` 里任何叫做 `AGENTS.md` 的条目,通过 `resolveToolKey` 解析成 `opencode` 这个工具——不论 opencode(或它的别名 `codex`)是否真的被选为 AI 工具。`uds init` 只要通用摘要写出过一次,就一定会把 `AGENTS.md` 记进 `manifest.integrations`(那只是一个追踪标记,不是工具选择的记录),所以每一个 `generateAgentsMd: true` 而且没选 codex/opencode 的项目都受影响。依生成器本身 2026-08-20 加入的设计说明:per-tool 模板本来就该只在真的选了 codex 或 opencode 时才取代通用摘要。已在三个真实项目(asiaostrich-telemetry-server、EngramGraph、dev-platform 自己的 `.standards/`)上确认,三者的 `aiTools` 都不含 codex/opencode。`calculateIntegrations`(与 `plan-executor.js` 的 `executeMigrateBlock`)现在会先检查工具是否真的被选,没有的话改用一般 `uds update` 本来就在用的同一个 `writeAgentsMdSummary`——`--apply` 与一般 `uds update` 现在会一致。新增的回归测试驱动真正的 `uds init`/`uds update`(无 mock);已对还原修正的版本确认会红,其中一支"第二次 `--apply`"幂等性检查还额外抓到了修正过程中自己引入的一个哈希不收敛问题(见下一条)。
44
+ - **通用 AGENTS.md 摘要"这个文件是索引,不是标准本文"的提醒(2026-08-18 加入)从未送到既有项目的受管区块——只到了文件头,而文件头在文件已存在时,标记式更新从来不会重新生成。** `writeAgentsMdSummary` 对已存在的文件,永远只替换 `<!-- UDS:STANDARDS:START/END -->` 两个标记之间的内容;提醒却写在标记外的文件头。已对两个真实采用者(asiaostrich-telemetry-server、EngramGraph)实测:不论更新前后,提醒在文件头和区块里都不存在。提醒现在也写进标记区块内(措辞与 per-tool 生成器自己的披露文字 `generateIndexDisclosure` 对齐,不另创第三种),于是每个项目在下一次 `uds update`/`--apply`(不论是新文件还是既有文件)都会收到它。顺手把这个区块也改用 per-tool 生成器本来就在用的同一个 `wrapWithMarkers` 辅助函数组出来(而非手写标记行),过程中也修掉一个相关缺口:全新的 AGENTS.md 文件原本也从未带有"请勿手动编辑"的警告注释,因为过去只有合并路径才会加上它。
45
+
20
46
  ## [6.13.0] - 2026-09-28
21
47
 
22
48
  > **正式版**:包含下方 6.13.0-beta.1 至 beta.5 的全部内容,beta.5 之后没有任何变更。重点:回合收尾关卡(agent 说了下一步却没做就不得结束回合)现在覆盖 **Claude Code 与 Codex**,两者都以从 npm 安装的版本在真实会话中验证过(Codex 要先用 `/hooks` 信任才会执行);Claude Code 关卡真的会拦(到 beta.4 为止每个回合都放行);Windows 上可用;`uds uninstall` 会移除它;`uds init` 让提交前检查真的执行;`developer-memory` 1.2.0。Gemini CLI 标为过时(Google 已对个人账号停用,改由 Antigravity CLI 取代,后者尚未支持)。
@@ -15,7 +15,7 @@ status: current
15
15
 
16
16
  > **语言**: [English](../../README.md) | [繁體中文](../zh-TW/README.md) | 简体中文
17
17
 
18
- **版本**: 6.13.0 | **发布日期**: 2026-09-28 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
18
+ **版本**: 6.14.0-beta.1 (Pre-release) | **发布日期**: 2026-09-29 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
19
19
 
20
20
  语言无关、框架无关的软件项目文档标准。通过 AI 原生工作流,确保不同技术栈之间的一致性、质量和可维护性。
21
21
 
@@ -13,7 +13,8 @@ status: current
13
13
  <!-- UDS_SUPPORTED_VERSIONS_START -->
14
14
  | 版本 | 支持状态 |
15
15
  |------|--------|
16
- | 6.13.0 | ✅ 最新正式版 |
16
+ | 6.14.0-beta.1 | ✅ 预发布版本 |
17
+ | 6.13.1 | ✅ 最新正式版 |
17
18
  | < 6.0.0 | ❌ 已终止支持 |
18
19
  <!-- UDS_SUPPORTED_VERSIONS_END -->
19
20
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  source: ../../../core/turn-completion-integrity.md
3
- source_version: 1.4.1
4
- translation_version: 1.4.1
5
- last_synced: 2026-09-28
6
- source_hash: 0c04676006c0
3
+ source_version: 1.5.0
4
+ translation_version: 1.5.0
5
+ last_synced: 2026-09-29
6
+ source_hash: 08579653d9a4
7
7
  status: current
8
8
  ---
9
9
 
@@ -11,8 +11,8 @@ status: current
11
11
 
12
12
  > **语言**: [English](../../../core/turn-completion-integrity.md) | [繁體中文](../../zh-TW/core/turn-completion-integrity.md) | 简体中文
13
13
 
14
- **版本**: 1.4.1
15
- **最后更新**: 2026-09-28
14
+ **版本**: 1.5.0
15
+ **最后更新**: 2026-09-29
16
16
  **适用范围**: 任何由 agent 结束回合、把控制权交还给人的执行环境
17
17
  **Scope**: universal
18
18
  **行业标准**: 不声称任何来源——由实际观察到的失败归纳,见「证据」
@@ -144,13 +144,14 @@ agent 写下「我接着做 X」,然后结束回合,而 X 没有做。
144
144
  ## 支持的执行环境
145
145
 
146
146
  这个检查只在「适配层存在,且 hook 真的被接入该执行环境自己的配置」时才生效。
147
- 截至 v1.4.1:
147
+ 截至 v1.5.0:
148
148
 
149
149
  | 执行环境 | 事件 | 配置文件 | 拦截契约 |
150
150
  |---|---|---|---|
151
151
  | Claude Code | Stop | `.claude/settings.json` | stdout 输出 `{"decision":"block","reason":...}`,exit 0;沉默即放行 |
152
152
  | Codex | Stop | `.codex/hooks.json` | stdout 输出 `{"decision":"block","reason":...}`,exit 0——官方文档写明这个事件纯文本或空输出无效 |
153
153
  | Gemini CLI(过时) | AfterAgent | `.gemini/settings.json` | stdout 输出 `{"decision":"deny","reason":...}`,exit 0——官方文档标记为优先于 exit code 2 的做法 |
154
+ | Antigravity CLI(`agy`) | Stop | `.agents/hooks.json` | stdout 输出 `{"decision":"continue","reason":...}`,exit 0;`{}` 即放行 |
154
155
 
155
156
  在 Codex 上,接上了不等于会执行。Codex 会跳过项目级的 hook,直到项目被信任、**而且**
156
157
  这一支 hook 的定义在交互式 Codex 会话里通过 `/hooks` 被信任为止;信任记录绑定在定义的
@@ -173,12 +174,42 @@ agent 的最后一条消息,却不给出用户的;要拿到用户那一侧
173
174
 
174
175
  Gemini CLI 已过时。Google 于 2026-06-18 对个人账号停用 Gemini CLI,
175
176
  改由 Antigravity CLI(`agy`)取代;企业账号两者都还能用。这个适配层为那些用户保留,
176
- 但它从未在真实的 Gemini CLI 会话中验证过;使用 Google 工具的新采用者应预期的是
177
- Antigravity CLI,而它**尚未支持**。它文档记载的 Stop hook 契约,在关键之处与上表每一个
178
- 适配层都不同:hook 配置在 `.agents/hooks.json`、传入数据只有 `transcriptPath`
179
- (没有最后一条回复、也没有人的消息)、拦截是 `{"decision":"continue","reason":...}`
180
- 而不是 `block` 或 `deny`。等这份契约在真实会话中观察到之后才会加入适配层——
181
- 与下方 Cursor 没有适配层是同一个理由。
177
+ 但它从未在真实的 Gemini CLI 会话中验证过;使用 Google 工具的新采用者应使用下面的
178
+ Antigravity CLI 适配层。
179
+
180
+ Antigravity CLI 已支持,依据是真实会话观察到的契约(2026-09-29,agy 1.2.12),
181
+ 而不只是它的文档。这份契约在关键之处与上表每一个适配层都不同:
182
+
183
+ - **配置**在 `.agents/hooks.json`,以 hook 名称为键——
184
+ `{"<名称>": {"Stop": [{"type":"command","command":"...","timeout":N}]}}`,
185
+ `timeout` 单位为秒。没有 `hooks` 外层,handler 也不嵌套在 `hooks[]` 里。
186
+ - **stdin 既没有最后一条回复、也没有人的消息**,只有 `transcriptPath` 与元数据,所以两者
187
+ 都要从转录读(JSONL,每条有 `source`、`type`、`content`)。最后一条回复是最后一条
188
+ `source: MODEL`、`type: PLANNER_RESPONSE`。人的消息是最后一条
189
+ `source: USER_EXPLICIT`、`type: USER_INPUT`,取 `<USER_REQUEST>…</USER_REQUEST>` 之内的文字——
190
+ 后面接着的系统区块(`<ADDITIONAL_METADATA>` 等)不是人说的话。
191
+ - **`SYSTEM_MESSAGE` 记录绝不可当成人的消息读。** agy 会把这个 hook 自己的 `continue` 理由
192
+ 写回转录,成为这种记录(`source: SYSTEM`、`type: SYSTEM_MESSAGE`,内容为
193
+ 「Stop hook blocked termination: …」)。若把「不是模型的任何记录」都当成人,就会把 hook
194
+ 自己的话当成人说的,R9 豁免随之失效——也就是 R11 的失败,换成这份转录的形状重演。
195
+ - **拦截是 `{"decision":"continue","reason":...}`**,不是 `block` 或 `deny`;`{}` 即放行。
196
+ - **hook 执行时的工作目录是 `.agents/`,不是项目根目录**(2026-09-29 实测,agy 1.2.12)。
197
+ 因此安装的命令是 `node ../scripts/hooks/check-turn-completion-agy.mjs`;以项目根目录为准的
198
+ `node scripts/hooks/...` 会解析成 `<项目>/.agents/scripts/hooks/...`,出现
199
+ 「Cannot find module」,而且**agy 对执行失败的 hook 静默放行**——没有任何消息、stdout 照常,
200
+ 回合就这样结束。路径刻意用相对路径(这个文件本来就是要提交并共用的,绝对路径只属于某一台机器),
201
+ 也不用任何 shell 语法(`sh -c`、`$(...)`),因为 agy 是否经过 shell 执行 `command` 没有证据。
202
+ - **与 Claude Code 相反,hook 被调用时转录已经写到最后一条回复。**
203
+
204
+ 已验证:agy 1.2.12、非交互的 `agy -p`、**单轮且没有工具调用**——hook 被调用时最后一条回复
205
+ 已在转录里,`continue` 确实生效(模型又回了一轮),且没有遇到信任提示(与 Codex 不同)。
206
+ **未验证**:多轮对话、含工具调用的回合(此时最后一条 `PLANNER_RESPONSE` 是不是最后回复、
207
+ hook 执行时是否已写入)、`fullyIdle: false`、`error` 非空、交互模式、项目级
208
+ `.agents/hooks.json` 是否像 `.agents/skills/` 一样只对已登记的 Antigravity 项目生效,
209
+ 以及工作目录是否永远是 `.agents/`(只对项目级文件量测过;`uds init` 不会写用户级的
210
+ `~/.gemini/config/hooks.json`)。在未验证的情境下,适配层可能判断的是
211
+ 较早的一条回复而不是最后一条;读取失败时仍一律放行(R5)。`uds init --with-hooks` 会在安装
212
+ 那一行旁边打印已验证的范围。
182
213
 
183
214
  Cursor 已评估但不支持:截至撰写本文时,Cursor 的 stop hook 能不能真的
184
215
  拦下一个回合仍未确定,若对着一个没人验证过的契约交付一份适配层,
@@ -240,3 +271,5 @@ Cursor 已评估但不支持:截至撰写本文时,Cursor 的 stop hook 能
240
271
  - [ ] 归属词的搜索排除检查自己的标题与结构
241
272
  - [ ] 每个支持的执行环境的拦截契约都对照该环境自己的官方文档验证过,不是照搬另一个环境
242
273
  - [ ] 安装器只为采用者实际选择的执行环境写入该环境的 hook 配置
274
+ - [ ] 转录里会出现系统代写消息的执行环境,只从「人的记录」读人的消息,绝不从「不是模型写的任何东西」读
275
+ - [ ] 一份执行环境契约只对「真实会话观察过的范围」交付,并注明没观察到的范围
@@ -1,6 +1,6 @@
1
1
  # UDS 速查表
2
2
 
3
- > Quick reference for all UDS features | Last updated: 2026-09-23
3
+ > Quick reference for all UDS features | Last updated: 2026-09-29
4
4
 
5
5
  **Language**: [English](../../../docs/user/CHEATSHEET.md) | [繁體中文](../../zh-TW/docs/CHEATSHEET.md) | 简体中文
6
6
 
@@ -352,8 +352,10 @@
352
352
  | `check-docs-sync.sh` | Documentation Sync Checker |
353
353
  | `check-error-exit.mjs` | 🔴 沒填就是沒設定,而沒設定會 exit 2, |
354
354
  | `check-external-references.mjs` | External Reference Checker (SPEC-SELFDIAG-001 REQ- |
355
+ | `check-open-work-tracking.mjs` | Open-work-tracking reference checks for OWT-017 / |
355
356
  | `check-orphan-specs.ps1` | Check Orphan Specs |
356
357
  | `check-orphan-specs.sh` | Orphan Spec Detection Script |
358
+ | `check-prompt-footprint.mjs` | Prompt Footprint Ratchet — DEC-117 D2/L2 |
357
359
  | `check-scope-sync.ps1` | Check Scope Sync |
358
360
  | `check-scope-sync.sh` | Scope Consistency Check Script |
359
361
  | `check-skill-next-steps-sync.ps1` | Check Skill Next Steps Sync |
@@ -367,6 +369,7 @@
367
369
  | `check-translation-hash-ratchet.sh` | XSPEC-392 R6 棘輪:新的翻譯必須帶 source_hash,既有的欠債冷凍為基線。 |
368
370
  | `check-translation-sync.ps1` | Check Translation Sync |
369
371
  | `check-translation-sync.sh` | Translation Sync Checker |
372
+ | `check-upgrade-fidelity.sh` | Upgrade Fidelity Checker |
370
373
  | `check-usage-docs-sync.ps1` | Check if usage documentation needs to be regenerat |
371
374
  | `check-usage-docs-sync.sh` | check-usage-docs-sync.sh |
372
375
  | `check-version-sync.ps1` | Check Version Sync |
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  source: ../../../docs/CLI-INIT-OPTIONS.md
3
- source_version: 3.7.0
4
- translation_version: 3.7.0
5
- last_synced: 2026-09-26
3
+ source_version: 3.7.1
4
+ translation_version: 3.7.1
5
+ last_synced: 2026-09-29
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.7.0
14
- > **最后更新**: 2026-09-26
13
+ > **版本**: 3.7.1
14
+ > **最后更新**: 2026-09-29
15
15
 
16
16
  本文档详细说明 `uds init` 命令的每一个选项,包含使用情境、影响范围和建议选择。
17
17
 
@@ -870,16 +870,17 @@ UDS 的项目——并在 `[pre-commit]` 下回报同样的修复方式;此警
870
870
 
871
871
  `--with-hooks` 一定会安装进 `.claude/settings.json`。四个有 hook 支持的标准
872
872
  之一——`turn-completion-integrity`(见 CHANGELOG,Unreleased)——也会装进
873
- **Codex** 与 **Gemini CLI**,门槛是你有没有在 [AI 工具选择](#1-ai-工具选择)
873
+ **Codex**、**Gemini CLI**(过时)与 **Antigravity CLI**(`agy`),门槛是你有没有在 [AI 工具选择](#1-ai-工具选择)
874
874
  里选了那个工具(或用非交互模式的工具标志带入):
875
875
 
876
876
  | 工具 | 写入的配置文件 | 触发条件 |
877
877
  |------|---------------|---------|
878
878
  | Codex | `.codex/hooks.json` | 选了 **OpenAI Codex** |
879
879
  | Gemini CLI | `.gemini/settings.json` | 选了 **Gemini CLI** |
880
+ | Antigravity CLI | `.agents/hooks.json` | 选了 **Google Antigravity** |
880
881
 
881
- 没选的工具不会写入任何东西——`uds init` 不会在没用到 Codex 或 Gemini CLI
882
- 的项目里创建 `.codex/` 或 `.gemini/` 目录。其余三个有 hook 支持的标准
882
+ 没选的工具不会写入任何东西——`uds init` 不会在没用到 Codex、Gemini CLI 或 Antigravity
883
+ 的项目里创建 `.codex/`、`.gemini/` 或 `.agents/` 目录。其余三个有 hook 支持的标准
883
884
  (commit message 校验、logging、security)目前仍只支持 Claude Code;
884
885
  为什么目前只推广 turn-completion-integrity,以及 Cursor 的现状
885
886
  (已评估、不支持),见
@@ -1,7 +1,7 @@
1
1
  # UDS 功能参考手册
2
2
 
3
3
  > Universal Development Standards - 完整功能文档
4
- > Auto-generated | Last updated: 2026-09-23
4
+ > Auto-generated | Last updated: 2026-09-29
5
5
 
6
6
  **Language**: [English](../../../docs/reference/FEATURE-REFERENCE.md) | [繁體中文](../../zh-TW/docs/FEATURE-REFERENCE.md) | 简体中文
7
7
 
@@ -15,9 +15,9 @@
15
15
  4. [代理](#agents) (5)
16
16
  5. [工作流程](#workflows) (5)
17
17
  6. [核心规范](#core-standards) (153)
18
- 7. [脚本](#scripts) (59)
18
+ 7. [脚本](#scripts) (62)
19
19
 
20
- **Total Features: 351**
20
+ **Total Features: 354**
21
21
 
22
22
  ---
23
23
 
@@ -478,7 +478,7 @@
478
478
  | `deployment-standards` | 1.1.0 | This standard defines guidelines for safely deploying software to production, co |
479
479
  | `deprecation-standards` | 1.1.0 | |
480
480
  | `design-document-standards` | 1.0.0 | |
481
- | `developer-memory` | 1.1.1 | This standard defines a structured system for capturing, retrieving, and surfaci |
481
+ | `developer-memory` | 1.2.0 | This standard defines a structured system for capturing, retrieving, and surfaci |
482
482
  | `disaster-recovery-drill` | - | |
483
483
  | `documentation-lifecycle` | 1.0.0 | This standard defines **when** to update documentation, **when** to check it, an |
484
484
  | `documentation-structure` | 1.5.0 | This standard defines a consistent documentation structure for software projects |
@@ -516,7 +516,7 @@
516
516
  | `mutation-testing` | 1.1.0 | Mutation testing evaluates test suite effectiveness by injecting artificial bugs |
517
517
  | `no-cicd-deployment` | - | |
518
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 |
519
+ | `open-work-tracking` | 1.1.0 | The deferred-item-exit standard requires that a deferred item leave its document |
520
520
  | `packaging-standards` | 1.1.0 | This standard defines a Recipe-based packaging framework that enables user proje |
521
521
  | `performance-standards` | 1.2.0 | This standard defines comprehensive guidelines for software performance engineer |
522
522
  | `pii-classification` | 1.1.0 | **Status**: Active | **Updated**: 2026-06-19 | |
@@ -574,7 +574,7 @@
574
574
  | `timeout-standards` | - | |
575
575
  | `token-budget` | - | |
576
576
  | `translation-lifecycle-standards` | 1.0.1 | Translation lifecycle standards: MISSING vs OUTDATED distinction, semver-aware s |
577
- | `turn-completion-integrity` | 1.3.0 | An agent writes *"I'll do X next"* and then ends the turn without doing X. |
577
+ | `turn-completion-integrity` | 1.5.0 | An agent writes *"I'll do X next"* and then ends the turn without doing X. |
578
578
  | `user-journey-testing` | - | |
579
579
  | `user-story-mapping` | 1.0.0 | **Status**: Active | **Updated**: 2026-06-17 | |
580
580
  | `verification-evidence` | 1.3.0 | Establish an "Iron Law" that no task can be claimed as complete without verifica |
@@ -610,8 +610,10 @@
610
610
  | `check-docs-sync.sh` | Documentation Sync Checker |
611
611
  | `check-error-exit.mjs` | 🔴 沒填就是沒設定,而沒設定會 exit 2, |
612
612
  | `check-external-references.mjs` | External Reference Checker (SPEC-SELFDIAG-001 REQ-5, AC-7) |
613
+ | `check-open-work-tracking.mjs` | Open-work-tracking reference checks for OWT-017 / OWT-018 / OWT-019. |
613
614
  | `check-orphan-specs.ps1` | Check Orphan Specs |
614
615
  | `check-orphan-specs.sh` | Orphan Spec Detection Script |
616
+ | `check-prompt-footprint.mjs` | Prompt Footprint Ratchet — DEC-117 D2/L2 |
615
617
  | `check-scope-sync.ps1` | Check Scope Sync |
616
618
  | `check-scope-sync.sh` | Scope Consistency Check Script |
617
619
  | `check-skill-next-steps-sync.ps1` | Check Skill Next Steps Sync |
@@ -625,6 +627,7 @@
625
627
  | `check-translation-hash-ratchet.sh` | XSPEC-392 R6 棘輪:新的翻譯必須帶 source_hash,既有的欠債冷凍為基線。 |
626
628
  | `check-translation-sync.ps1` | Check Translation Sync |
627
629
  | `check-translation-sync.sh` | Translation Sync Checker |
630
+ | `check-upgrade-fidelity.sh` | Upgrade Fidelity Checker |
628
631
  | `check-usage-docs-sync.ps1` | Check if usage documentation needs to be regenerated |
629
632
  | `check-usage-docs-sync.sh` | check-usage-docs-sync.sh |
630
633
  | `check-version-sync.ps1` | Check Version Sync |
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  source: ../../CHANGELOG.md
3
- source_version: 6.13.0
4
- translation_version: 6.13.0
5
- last_synced: 2026-09-27
3
+ source_version: 6.14.0-beta.1
4
+ translation_version: 6.14.0-beta.1
5
+ last_synced: 2026-09-29
6
6
  status: current
7
7
  ---
8
8
 
@@ -17,6 +17,32 @@ status: current
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [6.14.0-beta.1] - 2026-09-29
21
+
22
+ > **測試版**——以 `npm install -g universal-dev-standards@beta` 安裝。要測什麼、如何退回正式版:[docs/PRE-RELEASE.md](../../docs/PRE-RELEASE.md)。
23
+ >
24
+ > **已知限制(2026-09-29 把安裝包裝進全新專案實測發現):** Antigravity CLI 的關卡**只有**在「**全新**專案、且已經有 `.agents/AGENTS.md`」時,由 `uds init --with-hooks` 裝上(init 靠這個檔案判斷專案在用 Antigravity)。既有專案執行 `uds update` **不會**補裝,而 `uds init` 不能對同一個專案跑第二次。因此這個測試版裡,既有專案拿不到 agy 關卡;預計下一版修正。
25
+
26
+ ### Added
27
+
28
+ - **`open-work-tracking` 1.1.0:在 OWT-016 之後新增三條要求——意圖與進度分開存放、意圖被修改要留痕、下一步要點名對象。** OWT-017(warning):承載一件工作之目標、驗收條件或限制的載體,不同時承載它的進度或下一步,以走訪各載體的結構判定、絕不看檔名,所以更新進度不必碰目標。OWT-018(error):對該意圖的每次修改都留下改了什麼、誰核可、為什麼的紀錄;沒有核可者的修改在 OWT-007 交回點被列出、不得靜默,且列出永不阻斷(OWT-008)。OWT-019(warning):「下一步」欄位點名檔案路徑、測試名稱、指令或需求編號之一,只有動詞不算;這個檢查判斷有沒有點名對象,不判斷句子寫得好不好。嚴重度的理由寫在標準裡。標準也記下對促成本次修改之提示詞刻意**不**採納的部分——那是使用者轉貼、作者不明、沒有實作的文字,只借了設計形狀:以手寫狀態檔當狀態真相(會過期,而戳比過期內容新是隱形的)、固定的開工儀式(由各代理工具設定,且會變成沒有任何 artefact 檢查判定得了的要求)。新增 `scripts/check-open-work-tracking.mjs`,是這三條要求的參考判定程序,作為 OWT-015 證據而非閘門提供(UDS 仍不設閘門,也沒有接進 `pre-release-check.sh`):`next-action` 回報「點名且已找到/點名但未找到/未點名」,`revision` 比對兩個版本(或一個檔案對 `--base <git rev>`)的驗收/目標/限制區段並要求一筆新增且完整的紀錄、把沒有核可者的修改列給交回點,`separation` 檢查沒有任何載體同時裝著兩者。它判定前先跑自己的自測臂、判定不了時 exit 2(不是 0),並寫明自己判定不了的事——紀錄是否誠實描述了修改、被點名的對象是否正確。**每次跑測試都被觀察到會紅:**測試套件複製該腳本、改它的原始碼文字,要求對真腳本通過的斷言對 17 個突變版失敗(每條要求的永遠通過與永遠失敗、每個辨認分支逐一關掉、舊紀錄被當成新紀錄、不完整的紀錄被接受)。**未校準(OWT-016):標題詞彙、指令清單、副檔名清單與編號樣式都是初始判斷,不是量測**——例如 `已知限制` 會被讀成限制區段;採用者應傳入自己的編號樣式。在真實歷史上重放,它回報 XSPEC-436 的驗收條件有變動而沒有修訂紀錄,以及 dev-platform 工作紀錄裡一筆未點名的下一步。
29
+
30
+ - **`turn-completion-integrity` 1.5.0:Antigravity CLI(`agy`)現已支援,依據是真實工作階段觀察到的契約。** 這份標準過去寫 agy「尚未支援」,因為它的 Stop hook 契約還沒被觀察過(R3:不對未經觀察的契約出適配層)。2026-09-29 已觀察(agy 1.2.12、`agy -p`、單輪、無工具呼叫),適配層 `scripts/hooks/check-turn-completion-agy.mjs` 建立在那次實跑的產出上,而不只是文件:hook 傳入資料只有 `transcriptPath`,所以最後一則回覆取最後一筆 `MODEL`/`PLANNER_RESPONSE`,人的訊息取最後一筆 `USER_EXPLICIT`/`USER_INPUT`(從 `<USER_REQUEST>` 內取出,後面的系統區塊丟掉)。`SYSTEM_MESSAGE` 紀錄絕不當成人說的話——agy 會把這個 hook 自己的 `continue` 理由寫回成這種紀錄,讀成人的話會讓 R9 叫停豁免失效。攔截是 `{"decision":"continue","reason":...}`,放行是 `{}`,所有失敗路徑都放行。`uds init --with-hooks` 在選了 Google Antigravity 時寫入 `.agents/hooks.json`(遇到無法解析的 `hooks.json` 不覆蓋),`uds uninstall` 只移除 UDS 自己的 handler、保留使用者其他 hook。**已驗證範圍:單輪、無工具呼叫、`agy -p`。未驗證:多輪、含工具呼叫的回合、互動模式、`fullyIdle: false`、`error` 非空、`.agents/hooks.json` 是否需要已登記的 Antigravity 專案、以及工作目錄是否永遠是 `.agents/`**——標準、適配層與安裝輸出都寫明了這一點。**同日實測:agy 執行 hook 時的工作目錄是 `.agents/`(不是專案根目錄),且對啟動失敗的 hook 靜默放行,所以安裝的指令是 `node ../scripts/hooks/check-turn-completion-agy.mjs`。**
31
+
32
+ ## [6.13.1] - 2026-09-28
33
+
34
+ > **修補版**:修正 6.13.0 暴露的兩個「以 `uds update` 升級既有專案」的缺陷(繁中的提交訊息語言段落變成英文;AGENTS.md 被改寫成另一種格式且少了「這是索引」提醒),並新增一道發版前檢查,實際從上一個正式版升級一次。**若你已用 `uds update` 升到 6.13.0,請在升級至 6.13.1 後再執行一次 `uds update`**,以還原那些段落。
35
+
36
+ ### 新增
37
+
38
+ - **`scripts/check-upgrade-fidelity.sh`,已接進 `pre-release-check.sh` 第 24 步:每次發版前跑一次真實的跨版本 `uds update` 升級檢查。** 上面修的兩個缺陷有同一個共同形狀——只有「既有專案、已經被上一個正式版更新過,再對更新版執行 `uds update`/`uds update --apply`」時才會發作——而 pre-release-check.sh 其餘 31 步與 CI 全都沒抓到,因為沒有任何一步做真正的跨版本升級:`uds init` 是全新跑一次(沒有東西可以回歸);`uds update` 對照的 bundled registry 版本又跟 manifest 已記錄的版本相同,會在走到出問題的那段程式碼前就提早返回。此檢查用真實、已發布在 npm 上的上一個正式版建立三種專案形狀(對應三個真的踩到這兩個缺陷的專案),分別用一般 `uds update -y` 與 `uds update --apply` 讓待檢查的 CLI 升級,並斷言:UDS 標記區塊外的內容永不改變;區塊內只允許一次真實升級該有的標準清單/數量變化;CLAUDE.md 的提交訊息語言標題逐字不變(不是「有出現」就算過);「這只是索引」的提醒存在;一般 update 與 `--apply` 對「該用哪個產生器」意見一致;連續兩次 `--apply`,第二次不再有任何變化。npm 連不上或上一版從未發布時**直接失敗**(結束碼 2,不是略過)——這個檢查唯一的價值就是跑一次真實的發布版,沒有它卻悄悄回報通過,正是要堵住的那個盲點重新打開。已雙向驗證:用 `--cli="npx -y universal-dev-standards@6.13.0"` 重現了上面兩個缺陷(CLAUDE.md 語言被換掉、AGENTS.md 產生器被換掉),並印出實際差異;本機開發版 CLI(已套用 commit `e1524872` 與 `8373207d`)在三種形狀上全部乾淨通過。
39
+
40
+ ### 修正
41
+
42
+ - **一般(非 `--apply`)的 `uds update -y` 會把專案 CLAUDE.md 裡繁體中文的提交訊息標題悄悄換成英文版,`--plan --integrations-only` 的預演差異也可能忽略專案的顯示語言設定。** `updateCommand` 主流程與其 `--plan` 預演各自獨立地只用 `output_language`/`commit_language`(提交訊息語言)推導整合區塊的內容語言,完全忽略 `display_language`(`uds init` 與 reconciler 一直用來決定「你想讀哪種語言」的設定)。一個以 `display_language: zh-tw` 與 `output_language: bilingual` 安裝的專案——一種常見組合——因此從 `init` 拿到正確的「## 提交訊息語言」標題,卻在下一次一般 `uds update` 拿到「## Commit Message Language」,丟掉了原本正確的語言選擇。已對兩個真實採用者(asiaostrich-telemetry-server、EngramGraph)從 6.12.0 升到 6.13.0 實測驗證。此缺陷早於 6.13.0 就存在(自 2026-03-25 的 commit `ad555d41` 起),且在 `uds update` 對一個已是最新版的專案執行時完全隱形——因為那種情況下它在走到這段程式碼前就提早返回——只有在真正跨版本升級時才會發作,這正是它看起來像 6.13.0 新回歸的原因。`buildToolIntegrationConfig`(`--apply`/reconciler 使用)在 2026-09-16 已修好正確的推導邏輯;現在剩下的兩個呼叫點都改用新增的 `resolveIntegrationLanguage(manifest)` 共用同一份邏輯。新增的回歸測試對著真實臨時專案與真正的產生器(無 mock)重現了確切的缺陷,另有一支靜態守衛測試,只要那段舊的內嵌推導在 CLI 原始碼任何地方重新出現就會變紅。
43
+ - **`uds update --apply`(reconciler)只要專案曾經由 `generateAgentsMd` 寫出過 AGENTS.md,就會把它整份改寫成完全不同、opencode 樣式的文件——即使是在剛跑完 `uds init` 後緊接著的第一次 `--apply`,其他什麼都沒改也一樣。** `desired-state-calculator.js` 的 `calculateIntegrations` 會把 `manifest.integrations` 裡任何叫做 `AGENTS.md` 的條目,透過 `resolveToolKey` 解析成 `opencode` 這個工具——不論 opencode(或它的別名 `codex`)是否真的被選為 AI 工具。`uds init` 只要通用摘要寫出過一次,就一定會把 `AGENTS.md` 記進 `manifest.integrations`(那只是一個追蹤標記,不是工具選擇的紀錄),所以每一個 `generateAgentsMd: true` 而且沒選 codex/opencode 的專案都受影響。依產生器本身 2026-08-20 加入的設計說明:per-tool 樣板本來就該只在真的選了 codex 或 opencode 時才取代通用摘要。已在三個真實專案(asiaostrich-telemetry-server、EngramGraph、dev-platform 自己的 `.standards/`)上確認,三者的 `aiTools` 都不含 codex/opencode。`calculateIntegrations`(與 `plan-executor.js` 的 `executeMigrateBlock`)現在會先檢查工具是否真的被選,沒有的話改用一般 `uds update` 本來就在用的同一個 `writeAgentsMdSummary`——`--apply` 與一般 `uds update` 現在會一致。新增的回歸測試驅動真正的 `uds init`/`uds update`(無 mock);已對還原修正的版本確認會紅,其中一支「第二次 `--apply`」冪等性檢查還額外抓到了修正過程中自己引入的一個雜湊不收斂問題(見下一條)。
44
+ - **通用 AGENTS.md 摘要「這個檔案是索引,不是標準本文」的提醒(2026-08-18 加入)從未送到既有專案的受管區塊——只到了檔頭,而檔頭在檔案已存在時,標記式更新從來不會重新產生。** `writeAgentsMdSummary` 對已存在的檔案,永遠只替換 `<!-- UDS:STANDARDS:START/END -->` 兩個標記之間的內容;提醒卻寫在標記外的檔頭。已對兩個真實採用者(asiaostrich-telemetry-server、EngramGraph)實測:不論更新前後,提醒在檔頭和區塊裡都不存在。提醒現在也寫進標記區塊內(措辭與 per-tool 產生器自己的揭露文字 `generateIndexDisclosure` 對齊,不另創第三種),於是每個專案在下一次 `uds update`/`--apply`(不論是新檔還是既有檔)都會收到它。順手把這個區塊也改用 per-tool 產生器本來就在用的同一個 `wrapWithMarkers` 輔助函式組出來(而非手寫標記行),過程中也修掉一個相關缺口:全新的 AGENTS.md 檔案原本也從未帶有「請勿手動編輯」的警告註解,因為過去只有合併路徑才會加上它。
45
+
20
46
  ## [6.13.0] - 2026-09-28
21
47
 
22
48
  > **正式版**:包含下方 6.13.0-beta.1 至 beta.5 的全部內容,beta.5 之後沒有任何變更。重點:回合收尾關卡(agent 說了下一步卻沒做就不得結束回合)現在涵蓋 **Claude Code 與 Codex**,兩者都以從 npm 安裝的版本在真實工作階段驗證過(Codex 要先用 `/hooks` 信任才會執行);Claude Code 關卡真的會擋(到 beta.4 為止每個回合都放行);Windows 上可用;`uds uninstall` 會移除它;`uds init` 讓提交前檢查真的執行;`developer-memory` 1.2.0。Gemini CLI 標為過時(Google 已對個人帳號停用,改由 Antigravity CLI 取代,後者尚未支援)。
@@ -15,7 +15,7 @@ status: current
15
15
 
16
16
  > **語言**: [English](../../README.md) | 繁體中文 | [简体中文](../zh-CN/README.md)
17
17
 
18
- **版本**: 6.13.0 | **發布日期**: 2026-09-28 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
18
+ **版本**: 6.14.0-beta.1 (Pre-release) | **發布日期**: 2026-09-29 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
19
19
 
20
20
  語言無關、框架無關的軟體專案文件標準。透過 AI 原生工作流,確保不同技術堆疊之間的一致性、品質和可維護性。
21
21
 
@@ -13,7 +13,8 @@ status: current
13
13
  <!-- UDS_SUPPORTED_VERSIONS_START -->
14
14
  | 版本 | 支援狀態 |
15
15
  |------|--------|
16
- | 6.13.0 | ✅ 最新正式版 |
16
+ | 6.14.0-beta.1 | ✅ 預發布版本 |
17
+ | 6.13.1 | ✅ 最新正式版 |
17
18
  | < 6.0.0 | ❌ 已終止支援 |
18
19
  <!-- UDS_SUPPORTED_VERSIONS_END -->
19
20