universal-dev-standards 6.2.3 → 6.2.5

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.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  source: ../../CHANGELOG.md
3
- source_version: 6.2.3
4
- translation_version: 6.2.3
3
+ source_version: 6.2.5
4
+ translation_version: 6.2.5
5
5
  last_synced: 2026-07-31
6
6
  status: current
7
7
  ---
@@ -17,6 +17,18 @@ status: current
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [6.2.5] - 2026-07-31
21
+
22
+ ### 修复
23
+
24
+ - **`uds update` 的备份目录可能被提交进你的 repo。** `.uds-backup-<时间戳>/` 会写在项目旁供回滚,而没有任何规则忽略它——于是一次 `git add -A` 就把它扫了进去。这在我们自己的 repo 发生过两次,其中一次把 360 个文件、73,992 行带进了公开 repo。备份现在会忽略自己:创建时就在目录内写一个内容为 `*` 的 `.gitignore`,`git status` 与 `git add -A` 不再看得到它,而**你的** `.gitignore` 不会被修改。旧版本产生的既有备份不会被追溯隐藏——请自行删除或补上规则。
25
+
26
+ ## [6.2.4] - 2026-07-31
27
+
28
+ ### 修复
29
+
30
+ - **`uds update` 会提议删掉你自己写的技能。** 来源判定只要 `manifest.skillHashes` 记录了某个技能底下的任一文件,就把它当成 UDS 自己的资产。那个判准之所以安全,只因为 hasher 是坏的——它为 78 个已安装技能只留下 2 笔记录。6.2.2 修好 hasher 之后,同一份 map 被填满技能文件夹底下全部 137 个文件,包括手写的那些;它们于是落在「以 UDS 出货内容构建的期望状态」之外,被判为应删除的孤儿。某个项目的计划提议删掉 18 个目录,其中 14 个是它自己的运维技能。来源判定现在只保留一个信号:名称存在于 UDS 自己的 `skills/` 树下。UDS 已下架的技能改为发警告而非删除——磁盘上没有任何东西能把它们和你自己的作品区分开,而**留下一个带警告的陈旧目录,比删掉别人手写的文件,是比较好的失败方式**。**若你正在使用 6.2.2 或 6.2.3,且自己的技能与 UDS 的并存,应用任何变更前请先跑 `uds update --plan`。**
31
+
20
32
  ## [6.2.3] - 2026-07-31
21
33
 
22
34
  ### 修复
@@ -15,7 +15,7 @@ status: current
15
15
 
16
16
  > **语言**: [English](../../README.md) | [繁體中文](../zh-TW/README.md) | 简体中文
17
17
 
18
- **版本**: 6.2.3 | **发布日期**: 2026-07-31 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
18
+ **版本**: 6.2.5 | **发布日期**: 2026-07-31 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
19
19
 
20
20
  语言无关、框架无关的软件项目文档标准。通过 AI 原生工作流,确保不同技术栈之间的一致性、质量和可维护性。
21
21
 
@@ -13,7 +13,7 @@ status: current
13
13
  <!-- UDS_SUPPORTED_VERSIONS_START -->
14
14
  | 版本 | 支持状态 |
15
15
  |------|--------|
16
- | 6.2.3 | ✅ 最新正式版 |
16
+ | 6.2.5 | ✅ 最新正式版 |
17
17
  | < 6.0.0 | ❌ 已终止支持 |
18
18
  <!-- UDS_SUPPORTED_VERSIONS_END -->
19
19
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  source: ../../CHANGELOG.md
3
- source_version: 6.2.3
4
- translation_version: 6.2.3
3
+ source_version: 6.2.5
4
+ translation_version: 6.2.5
5
5
  last_synced: 2026-07-31
6
6
  status: current
7
7
  ---
@@ -17,6 +17,18 @@ status: current
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [6.2.5] - 2026-07-31
21
+
22
+ ### 修復
23
+
24
+ - **`uds update` 的備份目錄可能被提交進你的 repo。** `.uds-backup-<時間戳>/` 會寫在專案旁供回滾,而沒有任何規則忽略它——於是一次 `git add -A` 就把它掃了進去。這在我們自己的 repo 發生過兩次,其中一次把 360 個檔、73,992 行帶進了公開 repo。備份現在會忽略自己:建立時就在目錄內寫一個內容為 `*` 的 `.gitignore`,`git status` 與 `git add -A` 不再看得到它,而**你的** `.gitignore` 不會被修改。舊版本產生的既有備份不會被追溯隱藏——請自行刪除或補上規則。
25
+
26
+ ## [6.2.4] - 2026-07-31
27
+
28
+ ### 修復
29
+
30
+ - **`uds update` 會提議刪掉你自己寫的技能。** 來源判定只要 `manifest.skillHashes` 記錄了某個技能底下的任一檔案,就把它當成 UDS 自己的資產。那個判準之所以安全,只因為 hasher 是壞的——它為 78 個已安裝技能只留下 2 筆紀錄。6.2.2 修好 hasher 之後,同一份 map 被填滿技能資料夾底下全部 137 個檔案,包括手寫的那些;它們於是落在「以 UDS 出貨內容建構的期望狀態」之外,被判為應刪除的孤兒。某個專案的計畫提議刪掉 18 個目錄,其中 14 個是它自己的維運技能。來源判定現在只保留一個訊號:名稱存在於 UDS 自己的 `skills/` 樹下。UDS 已下架的技能改為發警告而非刪除——磁碟上沒有任何東西能把它們和你自己的作品區分開,而**留下一個帶警告的陳舊目錄,比刪掉別人手寫的檔案,是比較好的失敗方式**。**若你正在使用 6.2.2 或 6.2.3,且自己的技能與 UDS 的並存,套用任何變更前請先跑 `uds update --plan`。**
31
+
20
32
  ## [6.2.3] - 2026-07-31
21
33
 
22
34
  ### 修復
@@ -15,7 +15,7 @@ status: current
15
15
 
16
16
  > **語言**: [English](../../README.md) | 繁體中文 | [简体中文](../zh-CN/README.md)
17
17
 
18
- **版本**: 6.2.3 | **發布日期**: 2026-07-31 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
18
+ **版本**: 6.2.5 | **發布日期**: 2026-07-31 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
19
19
 
20
20
  語言無關、框架無關的軟體專案文件標準。透過 AI 原生工作流,確保不同技術堆疊之間的一致性、品質和可維護性。
21
21
 
@@ -13,7 +13,7 @@ status: current
13
13
  <!-- UDS_SUPPORTED_VERSIONS_START -->
14
14
  | 版本 | 支援狀態 |
15
15
  |------|--------|
16
- | 6.2.3 | ✅ 最新正式版 |
16
+ | 6.2.5 | ✅ 最新正式版 |
17
17
  | < 6.0.0 | ❌ 已終止支援 |
18
18
  <!-- UDS_SUPPORTED_VERSIONS_END -->
19
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-dev-standards",
3
- "version": "6.2.3",
3
+ "version": "6.2.5",
4
4
  "description": "CLI tool for adopting Universal Development Standards",
5
5
  "keywords": [
6
6
  "documentation",
@@ -295,10 +295,25 @@ function shippedCommandNames() {
295
295
  *
296
296
  * Anything else is the adopter's own, and is warned about rather than deleted.
297
297
  */
298
- function isUdsProvenance(skillName, manifest, agent, level) {
299
- if (sourceEntryNames().has(skillName)) return true;
300
- const prefix = `${agent}/${level}/${skillName}/`;
301
- return Object.keys(manifest?.skillHashes || {}).some((k) => k.startsWith(prefix));
298
+ // A directory whose name exists in UDS's own `skills/` tree was put there by UDS.
299
+ // That is the only positive signal, and everything else is the adopter's.
300
+ //
301
+ // `manifest.skillHashes` USED TO BE a second signal here ("authoritative whenever
302
+ // present"). That was only ever safe because the hasher was broken: a trailing
303
+ // separator in three skill paths made it record 2 entries for 78 installed skills,
304
+ // so the clause almost never fired. Fixing the hasher (6.2.2) populated the same
305
+ // map with every file under the skills folder — including the adopter's own — and
306
+ // each one of those became a deletion candidate, re-opening the exact defect this
307
+ // function was written to close. The lesson is not about hashes: a broken tool's
308
+ // sparse output was used as evidence that reading it was safe.
309
+ //
310
+ // The cost of the narrow signal is unchanged and still deliberate: skills UDS used
311
+ // to ship and has since removed are warned about rather than deleted, because
312
+ // nothing on disk distinguishes them from the adopter's own work. Leaving a few
313
+ // stale directories with a warning is a better way to fail than deleting files
314
+ // somebody hand-wrote.
315
+ function isUdsProvenance(skillName) {
316
+ return sourceEntryNames().has(skillName);
302
317
  }
303
318
 
304
319
  /**
@@ -335,7 +350,7 @@ function scanSkills(state, projectPath, manifest) {
335
350
  // the skills folder used to be assumed UDS-managed, so a plan for a repo
336
351
  // with hand-written skills proposed deleting them: dev-platform's would
337
352
  // have removed fourteen. (XSPEC-343 R2)
338
- udsManaged: isUdsProvenance(skillName, manifest, agent, level)
353
+ udsManaged: isUdsProvenance(skillName)
339
354
  }
340
355
  });
341
356
  }
@@ -64,6 +64,28 @@ export function createBackup(projectPath, plan) {
64
64
  };
65
65
  }
66
66
 
67
+ // Make the backup invisible to git, from inside itself.
68
+ //
69
+ // WHY THIS IS NOT A LINE IN THE ADOPTER'S .gitignore. We create this directory
70
+ // in someone else's repository; making it disappear is our job, but editing
71
+ // their .gitignore to do it is not — that file is theirs, it may be generated,
72
+ // and a tool appending to it on every update is a worse trade than the problem.
73
+ // A `*` here ignores everything in this directory (this file included, which is
74
+ // fine: git reads .gitignore whether or not it is tracked), so `git status` and
75
+ // `git add -A` never see the backup at all, and nothing outside is touched.
76
+ //
77
+ // WHY IT EXISTS. Nothing ignored these directories, so `git add -A` in two
78
+ // sibling repos committed them: EngramGraph's 0.8.0 release commit took in 5
79
+ // backups — 360 files, 73,992 lines — and dev-platform took one. Both were
80
+ // public. The adopter is not the right place to put this responsibility: they
81
+ // did not create the directory and have no reason to expect it.
82
+ try {
83
+ writeFileSync(join(backupDir, '.gitignore'), '*\n', 'utf8');
84
+ } catch (err) {
85
+ // A backup that git can see still beats no backup — record and carry on.
86
+ errors.push(`Failed to write backup .gitignore: ${err.message}`);
87
+ }
88
+
67
89
  // Backup each file
68
90
  for (const relativePath of filesToBackup) {
69
91
  const sourcePath = join(projectPath, relativePath);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "version": "6.2.3",
3
+ "version": "6.2.5",
4
4
  "lastUpdated": "2026-05-13",
5
5
  "description": "Standards registry for universal-dev-standards with integrated skills and AI-optimized formats",
6
6
  "formats": {
@@ -58,14 +58,14 @@
58
58
  "standards": {
59
59
  "name": "universal-dev-standards",
60
60
  "url": "https://github.com/AsiaOstrich/universal-dev-standards",
61
- "version": "6.2.3"
61
+ "version": "6.2.5"
62
62
  },
63
63
  "skills": {
64
64
  "name": "universal-dev-standards",
65
65
  "url": "https://github.com/AsiaOstrich/universal-dev-standards",
66
66
  "localPath": "skills",
67
67
  "rawUrl": "https://raw.githubusercontent.com/AsiaOstrich/universal-dev-standards/main/skills",
68
- "version": "6.2.3",
68
+ "version": "6.2.5",
69
69
  "note": "Skills are now included in the main repository under skills/"
70
70
  }
71
71
  },
@@ -2236,7 +2236,7 @@
2236
2236
  "id": "license-compliance",
2237
2237
  "name": "License Compliance Standards",
2238
2238
  "nameZh": "授權合規標準",
2239
- "version": "6.2.3",
2239
+ "version": "6.2.5",
2240
2240
  "source": {
2241
2241
  "human": "core/license-compliance.md",
2242
2242
  "ai": "ai/standards/license-compliance.ai.yaml"
@@ -2248,7 +2248,7 @@
2248
2248
  "id": "verification-oracle",
2249
2249
  "name": "Verification Oracle Standards",
2250
2250
  "nameZh": "驗證 Oracle 標準",
2251
- "version": "6.2.3",
2251
+ "version": "6.2.5",
2252
2252
  "source": {
2253
2253
  "human": "core/verification-oracle.md",
2254
2254
  "ai": "ai/standards/verification-oracle.ai.yaml"
@@ -2260,7 +2260,7 @@
2260
2260
  "id": "model-provenance",
2261
2261
  "name": "Model Provenance Policy Standards",
2262
2262
  "nameZh": "模型來源政策標準",
2263
- "version": "6.2.3",
2263
+ "version": "6.2.5",
2264
2264
  "source": {
2265
2265
  "human": "core/model-provenance.md",
2266
2266
  "ai": "ai/standards/model-provenance.ai.yaml"
@@ -2272,7 +2272,7 @@
2272
2272
  "id": "resource-cost-boundary",
2273
2273
  "name": "Resource / Cost Boundary Declaration Standards",
2274
2274
  "nameZh": "資源/成本邊界宣告標準",
2275
- "version": "6.2.3",
2275
+ "version": "6.2.5",
2276
2276
  "source": {
2277
2277
  "human": "core/resource-cost-boundary.md",
2278
2278
  "ai": "ai/standards/resource-cost-boundary.ai.yaml"