universal-dev-standards 6.9.0 → 6.11.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 (63) hide show
  1. package/bin/uds.js +2 -0
  2. package/bundled/core/agent-communication-protocol.md +8 -0
  3. package/bundled/core/branch-completion.md +8 -0
  4. package/bundled/core/change-batching-standards.md +8 -0
  5. package/bundled/core/execution-history.md +8 -0
  6. package/bundled/core/pipeline-integration-standards.md +8 -0
  7. package/bundled/core/workflow-enforcement.md +8 -0
  8. package/bundled/core/workflow-state-protocol.md +8 -0
  9. package/bundled/locales/zh-CN/CHANGELOG.md +49 -3
  10. package/bundled/locales/zh-CN/README.md +1 -1
  11. package/bundled/locales/zh-CN/SECURITY.md +1 -1
  12. package/bundled/locales/zh-CN/core/agent-communication-protocol.md +7 -0
  13. package/bundled/locales/zh-CN/core/branch-completion.md +7 -0
  14. package/bundled/locales/zh-CN/core/change-batching-standards.md +7 -0
  15. package/bundled/locales/zh-CN/core/execution-history.md +7 -0
  16. package/bundled/locales/zh-CN/core/pipeline-integration-standards.md +7 -0
  17. package/bundled/locales/zh-CN/core/workflow-enforcement.md +7 -0
  18. package/bundled/locales/zh-CN/core/workflow-state-protocol.md +7 -0
  19. package/bundled/locales/zh-CN/docs/CHEATSHEET.md +1 -1
  20. package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +52 -5
  21. package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +3 -1
  22. package/bundled/locales/zh-CN/docs/MIGRATION-v6.md +8 -4
  23. package/bundled/locales/zh-TW/CHANGELOG.md +50 -3
  24. package/bundled/locales/zh-TW/README.md +1 -1
  25. package/bundled/locales/zh-TW/SECURITY.md +1 -1
  26. package/bundled/locales/zh-TW/core/agent-communication-protocol.md +7 -0
  27. package/bundled/locales/zh-TW/core/branch-completion.md +7 -0
  28. package/bundled/locales/zh-TW/core/change-batching-standards.md +7 -0
  29. package/bundled/locales/zh-TW/core/execution-history.md +7 -0
  30. package/bundled/locales/zh-TW/core/pipeline-integration-standards.md +7 -0
  31. package/bundled/locales/zh-TW/core/workflow-enforcement.md +7 -0
  32. package/bundled/locales/zh-TW/core/workflow-state-protocol.md +7 -0
  33. package/bundled/locales/zh-TW/docs/CHEATSHEET.md +1 -1
  34. package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +52 -5
  35. package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +3 -1
  36. package/bundled/locales/zh-TW/docs/MIGRATION-v6.md +8 -4
  37. package/bundled/locales/zh-TW/integrations/claude-code/README.md +14 -5
  38. package/package.json +7 -6
  39. package/src/commands/check.js +413 -44
  40. package/src/commands/config.js +34 -28
  41. package/src/commands/init.js +37 -7
  42. package/src/commands/spec.js +2 -2
  43. package/src/commands/update.js +560 -74
  44. package/src/core/manifest.js +39 -1
  45. package/src/flows/init-flow.js +9 -1
  46. package/src/generators/layered-claudemd.js +13 -4
  47. package/src/i18n/messages.js +39 -3
  48. package/src/installers/integration-installer.js +17 -10
  49. package/src/installers/manifest-installer.js +4 -0
  50. package/src/installers/skills-installer.js +4 -4
  51. package/src/installers/standards-installer.js +3 -3
  52. package/src/prompts/init.js +33 -4
  53. package/src/reconciler/actual-state-scanner.js +29 -2
  54. package/src/reconciler/desired-state-calculator.js +51 -2
  55. package/src/reconciler/diff-engine.js +76 -5
  56. package/src/reconciler/plan-executor.js +48 -27
  57. package/src/utils/hasher.js +61 -5
  58. package/src/utils/integration-generator.js +431 -92
  59. package/src/utils/marker-locator.js +140 -0
  60. package/src/utils/reference-sync.js +156 -8
  61. package/src/utils/registry.js +57 -0
  62. package/src/utils/spinner.js +31 -0
  63. package/standards-registry.json +8 -8
@@ -3,8 +3,10 @@ import { dirname, join, basename } from 'path';
3
3
  import { getLanguageRules } from '../prompts/integrations.js';
4
4
  import { computeIntegrationBlockHash } from './hasher.js';
5
5
  import { UDS_MARKERS, SUPPORTED_AI_TOOLS, LEGACY_TOOL_MAPPINGS } from '../core/constants.js';
6
- import { resolveSelectedOptionSources, resolveStandardFilename } from './registry.js';
6
+ import { locateMarkerBlock } from './marker-locator.js';
7
+ import { resolveSelectedOptionSources, resolveStandardFilename, getAllStandards } from './registry.js';
7
8
  import { getAgentConfig, getAgentTier } from '../config/ai-agent-paths.js';
9
+ import { STANDARD_ID_MAPPING } from './conversion-rules.js';
8
10
 
9
11
  /**
10
12
  * Resolve contentMode and level based on AI tool's tier and capabilities.
@@ -2003,6 +2005,16 @@ src/
2003
2005
  /**
2004
2006
  * Tool-specific file headers
2005
2007
  */
2008
+ // 🔴 These headers used to open by telling the agent to "PRIORITIZE reading the
2009
+ // concise rules in `core/`". `uds init` installs standards into `.standards/`
2010
+ // and has never created a `core/` directory in an adopter's project — `core/`
2011
+ // is where the standards live in the UDS repo, not in the repos that adopt it.
2012
+ // So the first instruction in every generated file, for every tool, in every
2013
+ // language, pointed at nothing. An adopter reported the symptom on 2026-09-16
2014
+ // and read it as residue from an old install; it was not residue, a clean
2015
+ // `uds init` wrote it. 36 copies of the same two sentences, all wrong the same
2016
+ // way. `tests/unit/utils/tool-headers-no-core.test.js` walks the generated
2017
+ // output so a tenth tool cannot reintroduce it.
2006
2018
  const TOOL_HEADERS = {
2007
2019
  cursor: {
2008
2020
  en: `# Cursor Rules
@@ -2015,8 +2027,8 @@ You are an expert software engineer assistant. Follow these project standards.
2015
2027
  All responses should be in **English**.
2016
2028
 
2017
2029
  ## Core Standards Usage Rule
2018
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2019
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2030
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2031
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2020
2032
  > This ensures token efficiency and focused context.`,
2021
2033
  'zh-tw': `# Cursor 規則
2022
2034
  # 由 Universal Dev Standards CLI 生成
@@ -2028,8 +2040,8 @@ All responses should be in **English**.
2028
2040
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2029
2041
 
2030
2042
  ## 核心標準使用規則 / Core Standards Usage Rule
2031
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2032
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2043
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2044
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2033
2045
  > 這確保了 Token 效率和上下文聚焦。`,
2034
2046
  bilingual: `# Cursor Rules | Cursor 規則
2035
2047
  # Generated by Universal Dev Standards CLI
@@ -2044,10 +2056,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2044
2056
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2045
2057
 
2046
2058
  ## Core Standards Usage Rule / 核心標準使用規則
2047
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2048
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2049
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2050
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2059
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2060
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2061
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2062
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2051
2063
  > This ensures token efficiency and focused context.
2052
2064
  > 這確保了 Token 效率和上下文聚焦。`
2053
2065
  },
@@ -2062,8 +2074,8 @@ You are an expert software engineer assistant. Follow these project standards.
2062
2074
  All responses should be in **English**.
2063
2075
 
2064
2076
  ## Core Standards Usage Rule
2065
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2066
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2077
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2078
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2067
2079
  > This ensures token efficiency and focused context.`,
2068
2080
  'zh-tw': `# Windsurf 規則
2069
2081
  # 由 Universal Dev Standards CLI 生成
@@ -2075,8 +2087,8 @@ All responses should be in **English**.
2075
2087
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2076
2088
 
2077
2089
  ## 核心標準使用規則 / Core Standards Usage Rule
2078
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2079
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2090
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2091
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2080
2092
  > 這確保了 Token 效率和上下文聚焦。`,
2081
2093
  bilingual: `# Windsurf Rules | Windsurf 規則
2082
2094
  # Generated by Universal Dev Standards CLI
@@ -2091,10 +2103,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2091
2103
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2092
2104
 
2093
2105
  ## Core Standards Usage Rule / 核心標準使用規則
2094
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2095
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2096
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2097
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2106
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2107
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2108
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2109
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2098
2110
  > This ensures token efficiency and focused context.
2099
2111
  > 這確保了 Token 效率和上下文聚焦。`
2100
2112
  },
@@ -2109,8 +2121,8 @@ You are an expert software engineer assistant. Follow these project standards.
2109
2121
  All responses should be in **English**.
2110
2122
 
2111
2123
  ## Core Standards Usage Rule
2112
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2113
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2124
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2125
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2114
2126
  > This ensures token efficiency and focused context.`,
2115
2127
  'zh-tw': `# Cline 規則
2116
2128
  # 由 Universal Dev Standards CLI 生成
@@ -2122,8 +2134,8 @@ All responses should be in **English**.
2122
2134
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2123
2135
 
2124
2136
  ## 核心標準使用規則 / Core Standards Usage Rule
2125
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2126
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2137
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2138
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2127
2139
  > 這確保了 Token 效率和上下文聚焦。`,
2128
2140
  bilingual: `# Cline Rules | Cline 規則
2129
2141
  # Generated by Universal Dev Standards CLI
@@ -2138,10 +2150,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2138
2150
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2139
2151
 
2140
2152
  ## Core Standards Usage Rule / 核心標準使用規則
2141
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2142
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2143
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2144
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2153
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2154
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2155
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2156
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2145
2157
  > This ensures token efficiency and focused context.
2146
2158
  > 這確保了 Token 效率和上下文聚焦。`
2147
2159
  },
@@ -2156,8 +2168,8 @@ You are an expert software engineer assistant. Follow these project standards.
2156
2168
  All responses should be in **English**.
2157
2169
 
2158
2170
  ## Core Standards Usage Rule
2159
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2160
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2171
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2172
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2161
2173
  > This ensures token efficiency and focused context.`,
2162
2174
  'zh-tw': `# GitHub Copilot 說明
2163
2175
  # 由 Universal Dev Standards CLI 生成
@@ -2169,8 +2181,8 @@ All responses should be in **English**.
2169
2181
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2170
2182
 
2171
2183
  ## 核心標準使用規則 / Core Standards Usage Rule
2172
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2173
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2184
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2185
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2174
2186
  > 這確保了 Token 效率和上下文聚焦。`,
2175
2187
  bilingual: `# GitHub Copilot Instructions | GitHub Copilot 說明
2176
2188
  # Generated by Universal Dev Standards CLI
@@ -2185,10 +2197,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2185
2197
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2186
2198
 
2187
2199
  ## Core Standards Usage Rule / 核心標準使用規則
2188
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2189
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2190
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2191
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2200
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2201
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2202
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2203
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2192
2204
  > This ensures token efficiency and focused context.
2193
2205
  > 這確保了 Token 效率和上下文聚焦。`
2194
2206
  },
@@ -2204,8 +2216,8 @@ Follow these project standards.
2204
2216
  All responses should be in **English**.
2205
2217
 
2206
2218
  ## Core Standards Usage Rule
2207
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2208
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2219
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2220
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2209
2221
  > This ensures token efficiency and focused context.`,
2210
2222
  'zh-tw': `# Antigravity 系統指令
2211
2223
  # 由 Universal Dev Standards CLI 生成
@@ -2218,8 +2230,8 @@ Google Antigravity (Gemini Advanced Agent) 的推薦系統指令。
2218
2230
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2219
2231
 
2220
2232
  ## 核心標準使用規則 / Core Standards Usage Rule
2221
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2222
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2233
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2234
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2223
2235
  > 這確保了 Token 效率和上下文聚焦。`,
2224
2236
  bilingual: `# Antigravity System Instructions | Antigravity 系統指令
2225
2237
  # Generated by Universal Dev Standards CLI
@@ -2234,10 +2246,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2234
2246
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2235
2247
 
2236
2248
  ## Core Standards Usage Rule / 核心標準使用規則
2237
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2238
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2239
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2240
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2249
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2250
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2251
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2252
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2241
2253
  > This ensures token efficiency and focused context.
2242
2254
  > 這確保了 Token 效率和上下文聚焦。`
2243
2255
  },
@@ -2250,8 +2262,8 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2250
2262
  All responses should be in **English**.
2251
2263
 
2252
2264
  ## Core Standards Usage Rule
2253
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2254
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2265
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2266
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2255
2267
  > This ensures token efficiency and focused context.`,
2256
2268
  'zh-tw': `# Claude Code 專案指南
2257
2269
  # 由 Universal Dev Standards CLI 生成
@@ -2262,8 +2274,8 @@ All responses should be in **English**.
2262
2274
  AI 助手應以繁體中文回覆使用者的問題與請求。
2263
2275
 
2264
2276
  ## 核心標準使用規則 / Core Standards Usage Rule
2265
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2266
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2277
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2278
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2267
2279
  > 這確保了 Token 效率和上下文聚焦。`,
2268
2280
  bilingual: `# Project Guidelines for Claude Code | Claude Code 專案指南
2269
2281
  # Generated by Universal Dev Standards CLI
@@ -2276,10 +2288,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2276
2288
  AI 助手應以繁體中文回覆使用者的問題與請求。
2277
2289
 
2278
2290
  ## Core Standards Usage Rule / 核心標準使用規則
2279
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2280
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2281
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2282
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2291
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2292
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2293
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2294
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2283
2295
  > This ensures token efficiency and focused context.
2284
2296
  > 這確保了 Token 效率和上下文聚焦。`
2285
2297
  },
@@ -2294,8 +2306,8 @@ You are an expert software engineer assistant. Follow these project standards.
2294
2306
  All responses should be in **English**.
2295
2307
 
2296
2308
  ## Core Standards Usage Rule
2297
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2298
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2309
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2310
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2299
2311
  > This ensures token efficiency and focused context.`,
2300
2312
  'zh-tw': `# AGENTS.md - OpenAI Codex CLI 規則
2301
2313
  # 由 Universal Dev Standards CLI 生成
@@ -2307,8 +2319,8 @@ All responses should be in **English**.
2307
2319
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2308
2320
 
2309
2321
  ## 核心標準使用規則 / Core Standards Usage Rule
2310
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2311
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2322
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2323
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2312
2324
  > 這確保了 Token 效率和上下文聚焦。`,
2313
2325
  bilingual: `# AGENTS.md - OpenAI Codex CLI Rules | OpenAI Codex CLI 規則
2314
2326
  # Generated by Universal Dev Standards CLI
@@ -2323,10 +2335,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2323
2335
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2324
2336
 
2325
2337
  ## Core Standards Usage Rule / 核心標準使用規則
2326
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2327
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2328
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2329
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2338
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2339
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2340
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2341
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2330
2342
  > This ensures token efficiency and focused context.
2331
2343
  > 這確保了 Token 效率和上下文聚焦。`
2332
2344
  },
@@ -2341,8 +2353,8 @@ You are an expert software engineer assistant powered by Gemini. Follow these pr
2341
2353
  All responses should be in **English**.
2342
2354
 
2343
2355
  ## Core Standards Usage Rule
2344
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2345
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2356
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2357
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2346
2358
  > This ensures token efficiency and focused context.`,
2347
2359
  'zh-tw': `# GEMINI.md - Gemini CLI 規則
2348
2360
  # 由 Universal Dev Standards CLI 生成
@@ -2354,8 +2366,8 @@ All responses should be in **English**.
2354
2366
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2355
2367
 
2356
2368
  ## 核心標準使用規則 / Core Standards Usage Rule
2357
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2358
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2369
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2370
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2359
2371
  > 這確保了 Token 效率和上下文聚焦。`,
2360
2372
  bilingual: `# GEMINI.md - Gemini CLI Rules | Gemini CLI 規則
2361
2373
  # Generated by Universal Dev Standards CLI
@@ -2370,10 +2382,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2370
2382
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2371
2383
 
2372
2384
  ## Core Standards Usage Rule / 核心標準使用規則
2373
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2374
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2375
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2376
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2385
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2386
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2387
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2388
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2377
2389
  > This ensures token efficiency and focused context.
2378
2390
  > 這確保了 Token 效率和上下文聚焦。`
2379
2391
  },
@@ -2388,8 +2400,8 @@ You are an expert software engineer assistant. Follow these project standards.
2388
2400
  All responses should be in **English**.
2389
2401
 
2390
2402
  ## Core Standards Usage Rule
2391
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2392
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2403
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2404
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2393
2405
  > This ensures token efficiency and focused context.`,
2394
2406
  'zh-tw': `# AGENTS.md - OpenCode 規則
2395
2407
  # 由 Universal Dev Standards CLI 生成
@@ -2401,8 +2413,8 @@ All responses should be in **English**.
2401
2413
  所有回覆必須使用**繁體中文 (Traditional Chinese)**。
2402
2414
 
2403
2415
  ## 核心標準使用規則 / Core Standards Usage Rule
2404
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2405
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2416
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2417
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2406
2418
  > 這確保了 Token 效率和上下文聚焦。`,
2407
2419
  bilingual: `# AGENTS.md - OpenCode Rules | OpenCode 規則
2408
2420
  # Generated by Universal Dev Standards CLI
@@ -2417,10 +2429,10 @@ All responses should be in **Traditional Chinese (繁體中文)**, with technica
2417
2429
  所有回覆必須使用**繁體中文**,技術術語可保留英文。
2418
2430
 
2419
2431
  ## Core Standards Usage Rule / 核心標準使用規則
2420
- > When verifying standards, checking code, or performing tasks, **PRIORITIZE** reading the concise rules in \`core/\` (e.g., \`core/testing-standards.md\`).
2421
- > 當驗證標準、檢查程式碼或執行任務時,**優先**讀取 \`core/\` 中的精簡規則(例如 \`core/testing-standards.md\`)。
2422
- > **ONLY** read \`core/guides/\` or \`methodologies/guides/\` when explicitly asked for educational content, detailed explanations, or tutorials.
2423
- > 只有在被明確要求提供教育內容、詳細解釋或教學時,才讀取 \`core/guides/\` 或 \`methodologies/guides/\`。
2432
+ > When verifying standards, checking code, or performing tasks, read the rules in \`.standards/\` — that is where this project's standards are installed.
2433
+ > 當驗證標準、檢查程式碼或執行任務時,讀取 \`.standards/\` 裡的規則——那是本專案標準實際安裝的位置。
2434
+ > Each file states its own requirements; read the one the task is about rather than all of them.
2435
+ > 每個檔案各自寫明它要求什麼;讀與當下任務相關的那一份,不必全部讀完。
2424
2436
  > This ensures token efficiency and focused context.
2425
2437
  > 這確保了 Token 效率和上下文聚焦。`
2426
2438
  }
@@ -2736,6 +2748,237 @@ function generateWorkflowGateContent(language) {
2736
2748
  * @param {Object} config - Integration configuration
2737
2749
  * @returns {string} Generated content
2738
2750
  */
2751
+ /**
2752
+ * Strip a standard's extension to get its bare identifying stem, e.g.
2753
+ * 'commit-message.ai.yaml' -> 'commit-message'. Shared by
2754
+ * resolveStandardReferences and getHeadingToPrimaryStandardStem below.
2755
+ */
2756
+ function stemOf(value) {
2757
+ return basename(String(value)).replace(/\.(ai\.yaml|yaml|md)$/i, '');
2758
+ }
2759
+
2760
+ /**
2761
+ * Normalize a Markdown ATX heading line for comparison, e.g.
2762
+ * '## 提交訊息標準 ' -> '提交訊息標準'. Returns null for a non-heading line.
2763
+ */
2764
+ function normalizeHeadingLine(line) {
2765
+ const m = String(line).match(/^#{1,6}\s+(.+?)\s*$/);
2766
+ return m ? m[1].trim() : null;
2767
+ }
2768
+
2769
+ let _headingToPrimaryStandardStem = null;
2770
+
2771
+ /**
2772
+ * Map every RULE_TEMPLATES section heading (any category, detail level,
2773
+ * language that has a Reference:/參考: line) to the stem of the FIRST
2774
+ * `.standards/...` path on that line — that section's "primary standard".
2775
+ *
2776
+ * XSPEC adopter-report, narrow auto-repair (decision 1, 2026-09-18):
2777
+ * 6.10.0's resolveStandardReferences deleted `.standards/commit-message-guide.md`
2778
+ * from an existing file's "## 提交訊息標準" section — it looked exactly like a
2779
+ * retired, uninstalled UDS standard — leaving only the trailing options
2780
+ * reference behind. Rewriting away the resulting dangling comma (the earlier
2781
+ * fix, same XSPEC) does not bring the deleted item back: it is gone from the
2782
+ * file, and nothing else regenerates that section, because rule-template
2783
+ * sections live OUTSIDE the UDS markers by design.
2784
+ *
2785
+ * This map is how resolveStandardReferences recognizes "this heading belongs
2786
+ * to a UDS rule template, and here is the one reference it must never be
2787
+ * missing" — so it can restore ONLY that single item, ONLY when it is
2788
+ * genuinely installed and missing from the line. A heading that does not
2789
+ * match any template (a user's own section) is simply absent from this map,
2790
+ * so it is never touched.
2791
+ *
2792
+ * Computed once and cached — RULE_TEMPLATES is a static module constant.
2793
+ *
2794
+ * @returns {Map<string, string>} heading text (without leading '#'s) -> primary standard stem
2795
+ */
2796
+ function getHeadingToPrimaryStandardStem() {
2797
+ if (_headingToPrimaryStandardStem) return _headingToPrimaryStandardStem;
2798
+
2799
+ const map = new Map();
2800
+ const refLineRe = /^(?:Reference|參考|参考)[::]([^\n]*)$/im;
2801
+
2802
+ for (const categoryTemplates of Object.values(RULE_TEMPLATES)) {
2803
+ for (const modeTemplates of Object.values(categoryTemplates)) {
2804
+ for (const text of Object.values(modeTemplates)) {
2805
+ const heading = normalizeHeadingLine(String(text).split('\n')[0]);
2806
+ if (!heading) continue;
2807
+
2808
+ // 'minimal' mode has no Reference: line at all — nothing to repair,
2809
+ // and no primary standard to record for that heading.
2810
+ const refMatch = text.match(refLineRe);
2811
+ if (!refMatch) continue;
2812
+
2813
+ const firstItem = refMatch[1].split(',')[0].trim();
2814
+ const pathMatch = firstItem.match(/^\.standards\/([^\s,`)\]]+)$/);
2815
+ if (!pathMatch) continue;
2816
+
2817
+ map.set(heading, stemOf(pathMatch[1]));
2818
+ }
2819
+ }
2820
+ }
2821
+
2822
+ _headingToPrimaryStandardStem = map;
2823
+ return map;
2824
+ }
2825
+
2826
+ /**
2827
+ * Point every `.standards/<file>` reference at the file this project actually has.
2828
+ *
2829
+ * `RULE_TEMPLATES` spells its references as `.standards/<name>.md` because that
2830
+ * is what UDS shipped when they were written. A project installed with
2831
+ * `--format ai` holds `<name>.ai.yaml`, so those lines named files that are not
2832
+ * there — reproduced on 6.9.0 (2026-09-16): a clean `--format ai` project got
2833
+ * `.standards/anti-hallucination.md` and `.standards/checkin-standards.md`, and
2834
+ * `uds check` called the file in sync because it compared names with the
2835
+ * extension stripped and never asked whether the file existed.
2836
+ *
2837
+ * Rewrites by stem against the installed set; a reference whose standard this
2838
+ * project did not install is dropped rather than left dangling, and if that
2839
+ * empties the line, the line goes too.
2840
+ *
2841
+ * @param {string} content - Generated integration content
2842
+ * @param {string[]} installedStandards - Manifest standards (IDs or paths)
2843
+ * @param {string} standardsFormat - 'ai' | 'human'
2844
+ * @returns {string}
2845
+ */
2846
+ function resolveStandardReferences(content, installedStandards = [], standardsFormat = 'ai', projectPath = null) {
2847
+ if (!content) return content;
2848
+
2849
+ // Every stem UDS itself ships — the only references this function may delete.
2850
+ //
2851
+ // Read defensively: this runs inside pure content generation, and callers
2852
+ // (including this repo's own tests) may have the registry or `fs` mocked. A
2853
+ // registry that cannot be read means "delete nothing", which degrades to
2854
+ // rewriting matched paths only — never to removing a line.
2855
+ const udsOwnedStems = new Set();
2856
+ try {
2857
+ for (const std of getAllStandards()) {
2858
+ if (std?.id) udsOwnedStems.add(stemOf(std.id));
2859
+ const sources = typeof std?.source === 'string'
2860
+ ? [std.source]
2861
+ : [std?.source?.ai, std?.source?.human].filter(Boolean);
2862
+ for (const src of sources) udsOwnedStems.add(stemOf(src));
2863
+ }
2864
+ } catch {
2865
+ // Registry unavailable — keep every reference that does not match.
2866
+ }
2867
+
2868
+ const installedByStem = new Map();
2869
+ for (const entry of installedStandards) {
2870
+ const filename = resolveStandardFilename(entry, standardsFormat) || basename(String(entry));
2871
+ installedByStem.set(stemOf(entry), filename);
2872
+ installedByStem.set(stemOf(filename), filename);
2873
+ }
2874
+
2875
+ // XSPEC adopter-report Q2: a reference written against a pre-6.0.0
2876
+ // filename (`commit-message-guide.md`) must still resolve to whatever this
2877
+ // project installed under the CURRENT id (`commit-message`) — that rename
2878
+ // is exactly what STANDARD_ID_MAPPING already records, previously
2879
+ // consulted only by the human→AI YAML generator. Without it, the old name
2880
+ // was indistinguishable from a retired, UDS-owned standard the project
2881
+ // chose not to install, and got deleted instead of rewritten.
2882
+ const resolveActualFilename = (path) => {
2883
+ const stem = stemOf(path);
2884
+ return installedByStem.get(stem) || installedByStem.get(STANDARD_ID_MAPPING[stem] || stem) || null;
2885
+ };
2886
+
2887
+ const headingToPrimaryStem = getHeadingToPrimaryStandardStem();
2888
+ const headingLineRe = /^#{1,6}\s+/;
2889
+ const referenceLineRe = /^([^\n]*(?:Reference|參考|参考)[::])([^\n]*)$/i;
2890
+
2891
+ // XSPEC adopter-report Q2: rebuilt as a line-by-line split → filter → join
2892
+ // instead of a single global regex, so each "Reference:" line's PRECEDING
2893
+ // heading is known (needed for decision 1's narrow auto-repair below) —
2894
+ // and instead of patching a deleted substring's separators with more
2895
+ // regexes. The old single-regex approach deleted only the matched
2896
+ // `.standards/...` text in place and then tried to tidy up whatever
2897
+ // punctuation was left around the hole; it handled a trailing comma, a
2898
+ // doubled comma, and a comma with stray space, but not a comma left
2899
+ // dangling right after the colon when the FIRST item was the one dropped
2900
+ // (`Reference:, .standards/other.md`).
2901
+ const lines = content.split('\n');
2902
+ let currentHeading = null;
2903
+ const outLines = [];
2904
+
2905
+ for (const rawLine of lines) {
2906
+ if (headingLineRe.test(rawLine)) {
2907
+ currentHeading = normalizeHeadingLine(rawLine);
2908
+ outLines.push(rawLine);
2909
+ continue;
2910
+ }
2911
+
2912
+ const refMatch = rawLine.match(referenceLineRe);
2913
+ if (!refMatch) {
2914
+ outLines.push(rawLine);
2915
+ continue;
2916
+ }
2917
+
2918
+ const [, label, rest] = refMatch;
2919
+ const items = rest.split(',').map((s) => s.trim()).filter(Boolean);
2920
+ const kept = [];
2921
+ const presentStems = new Set();
2922
+
2923
+ for (const item of items) {
2924
+ const pathMatch = item.match(/^(\.standards\/)([^\s,`)\]]+)$/);
2925
+ if (!pathMatch) {
2926
+ // Not a bare `.standards/...` reference (e.g. trailing prose) — leave untouched.
2927
+ kept.push(item);
2928
+ continue;
2929
+ }
2930
+ const [, prefix, path] = pathMatch;
2931
+
2932
+ // Option files live in `.standards/options/…` and are named by path, not ID.
2933
+ if (path.startsWith('options/')) { kept.push(item); presentStems.add(stemOf(path)); continue; }
2934
+
2935
+ const actual = resolveActualFilename(path);
2936
+ if (actual) { kept.push(`${prefix}${actual}`); presentStems.add(stemOf(actual)); continue; }
2937
+
2938
+ // 🔴 Only UDS's own standards may be dropped. The first version of this
2939
+ // rewrite removed every unmatched reference, which deleted a project's own
2940
+ // `.standards/our-house-rule.md` line — a file it had put there on purpose.
2941
+ // Removing a user's line is worse than the dead link this exists to fix.
2942
+ let onDisk = false;
2943
+ try {
2944
+ onDisk = Boolean(projectPath) && existsSync(join(projectPath, '.standards', path));
2945
+ } catch {
2946
+ onDisk = false;
2947
+ }
2948
+ if (onDisk || !udsOwnedStems.has(stemOf(path))) {
2949
+ kept.push(item);
2950
+ presentStems.add(stemOf(path));
2951
+ continue;
2952
+ }
2953
+ // Dropped: a UDS-owned reference to a standard this project did not install.
2954
+ }
2955
+
2956
+ // XSPEC adopter-report, narrow auto-repair (decision 1): this line's
2957
+ // heading matches a UDS rule template EXACTLY (see
2958
+ // getHeadingToPrimaryStandardStem's docblock) and that template's
2959
+ // primary standard is genuinely installed but missing from the line —
2960
+ // put it back at the front. Idempotent: a line that already has it does
2961
+ // nothing. Everything else about the line — the project's own entries,
2962
+ // options files, existing order — is untouched, and no OTHER (secondary)
2963
+ // template item is ever added back.
2964
+ const primaryStem = currentHeading ? headingToPrimaryStem.get(currentHeading) : null;
2965
+ if (primaryStem && !presentStems.has(primaryStem)) {
2966
+ const primaryActual = installedByStem.get(primaryStem);
2967
+ if (primaryActual) {
2968
+ kept.unshift(`.standards/${primaryActual}`);
2969
+ }
2970
+ }
2971
+
2972
+ if (kept.length === 0) {
2973
+ outLines.push('');
2974
+ continue;
2975
+ }
2976
+ outLines.push(`${label} ${kept.join(', ')}`);
2977
+ }
2978
+
2979
+ return outLines.join('\n').replace(/\n{3,}/g, '\n\n');
2980
+ }
2981
+
2739
2982
  export function generateIntegrationContent(config) {
2740
2983
  const {
2741
2984
  tool,
@@ -2890,7 +3133,8 @@ export function generateIntegrationContent(config) {
2890
3133
  sections.push('\n');
2891
3134
  }
2892
3135
 
2893
- return sections.join('\n').trim() + '\n';
3136
+ const assembled = sections.join('\n').trim() + '\n';
3137
+ return resolveStandardReferences(assembled, installedStandards, standardsFormat, config.projectPath || null);
2894
3138
  }
2895
3139
 
2896
3140
  /**
@@ -2939,7 +3183,10 @@ export function mergeRules(existingContent, newContent, strategy) {
2939
3183
  * @returns {Object} Result with success status
2940
3184
  */
2941
3185
  export function writeIntegrationFile(tool, config, projectPath) {
2942
- const fileName = getToolFileName(tool);
3186
+ // XSPEC-418 R2/R3: config.integrationTargets carries manifest.integrationTargets
3187
+ // (or its init-time equivalent) through unchanged — this is the actual write path,
3188
+ // so it must be the one place that honors a per-tool target override.
3189
+ const fileName = resolveIntegrationTargetFile(tool, { integrationTargets: config.integrationTargets });
2943
3190
  if (!fileName) {
2944
3191
  return { success: false, error: `Unknown tool: ${tool}` };
2945
3192
  }
@@ -2973,6 +3220,19 @@ export function writeIntegrationFile(tool, config, projectPath) {
2973
3220
  }
2974
3221
  }
2975
3222
 
3223
+ // 🔴 The rule sections live OUTSIDE the markers, so a marker-based update
3224
+ // never refreshes them: a file first written by an older CLI kept
3225
+ // `.standards/commit-message-guide.md` for ever, and a regenerate on the
3226
+ // fixed generator still left it (measured 2026-09-16). Repoint stale
3227
+ // `.standards/` paths across the whole file — it touches nothing but the
3228
+ // paths, and a path to a file that is not there helps no reader.
3229
+ content = resolveStandardReferences(
3230
+ content,
3231
+ config.installedStandards || [],
3232
+ config.standardsFormat || 'ai',
3233
+ projectPath
3234
+ );
3235
+
2976
3236
  writeFileSync(filePath, content);
2977
3237
 
2978
3238
  // Compute block hash for tracking UDS content separately from user content
@@ -2993,10 +3253,13 @@ export function writeIntegrationFile(tool, config, projectPath) {
2993
3253
  * Check if integration file exists
2994
3254
  * @param {string} tool - Tool name
2995
3255
  * @param {string} projectPath - Project root path
3256
+ * @param {Object} [manifestLike] - Manifest-like object; only `integrationTargets` is
3257
+ * read (XSPEC-418 R2) — pass the real manifest, or `{ integrationTargets }` at
3258
+ * init time before a manifest object exists.
2996
3259
  * @returns {boolean} True if file exists
2997
3260
  */
2998
- export function integrationFileExists(tool, projectPath) {
2999
- const fileName = getToolFileName(tool);
3261
+ export function integrationFileExists(tool, projectPath, manifestLike) {
3262
+ const fileName = resolveIntegrationTargetFile(tool, manifestLike);
3000
3263
  return fileName && existsSync(join(projectPath, fileName));
3001
3264
  }
3002
3265
 
@@ -3201,9 +3464,19 @@ function withSelectedOptions(manifest) {
3201
3464
 
3202
3465
  export function buildToolIntegrationConfig(manifest, tool) {
3203
3466
  const selected = manifest.options?.output_language || manifest.options?.commit_language || 'english';
3204
- const language = selected === 'bilingual'
3467
+
3468
+ // Content language comes from `display_language` — the setting whose entire
3469
+ // job is "what language do you want to read" — and only falls back to
3470
+ // `output_language`, which is the commit-message language, when the project
3471
+ // has no display setting to go on. They are different questions: `uds init`
3472
+ // has always used the first, every regeneration path used the second, and a
3473
+ // project installed with `--locale zh-tw` therefore got Chinese instructions
3474
+ // from `init` and English ones from the next `uds update`, silently.
3475
+ const display = manifest.options?.display_language;
3476
+ const fromOutput = selected === 'bilingual'
3205
3477
  ? 'bilingual'
3206
3478
  : selected === 'traditional-chinese' ? 'zh-tw' : 'en';
3479
+ const language = ['en', 'zh-tw', 'bilingual'].includes(display) ? display : fromOutput;
3207
3480
  const resolved = resolveContentModeForTool(tool, manifest.contentMode || 'auto');
3208
3481
 
3209
3482
  return {
@@ -3220,7 +3493,12 @@ export function buildToolIntegrationConfig(manifest, tool) {
3220
3493
  contentMode: resolved.contentMode,
3221
3494
  level: resolved.level,
3222
3495
  outputLanguage: selected,
3223
- methodology: manifest.methodology
3496
+ methodology: manifest.methodology,
3497
+ // XSPEC-418 R2/R3: threads the per-tool target override through to
3498
+ // writeIntegrationFile via resolveIntegrationTargetFile. Every caller of
3499
+ // this function (regenerateIntegrations, plan-executor's migrate_block,
3500
+ // backfillIntegrationConfigs) gets the override for free.
3501
+ integrationTargets: manifest.integrationTargets
3224
3502
  };
3225
3503
  }
3226
3504
 
@@ -3280,13 +3558,18 @@ export function wrapWithMarkers(content, format) {
3280
3558
  */
3281
3559
  export function extractMarkedContent(fileContent, format) {
3282
3560
  const markers = UDS_MARKERS[format] || UDS_MARKERS.markdown;
3283
- const startIdx = fileContent.indexOf(markers.start);
3284
- const endIdx = fileContent.indexOf(markers.end);
3285
-
3286
- if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) {
3561
+ // XSPEC adopter-report Q5: locateMarkerBlock requires the marker to occupy
3562
+ // a whole line by itself (and not be inside a fenced code block), so a
3563
+ // sentence that merely mentions the marker text is never mistaken for the
3564
+ // real boundary. It throws AmbiguousMarkerError if more than one real pair
3565
+ // exists — callers must not catch that away silently.
3566
+ const block = locateMarkerBlock(fileContent, markers);
3567
+
3568
+ if (!block) {
3287
3569
  return { before: fileContent, content: '', after: '' };
3288
3570
  }
3289
3571
 
3572
+ const { startIdx, endIdx } = block;
3290
3573
  return {
3291
3574
  before: fileContent.substring(0, startIdx),
3292
3575
  content: fileContent.substring(startIdx + markers.start.length, endIdx).trim(),
@@ -3303,15 +3586,18 @@ export function extractMarkedContent(fileContent, format) {
3303
3586
  */
3304
3587
  export function updateMarkedSection(existingContent, newMarkedContent, format) {
3305
3588
  const markers = UDS_MARKERS[format] || UDS_MARKERS.markdown;
3306
- const startIdx = existingContent.indexOf(markers.start);
3307
- const endIdx = existingContent.indexOf(markers.end);
3589
+ // XSPEC adopter-report Q5: same rule as extractMarkedContent — a line that
3590
+ // merely mentions the marker text is not a boundary, so it is never
3591
+ // deleted along with (what used to be mistaken for) "the UDS block".
3592
+ const block = locateMarkerBlock(existingContent, markers);
3308
3593
 
3309
- if (startIdx === -1 || endIdx === -1) {
3594
+ if (!block) {
3310
3595
  // No existing markers, append new content
3311
3596
  return existingContent.trim() + '\n\n' + wrapWithMarkers(newMarkedContent, format) + '\n';
3312
3597
  }
3313
3598
 
3314
3599
  // Replace existing marked section
3600
+ const { startIdx, endIdx } = block;
3315
3601
  const before = existingContent.substring(0, startIdx);
3316
3602
  const after = existingContent.substring(endIdx + markers.end.length);
3317
3603
 
@@ -3327,6 +3613,45 @@ export function getToolFilePath(tool) {
3327
3613
  return getToolFileName(tool) || null;
3328
3614
  }
3329
3615
 
3616
+ /**
3617
+ * Tool × manifest → the integration file this tool actually reads/writes.
3618
+ *
3619
+ * XSPEC-418 R2: honors a per-tool override recorded in
3620
+ * `manifest.integrationTargets` (currently only ever set for `claude-code`, to
3621
+ * `CLAUDE.local.md` — a personal UDS adoption in a repo with a team-owned,
3622
+ * version-controlled `CLAUDE.md`). No override set → same file
3623
+ * `getToolFilePath` already returns, so every manifest that never sets
3624
+ * `integrationTargets` gets byte-identical output (XSPEC-418 AC-5).
3625
+ *
3626
+ * This is the single place "tool → target file" is decided once a manifest (or
3627
+ * a manifest-shaped config carrying `integrationTargets`) is in scope. Every
3628
+ * call site that used to call `getToolFilePath`/`getToolFileName` to answer
3629
+ * "what file do I read/write for this tool right now" must call this instead
3630
+ * — enforced by the static-scan guard in
3631
+ * tests/unit/core/integration-target-resolver-guard.test.js.
3632
+ *
3633
+ * Placed here rather than core/constants.js, where XSPEC-418 originally
3634
+ * suggested it next to `resolveIntegrationFile`: the default-file fallback
3635
+ * must be the `getToolFileName` above — the one with the legacy-mapping guard,
3636
+ * the already-a-filename passthrough, and the "known agent missing from
3637
+ * SUPPORTED_AI_TOOLS" throw (see its own comment) — not a re-implementation in
3638
+ * constants.js, which would silently drop that throw for every call site this
3639
+ * migrates. constants.js is imported BY this file already, so this file
3640
+ * cannot be imported back from constants.js without a cycle; it lives beside
3641
+ * the function it wraps instead.
3642
+ *
3643
+ * @param {string} tool - Tool key (e.g. 'claude-code'), or an entry already
3644
+ * resolved to a file path — passed straight to `getToolFileName`, which
3645
+ * already tolerates that shape (XSPEC-208 BUG-208-01).
3646
+ * @param {Object} [manifest] - Manifest-like object; only `integrationTargets` is read.
3647
+ * @returns {string|null} Repo-relative target file, or null for a genuinely unknown tool.
3648
+ */
3649
+ export function resolveIntegrationTargetFile(tool, manifest) {
3650
+ const key = LEGACY_TOOL_MAPPINGS[tool] || tool;
3651
+ const override = manifest?.integrationTargets?.[key];
3652
+ if (typeof override === 'string' && override.length > 0) return override;
3653
+ return getToolFileName(tool) || null;
3654
+ }
3330
3655
 
3331
3656
  /**
3332
3657
  * Get default commands based on ecosystem
@@ -3431,6 +3756,7 @@ export function generateAgentsMdSummary(config = {}) {
3431
3756
  language = 'en',
3432
3757
  outputLanguage = 'english',
3433
3758
  standardOptions = {},
3759
+ standardsFormat = 'ai',
3434
3760
  projectPath
3435
3761
  } = config;
3436
3762
 
@@ -3523,12 +3849,25 @@ export function generateAgentsMdSummary(config = {}) {
3523
3849
  // only the option files. On one adopter that meant seven lines standing in
3524
3850
  // for seventy, under a heading reading "Installed Standards", with nothing
3525
3851
  // anywhere reporting the sixty-three that had been dropped.
3526
- const resolved = installedStandards
3527
- .map((s) => resolveStandardFilename(s, 'ai'))
3528
- .filter((name) => name?.endsWith('.ai.yaml'));
3529
-
3530
- for (const filename of resolved) {
3531
- lines.push(`- \`.standards/${filename}\` — ${filename.replace('.ai.yaml', '')}`);
3852
+ // Two things this used to get wrong, both of which produced a list of paths
3853
+ // that are not there — under a heading telling the agent to read them.
3854
+ //
3855
+ // Options install one directory deeper (`.standards/options/…`), and this
3856
+ // wrote every entry at the top level. The sibling renderer in this file has
3857
+ // always handled that; the docblock above it says a previous fix reached
3858
+ // "one of the two producers", and this is the other one.
3859
+ //
3860
+ // And the format was pinned to `ai`, so a `--format human` project was
3861
+ // handed `.ai.yaml` names for files it holds as `.md`.
3862
+ const format = standardsFormat === 'human' ? 'human' : 'ai';
3863
+ const suffix = format === 'human' ? '.md' : '.ai.yaml';
3864
+
3865
+ for (const entry of installedStandards) {
3866
+ const filename = resolveStandardFilename(entry, format);
3867
+ if (!filename?.endsWith(suffix)) continue;
3868
+ const isOption = entry.includes('/options/') || entry.includes('\\options\\');
3869
+ const dir = isOption ? '.standards/options' : '.standards';
3870
+ lines.push(`- \`${dir}/${filename}\` — ${filename.replace(suffix, '')}`);
3532
3871
  }
3533
3872
  } else {
3534
3873
  lines.push('No standards installed yet. Run `npx uds init` to install.');