universal-dev-standards 6.8.0 → 6.9.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 (194) hide show
  1. package/bin/uds.js +12 -2
  2. package/bundled/ai/standards/acceptance-criteria-traceability.ai.yaml +14 -2
  3. package/bundled/ai/standards/adr-standards.ai.yaml +14 -2
  4. package/bundled/ai/standards/code-review.ai.yaml +13 -3
  5. package/bundled/ai/standards/commit-message.ai.yaml +8 -4
  6. package/bundled/ai/standards/deferred-item-exit.ai.yaml +225 -0
  7. package/bundled/ai/standards/feature-discovery-standards.ai.yaml +14 -2
  8. package/bundled/ai/standards/governance-layer.ai.yaml +128 -2
  9. package/bundled/ai/standards/logging.ai.yaml +2 -2
  10. package/bundled/ai/standards/retrospective-standards.ai.yaml +14 -2
  11. package/bundled/ai/standards/reverse-engineering-standards.ai.yaml +73 -2
  12. package/bundled/ai/standards/security-standards.ai.yaml +2 -2
  13. package/bundled/ai/standards/spec-driven-development.ai.yaml +14 -2
  14. package/bundled/ai/standards/tech-debt-standards.ai.yaml +87 -3
  15. package/bundled/ai/standards/turn-completion-integrity.ai.yaml +131 -0
  16. package/bundled/core/acceptance-criteria-traceability.md +5 -2
  17. package/bundled/core/adr-standards.md +26 -2
  18. package/bundled/core/code-review-checklist.md +5 -2
  19. package/bundled/core/context-aware-loading.md +1 -1
  20. package/bundled/core/deferred-item-exit.md +254 -0
  21. package/bundled/core/feature-discovery-standards.md +5 -1
  22. package/bundled/core/governance-layer.md +114 -2
  23. package/bundled/core/retrospective-standards.md +4 -2
  24. package/bundled/core/reverse-engineering-standards.md +81 -2
  25. package/bundled/core/spec-driven-development.md +8 -2
  26. package/bundled/core/tech-debt-standards.md +67 -8
  27. package/bundled/core/turn-completion-integrity.md +196 -0
  28. package/bundled/hooks/check-dangerous-cmd.mjs +60 -0
  29. package/bundled/hooks/check-logging-standard.mjs +59 -0
  30. package/bundled/hooks/check-turn-completion.mjs +233 -0
  31. package/bundled/hooks/inject-standards.mjs +183 -0
  32. package/bundled/hooks/telemetry-wrapper.mjs +77 -0
  33. package/bundled/hooks/turn-completion/detect.mjs +99 -0
  34. package/bundled/hooks/turn-completion/locales/en.mjs +159 -0
  35. package/bundled/hooks/turn-completion/locales/zh-TW.mjs +166 -0
  36. package/bundled/hooks/validate-commit-msg.mjs +104 -0
  37. package/bundled/locales/zh-CN/CHANGELOG.md +47 -3
  38. package/bundled/locales/zh-CN/CLAUDE.md +1 -1
  39. package/bundled/locales/zh-CN/README.md +2 -2
  40. package/bundled/locales/zh-CN/SECURITY.md +1 -1
  41. package/bundled/locales/zh-CN/core/adr-standards.md +1 -1
  42. package/bundled/locales/zh-CN/core/governance-layer.md +118 -6
  43. package/bundled/locales/zh-CN/core/retrospective-standards.md +1 -1
  44. package/bundled/locales/zh-CN/core/tech-debt-standards.md +71 -4
  45. package/bundled/locales/zh-CN/core/turn-completion-integrity.md +190 -0
  46. package/bundled/locales/zh-CN/docs/CHEATSHEET.md +8 -1
  47. package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +29 -68
  48. package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +25 -15
  49. package/bundled/locales/zh-CN/docs/USAGE-MODES-COMPARISON.md +1 -2
  50. package/bundled/locales/zh-CN/integrations/google-antigravity/{INSTRUCTIONS.md → AGENTS.md} +1 -1
  51. package/bundled/locales/zh-CN/integrations/google-antigravity/README.md +3 -3
  52. package/bundled/locales/zh-CN/skills/atdd-assistant/SKILL.md +2 -0
  53. package/bundled/locales/zh-CN/skills/bdd-assistant/SKILL.md +2 -0
  54. package/bundled/locales/zh-CN/skills/brainstorm-assistant/SKILL.md +22 -12
  55. package/bundled/locales/zh-CN/skills/brainstorm-assistant/guide.md +12 -9
  56. package/bundled/locales/zh-CN/skills/code-review-assistant/SKILL.md +1 -0
  57. package/bundled/locales/zh-CN/skills/commands/brainstorm.md +17 -13
  58. package/bundled/locales/zh-CN/skills/commands/config.md +0 -1
  59. package/bundled/locales/zh-CN/skills/commands/init.md +1 -2
  60. package/bundled/locales/zh-CN/skills/commit-standards/SKILL.md +2 -0
  61. package/bundled/locales/zh-CN/skills/contract-test-assistant/SKILL.md +1 -0
  62. package/bundled/locales/zh-CN/skills/dev-methodology/SKILL.md +2 -0
  63. package/bundled/locales/zh-CN/skills/observability-assistant/SKILL.md +1 -0
  64. package/bundled/locales/zh-CN/skills/project-structure-guide/SKILL.md +1 -0
  65. package/bundled/locales/zh-CN/skills/release-standards/SKILL.md +3 -0
  66. package/bundled/locales/zh-CN/skills/requirement-assistant/SKILL.md +2 -0
  67. package/bundled/locales/zh-CN/skills/reverse-engineer/SKILL.md +3 -0
  68. package/bundled/locales/zh-CN/skills/runbook-assistant/SKILL.md +1 -0
  69. package/bundled/locales/zh-CN/skills/slo-assistant/SKILL.md +1 -0
  70. package/bundled/locales/zh-CN/skills/tdd-assistant/SKILL.md +2 -0
  71. package/bundled/locales/zh-TW/CHANGELOG.md +47 -3
  72. package/bundled/locales/zh-TW/CLAUDE.md +1 -1
  73. package/bundled/locales/zh-TW/README.md +2 -2
  74. package/bundled/locales/zh-TW/SECURITY.md +1 -1
  75. package/bundled/locales/zh-TW/core/acceptance-criteria-traceability.md +2 -0
  76. package/bundled/locales/zh-TW/core/adr-standards.md +26 -5
  77. package/bundled/locales/zh-TW/core/code-review-checklist.md +2 -0
  78. package/bundled/locales/zh-TW/core/container-image-standards.md +2 -2
  79. package/bundled/locales/zh-TW/core/contract-testing-standards.md +2 -2
  80. package/bundled/locales/zh-TW/core/cross-flow-regression.md +8 -7
  81. package/bundled/locales/zh-TW/core/data-contract.md +2 -2
  82. package/bundled/locales/zh-TW/core/data-migration-testing.md +2 -2
  83. package/bundled/locales/zh-TW/core/data-pipeline.md +2 -2
  84. package/bundled/locales/zh-TW/core/deferred-item-exit.md +251 -0
  85. package/bundled/locales/zh-TW/core/documentation-writing-standards.md +228 -3
  86. package/bundled/locales/zh-TW/core/full-coverage-testing.md +15 -2
  87. package/bundled/locales/zh-TW/core/governance-layer.md +118 -5
  88. package/bundled/locales/zh-TW/core/iac-design-principles.md +2 -2
  89. package/bundled/locales/zh-TW/core/incident-response.md +2 -2
  90. package/bundled/locales/zh-TW/core/model-provenance.md +4 -2
  91. package/bundled/locales/zh-TW/core/pii-classification.md +42 -6
  92. package/bundled/locales/zh-TW/core/prd-standards.md +4 -2
  93. package/bundled/locales/zh-TW/core/product-metrics-standards.md +4 -2
  94. package/bundled/locales/zh-TW/core/release-readiness-gate.md +2 -2
  95. package/bundled/locales/zh-TW/core/resource-cost-boundary.md +2 -2
  96. package/bundled/locales/zh-TW/core/retrospective-standards.md +5 -3
  97. package/bundled/locales/zh-TW/core/reverse-engineering-standards.md +83 -5
  98. package/bundled/locales/zh-TW/core/runbook.md +2 -2
  99. package/bundled/locales/zh-TW/core/schema-evolution.md +2 -2
  100. package/bundled/locales/zh-TW/core/secret-management-standards.md +2 -2
  101. package/bundled/locales/zh-TW/core/slo-sli.md +2 -2
  102. package/bundled/locales/zh-TW/core/spec-driven-development.md +2 -0
  103. package/bundled/locales/zh-TW/core/tech-debt-standards.md +71 -4
  104. package/bundled/locales/zh-TW/core/turn-completion-integrity.md +190 -0
  105. package/bundled/locales/zh-TW/core/user-journey-testing.md +2 -2
  106. package/bundled/locales/zh-TW/core/user-story-mapping.md +2 -2
  107. package/bundled/locales/zh-TW/core/verification-oracle.md +2 -2
  108. package/bundled/locales/zh-TW/docs/CHEATSHEET.md +8 -1
  109. package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +29 -68
  110. package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +25 -15
  111. package/bundled/locales/zh-TW/docs/USAGE-MODES-COMPARISON.md +1 -2
  112. package/bundled/locales/zh-TW/integrations/google-antigravity/{INSTRUCTIONS.md → AGENTS.md} +1 -1
  113. package/bundled/locales/zh-TW/integrations/google-antigravity/README.md +3 -3
  114. package/bundled/locales/zh-TW/skills/adr-assistant/SKILL.md +1 -1
  115. package/bundled/locales/zh-TW/skills/atdd-assistant/SKILL.md +2 -0
  116. package/bundled/locales/zh-TW/skills/bdd-assistant/SKILL.md +2 -0
  117. package/bundled/locales/zh-TW/skills/brainstorm-assistant/SKILL.md +22 -12
  118. package/bundled/locales/zh-TW/skills/brainstorm-assistant/guide.md +12 -9
  119. package/bundled/locales/zh-TW/skills/code-review-assistant/SKILL.md +1 -0
  120. package/bundled/locales/zh-TW/skills/commands/brainstorm.md +17 -13
  121. package/bundled/locales/zh-TW/skills/commands/config.md +0 -1
  122. package/bundled/locales/zh-TW/skills/commands/init.md +1 -2
  123. package/bundled/locales/zh-TW/skills/commit-standards/SKILL.md +2 -0
  124. package/bundled/locales/zh-TW/skills/contract-test-assistant/SKILL.md +2 -1
  125. package/bundled/locales/zh-TW/skills/dev-methodology/SKILL.md +2 -0
  126. package/bundled/locales/zh-TW/skills/dev-workflow-guide/SKILL.md +1 -1
  127. package/bundled/locales/zh-TW/skills/knowledge-graph/guide.md +2 -2
  128. package/bundled/locales/zh-TW/skills/migration-assistant/SKILL.md +1 -1
  129. package/bundled/locales/zh-TW/skills/observability-assistant/SKILL.md +1 -0
  130. package/bundled/locales/zh-TW/skills/project-discovery/SKILL.md +1 -0
  131. package/bundled/locales/zh-TW/skills/project-structure-guide/SKILL.md +1 -0
  132. package/bundled/locales/zh-TW/skills/release-standards/SKILL.md +3 -0
  133. package/bundled/locales/zh-TW/skills/requirement-assistant/SKILL.md +2 -0
  134. package/bundled/locales/zh-TW/skills/reverse-engineer/SKILL.md +3 -0
  135. package/bundled/locales/zh-TW/skills/runbook-assistant/SKILL.md +1 -0
  136. package/bundled/locales/zh-TW/skills/slo-assistant/SKILL.md +1 -0
  137. package/bundled/locales/zh-TW/skills/tdd-assistant/SKILL.md +2 -0
  138. package/bundled/skills/atdd-assistant/SKILL.md +2 -0
  139. package/bundled/skills/bdd-assistant/SKILL.md +2 -0
  140. package/bundled/skills/brainstorm-assistant/SKILL.md +31 -13
  141. package/bundled/skills/brainstorm-assistant/guide.md +9 -6
  142. package/bundled/skills/code-review-assistant/SKILL.md +1 -0
  143. package/bundled/skills/commands/brainstorm.md +12 -9
  144. package/bundled/skills/commands/config.md +0 -1
  145. package/bundled/skills/commands/init.md +2 -3
  146. package/bundled/skills/commit-standards/SKILL.md +2 -0
  147. package/bundled/skills/contract-test-assistant/SKILL.md +1 -0
  148. package/bundled/skills/dev-methodology/SKILL.md +4 -0
  149. package/bundled/skills/observability-assistant/SKILL.md +1 -0
  150. package/bundled/skills/project-discovery/SKILL.md +1 -0
  151. package/bundled/skills/project-structure-guide/SKILL.md +1 -0
  152. package/bundled/skills/release-standards/SKILL.md +3 -0
  153. package/bundled/skills/requirement-assistant/SKILL.md +2 -0
  154. package/bundled/skills/reverse-engineer/SKILL.md +3 -0
  155. package/bundled/skills/runbook-assistant/SKILL.md +1 -0
  156. package/bundled/skills/slo-assistant/SKILL.md +1 -0
  157. package/bundled/skills/tdd-assistant/SKILL.md +2 -0
  158. package/bundled/templates/.ai-context.yaml.template +194 -0
  159. package/bundled/templates/CLAUDE.md.template +145 -0
  160. package/bundled/templates/DESIGN.md +237 -0
  161. package/bundled/templates/SKILL-BRIEF-TEMPLATE.md +57 -0
  162. package/bundled/templates/SKILL-CANDIDATES.md +39 -0
  163. package/bundled/templates/gates/check-error-exit.mjs +309 -0
  164. package/bundled/templates/mcp-config.json +10 -0
  165. package/bundled/templates/methodology-template.yaml +209 -0
  166. package/bundled/templates/migration-template.md +408 -0
  167. package/bundled/templates/requirement-checklist.md +410 -0
  168. package/bundled/templates/requirement-document-template.md +591 -0
  169. package/bundled/templates/requirement-template.md +881 -0
  170. package/bundled/templates/reverse-spec-template.md +409 -0
  171. package/bundled/templates/test-case-template.md +74 -0
  172. package/bundled/templates/test-plan-template.md +74 -0
  173. package/package.json +7 -5
  174. package/src/commands/audit.js +82 -0
  175. package/src/commands/check.js +66 -10
  176. package/src/commands/init.js +161 -16
  177. package/src/commands/update.js +286 -14
  178. package/src/compilers/claude-code-compiler.js +4 -1
  179. package/src/config/ai-agent-paths.js +62 -17
  180. package/src/core/constants.js +42 -11
  181. package/src/core/manifest.js +201 -3
  182. package/src/core/paths.js +2 -2
  183. package/src/i18n/messages.js +6 -29
  184. package/src/installers/hooks-installer.js +167 -75
  185. package/src/installers/integration-installer.js +9 -5
  186. package/src/prompts/init.js +14 -14
  187. package/src/utils/detector.js +21 -1
  188. package/src/utils/effect-boundary.js +1093 -0
  189. package/src/utils/hasher.js +166 -1
  190. package/src/utils/hook-stats.js +1 -1
  191. package/src/utils/integration-generator.js +79 -1
  192. package/src/utils/reference-sync.js +4 -1
  193. package/src/utils/yaml-generator.js +51 -9
  194. package/standards-registry.json +31 -8
@@ -55,6 +55,62 @@ export const DEFAULT_MANIFEST = {
55
55
  integrationBlockHashes: {}
56
56
  };
57
57
 
58
+ /**
59
+ * Content modes an adopter may choose.
60
+ *
61
+ * `full` was retired in favour of `index` (XSPEC-357 R7). It was never a third
62
+ * behaviour: the only place the mode is read is a single `=== 'minimal'` test
63
+ * in `generateComplianceInstructions`, so `full` and `index` took the same
64
+ * branch and produced byte-identical files — 24 of 24 tool × language
65
+ * combinations, against a control confirming the comparison does detect a real
66
+ * difference (`full` vs `minimal` differed in all 24). Meanwhile the manifest
67
+ * schema accepted it, `--content-mode` offered it, the init prompt listed it as
68
+ * a distinct trade-off ("highest compliance, uses more context"), and every
69
+ * `partial`-tier tool was assigned it automatically. Adopters were choosing
70
+ * between two labels for one behaviour, and the label promised a difference
71
+ * that did not exist.
72
+ */
73
+ export const SUPPORTED_CONTENT_MODES = ['minimal', 'index'];
74
+
75
+ /**
76
+ * Retired content modes and what they now resolve to.
77
+ *
78
+ * The rewrite changes no adopter's output, because the two modes already
79
+ * generated the same bytes — which is what makes this breaking change cheap
80
+ * enough to do at all. Kept as a map rather than special-cased at each call
81
+ * site so the next retirement has somewhere to go.
82
+ */
83
+ export const RETIRED_CONTENT_MODES = { full: 'index' };
84
+
85
+ /**
86
+ * Resolve a content mode, migrating retired ones and flagging unknown ones.
87
+ *
88
+ * An unknown value resolves to `fallback` and is reported in `unrecognized`, so
89
+ * the caller can warn. The original intent was to throw — a *silent* fallback
90
+ * turns `--content-mode indx` into a normal run with nothing saying so — and
91
+ * that remains the goal for 7.0.0. It does not throw in 6.x because 6.8.0
92
+ * accepted unknown values and generated the `index` output, and
93
+ * `core/versioning.md` requires a deprecation warning in a MINOR release before
94
+ * behaviour that used to work starts failing. The warning is what removes the
95
+ * silence; the error is the MAJOR-version step.
96
+ *
97
+ * @param {string|undefined} mode - Requested mode
98
+ * @param {string} fallback - Mode to use when nothing was requested, or when the value is unknown
99
+ * @returns {{mode: string, migratedFrom: string|null, unrecognized: string|null}}
100
+ */
101
+ export function normalizeContentMode(mode, fallback = 'index') {
102
+ if (mode === undefined || mode === null || mode === '') {
103
+ return { mode: fallback, migratedFrom: null, unrecognized: null };
104
+ }
105
+ if (SUPPORTED_CONTENT_MODES.includes(mode)) {
106
+ return { mode, migratedFrom: null, unrecognized: null };
107
+ }
108
+ if (Object.prototype.hasOwnProperty.call(RETIRED_CONTENT_MODES, mode)) {
109
+ return { mode: RETIRED_CONTENT_MODES[mode], migratedFrom: mode, unrecognized: null };
110
+ }
111
+ return { mode: fallback, migratedFrom: null, unrecognized: mode };
112
+ }
113
+
58
114
  /**
59
115
  * Validation schema for manifest
60
116
  */
@@ -63,10 +119,125 @@ const MANIFEST_SCHEMA = {
63
119
  properties: {
64
120
  version: { type: 'string', pattern: '^\\d+\\.\\d+\\.\\d+$' },
65
121
  format: { type: 'string', enum: ['ai', 'human', 'both'] },
66
- contentMode: { type: 'string', enum: ['minimal', 'index', 'full'] }
122
+ contentMode: { type: 'string', enum: SUPPORTED_CONTENT_MODES }
67
123
  }
68
124
  };
69
125
 
126
+ /**
127
+ * Provenance — the record of which files UDS itself wrote. (XSPEC-384 R1)
128
+ *
129
+ * Ownership is a question about *origin*, and origin is something you record at
130
+ * the moment you write, not something you infer afterwards from another table.
131
+ * `fileHashes` was doing the inferring: absence from it was read as "not ours",
132
+ * although a manifest loses entries through version migrations, hand edits,
133
+ * merge conflicts, and older CLI bugs. The tool then picked the destructive
134
+ * branch for the case it could not actually distinguish.
135
+ *
136
+ * Two properties matter and neither is shared with `fileHashes`:
137
+ *
138
+ * - It is append-only. `fileHashes` is current state and gets rewritten every
139
+ * run; provenance is history. If both were written and pruned together,
140
+ * provenance would add nothing — it would just be a second copy that fails
141
+ * the same way at the same moment.
142
+ * - It is keyed by the path actually written, taken from the copy result,
143
+ * not by re-deriving the path from the source name. The re-derivation is
144
+ * wrong for nested option files (`options/<category>/<name>.ai.yaml` is
145
+ * flattened to `options/<name>.ai.yaml`), so a path-math-based record would
146
+ * claim ownership of files that do not exist while disowning ones that do.
147
+ *
148
+ * An entry is removed only when UDS deliberately deletes the file — deleting it
149
+ * is how we relinquish the claim, so that a file a user later creates under the
150
+ * same name is not silently inherited.
151
+ */
152
+ export const PROVENANCE_SCHEMA_VERSION = 1;
153
+
154
+ /**
155
+ * Valid writers, used so a typo becomes an error rather than an unrecognised
156
+ * provenance record that reads as "not ours".
157
+ */
158
+ export const PROVENANCE_WRITERS = ['init', 'update', 'config', 'sync'];
159
+
160
+ /**
161
+ * Record that UDS wrote a file.
162
+ * @param {Object} manifest - Manifest (not mutated)
163
+ * @param {string} relPath - Path relative to project root
164
+ * @param {string} writer - One of PROVENANCE_WRITERS
165
+ * @returns {Object} Updated manifest
166
+ */
167
+ export function recordFileProvenance(manifest, relPath, writer) {
168
+ if (!relPath) return manifest;
169
+ const normalized = relPath.replace(/\\/g, '/');
170
+ const at = new Date().toISOString();
171
+ const existing = manifest?.provenance?.files?.[normalized];
172
+ return {
173
+ ...manifest,
174
+ provenance: {
175
+ schema: PROVENANCE_SCHEMA_VERSION,
176
+ ...(manifest?.provenance || {}),
177
+ files: {
178
+ ...(manifest?.provenance?.files || {}),
179
+ [normalized]: {
180
+ firstWrittenBy: existing?.firstWrittenBy || writer,
181
+ firstWrittenAt: existing?.firstWrittenAt || at,
182
+ lastWrittenBy: writer,
183
+ lastWrittenAt: at
184
+ }
185
+ }
186
+ }
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Drop a provenance record, relinquishing UDS's claim on a path.
192
+ * @param {Object} manifest - Manifest (not mutated)
193
+ * @param {string} relPath - Path relative to project root
194
+ * @returns {Object} Updated manifest
195
+ */
196
+ export function forgetFileProvenance(manifest, relPath) {
197
+ const normalized = (relPath || '').replace(/\\/g, '/');
198
+ const files = { ...(manifest?.provenance?.files || {}) };
199
+ delete files[normalized];
200
+ return {
201
+ ...manifest,
202
+ provenance: {
203
+ schema: PROVENANCE_SCHEMA_VERSION,
204
+ ...(manifest?.provenance || {}),
205
+ files
206
+ }
207
+ };
208
+ }
209
+
210
+ /**
211
+ * Mark provenance as a complete account of what UDS owns.
212
+ *
213
+ * Called at the end of a run that wrote the full installed set. Until this has
214
+ * happened at least once, a file with no provenance record is `unknown` rather
215
+ * than `foreign`, because the absence of a record proves nothing yet.
216
+ *
217
+ * @param {Object} manifest - Manifest (not mutated)
218
+ * @returns {Object} Updated manifest
219
+ */
220
+ export function establishProvenance(manifest) {
221
+ return {
222
+ ...manifest,
223
+ provenance: {
224
+ schema: PROVENANCE_SCHEMA_VERSION,
225
+ files: {},
226
+ ...(manifest?.provenance || {}),
227
+ establishedAt: manifest?.provenance?.establishedAt || new Date().toISOString()
228
+ }
229
+ };
230
+ }
231
+
232
+ /**
233
+ * Whether provenance can be trusted as a complete list of UDS-owned files.
234
+ * @param {Object} manifest - Manifest
235
+ * @returns {boolean}
236
+ */
237
+ export function isProvenanceEstablished(manifest) {
238
+ return !!manifest?.provenance?.establishedAt;
239
+ }
240
+
70
241
  /**
71
242
  * Get manifest file path for a project
72
243
  * @param {string} projectPath - Project root path
@@ -354,10 +525,25 @@ function migrateToV320(manifest) {
354
525
  return {
355
526
  ...manifest,
356
527
  version: '3.2.0',
357
- contentMode: manifest.contentMode || 'index'
528
+ contentMode: migrateRetiredContentMode(manifest.contentMode)
358
529
  };
359
530
  }
360
531
 
532
+ /**
533
+ * Rewrite a retired content mode to its replacement, leaving anything else
534
+ * alone. Unlike `normalizeContentMode` this never throws: it runs while reading
535
+ * a manifest, and refusing to load a project because of one stale string would
536
+ * be a worse outcome than loading it and letting `validateManifest` report.
537
+ * @param {string|undefined} mode
538
+ * @returns {string}
539
+ */
540
+ function migrateRetiredContentMode(mode) {
541
+ if (mode && Object.prototype.hasOwnProperty.call(RETIRED_CONTENT_MODES, mode)) {
542
+ return RETIRED_CONTENT_MODES[mode];
543
+ }
544
+ return mode || 'index';
545
+ }
546
+
361
547
  /**
362
548
  * Migration to version 3.3.0
363
549
  * @param {Object} manifest - V3.2.x manifest
@@ -502,11 +688,23 @@ function ensureRequiredFields(manifest) {
502
688
  ...manifest,
503
689
  options,
504
690
  standards,
505
- contentMode: manifest.contentMode || 'index',
691
+ // Rewrites a stored `full` to `index`. This is the migration path for
692
+ // existing adopters and it runs on every read, so a manifest written by an
693
+ // older CLI is corrected the first time a newer one touches it — without
694
+ // changing a single byte of what that project's AI tool files receive.
695
+ contentMode: migrateRetiredContentMode(manifest.contentMode),
506
696
  fileHashes: normalizedHashes,
507
697
  skillHashes: manifest.skillHashes || {},
508
698
  commandHashes: manifest.commandHashes || {},
509
699
  integrationBlockHashes: manifest.integrationBlockHashes || {},
700
+ // Present but deliberately NOT established. Filling in `establishedAt`
701
+ // here would declare "these records are complete" about a manifest that
702
+ // has never had a provenance-aware run, which is the one claim that turns
703
+ // every pre-existing file into `foreign` — and `foreign` is the state the
704
+ // deletion path acts on. Only a completed run may establish it.
705
+ // A fresh object per call: a shared default would be one mutable record
706
+ // handed to every manifest in the process. (XSPEC-384 R1)
707
+ provenance: manifest.provenance || { schema: PROVENANCE_SCHEMA_VERSION, files: {} },
510
708
  };
511
709
  }
512
710
 
package/src/core/paths.js CHANGED
@@ -149,8 +149,8 @@ export class PathResolver {
149
149
  'copilot': 'copilot-instructions.md',
150
150
  'aider': '.aider.conf.yml',
151
151
  'opencode': 'AGENTS.md',
152
- 'roo': 'ROO.md',
153
- 'antigravity': 'INSTRUCTIONS.md'
152
+ 'roo-code': '.roo/rules/uds-standards.md',
153
+ 'antigravity': '.agents/AGENTS.md'
154
154
  };
155
155
 
156
156
  const targetFile = toolTargets[tool] || fileName;
@@ -100,12 +100,10 @@ export const messages = {
100
100
  question: 'Select content mode:',
101
101
  labels: {
102
102
  index: 'Standard',
103
- full: 'Full Embed',
104
103
  minimal: 'Minimal'
105
104
  },
106
105
  choices: {
107
106
  index: 'Summary + task mapping, AI knows when to read which standard',
108
- full: 'Embed all rules, AI can use immediately but larger file',
109
107
  minimal: 'File references only, best with Skills'
110
108
  },
111
109
  explanations: {
@@ -114,11 +112,6 @@ export const messages = {
114
112
  ' → AI can determine "which standard to read for which task"',
115
113
  ' → Balance between context usage and compliance'
116
114
  ],
117
- full: [
118
- ' → All rules embedded in config file (~10-15 KB)',
119
- ' → AI needs no extra file reads, highest compliance',
120
- ' → Best for short tasks or strict compliance projects'
121
- ],
122
115
  minimal: [
123
116
  ' → Only contains .standards/ file list',
124
117
  ' → AI needs to actively read standard files',
@@ -328,7 +321,6 @@ export const messages = {
328
321
  warning: 'Changing Content Mode will regenerate all AI tool config files',
329
322
  explanations: {
330
323
  index: ' → AI will determine when to read standards based on task mapping',
331
- full: ' → All rules embedded directly, highest AI compliance',
332
324
  minimal: ' → AI must actively read standards, recommend using with Skills'
333
325
  }
334
326
  },
@@ -934,7 +926,6 @@ export const messages = {
934
926
  standardsScopeLean: 'Lean (Skills handle the rest)',
935
927
  standardsScopeComplete: 'Complete',
936
928
  contentModeLabel: 'Content Mode',
937
- contentModeFull: 'Full Embed',
938
929
  contentModeIndex: 'Standard (recommended)',
939
930
  contentModeMinimal: 'Minimal (core only)',
940
931
  displayLanguageLabel: 'Display Language',
@@ -969,7 +960,10 @@ export const messages = {
969
960
  generatingAgentsMd: 'Generating AGENTS.md (universal summary)...',
970
961
  generatedAgentsMd: 'Generated AGENTS.md (universal summary)',
971
962
  couldNotGenerateAgentsMd: 'Could not generate AGENTS.md',
972
- installingSkills: 'Installing Claude Code Skills...',
963
+ installingSkills: 'Installing Skills...',
964
+ // Named per detected tool, never per one tool: the install now goes to each
965
+ // tool's own path (XSPEC-408 §18.3), so a Claude-only label would be a lie.
966
+ skillsPathUnknown: 'no verified skills path for this tool — nothing was installed for it',
973
967
  installedSkills: 'Installed {count} Skills to {locations}',
974
968
  installedSkillsWithErrors: 'Installed {count} Skills with {errors} errors',
975
969
  // P1-CLI-1: locale fallback summary (printed after install when some
@@ -1334,12 +1328,10 @@ export const messages = {
1334
1328
  question: '選擇內容模式:',
1335
1329
  labels: {
1336
1330
  index: '標準',
1337
- full: '完整嵌入',
1338
1331
  minimal: '最小化'
1339
1332
  },
1340
1333
  choices: {
1341
1334
  index: '摘要 + 任務對照表,AI 知道何時讀哪個規範',
1342
- full: '完整嵌入所有規則,AI 立即可用但檔案較大',
1343
1335
  minimal: '僅檔案參考,適合搭配 Skills 使用'
1344
1336
  },
1345
1337
  explanations: {
@@ -1348,11 +1340,6 @@ export const messages = {
1348
1340
  ' → AI 能判斷「做什麼任務時要讀哪個規範」',
1349
1341
  ' → 平衡 Context 使用量和合規程度'
1350
1342
  ],
1351
- full: [
1352
- ' → 所有規則直接嵌入設定檔(檔案約 10-15 KB)',
1353
- ' → AI 無需額外讀檔,合規率最高',
1354
- ' → 適合短期任務或需要嚴格遵循的專案'
1355
- ],
1356
1343
  minimal: [
1357
1344
  ' → 僅包含 .standards/ 檔案清單',
1358
1345
  ' → AI 需要主動讀取規範檔案',
@@ -1562,7 +1549,6 @@ export const messages = {
1562
1549
  warning: '變更 Content Mode 將重新生成所有 AI 工具設定檔',
1563
1550
  explanations: {
1564
1551
  index: ' → AI 會根據任務對照表判斷何時讀取規範',
1565
- full: ' → 所有規則直接嵌入,AI 合規率最高',
1566
1552
  minimal: ' → AI 需主動讀取規範,建議搭配 Skills'
1567
1553
  }
1568
1554
  },
@@ -2168,7 +2154,6 @@ export const messages = {
2168
2154
  standardsScopeLean: '精簡(Skills 處理其餘)',
2169
2155
  standardsScopeComplete: '完整',
2170
2156
  contentModeLabel: '內容模式',
2171
- contentModeFull: '完整嵌入',
2172
2157
  contentModeIndex: '標準(推薦)',
2173
2158
  contentModeMinimal: '最小(僅核心)',
2174
2159
  displayLanguageLabel: '顯示語言',
@@ -2203,7 +2188,8 @@ export const messages = {
2203
2188
  generatingAgentsMd: '產生 AGENTS.md(通用摘要)中...',
2204
2189
  generatedAgentsMd: '已產生 AGENTS.md(通用摘要)',
2205
2190
  couldNotGenerateAgentsMd: '無法產生 AGENTS.md',
2206
- installingSkills: '安裝 Claude Code Skills 中...',
2191
+ installingSkills: '安裝 Skills 中...',
2192
+ skillsPathUnknown: '沒有查證過的 skills 路徑,這個工具沒有安裝任何東西',
2207
2193
  installedSkills: '已安裝 {count} 個 Skills 到 {locations}',
2208
2194
  installedSkillsWithErrors: '已安裝 {count} 個 Skills,有 {errors} 個錯誤',
2209
2195
  // P1-CLI-1:locale fallback 摘要(安裝結束後顯示,列出沒有對應語系變體而退回英文來源的 skill)
@@ -2567,12 +2553,10 @@ export const messages = {
2567
2553
  question: '选择内容模式:',
2568
2554
  labels: {
2569
2555
  index: '标准',
2570
- full: '完整嵌入',
2571
2556
  minimal: '最小化'
2572
2557
  },
2573
2558
  choices: {
2574
2559
  index: '摘要 + 任务对照表,AI 知道何时读哪个规范',
2575
- full: '完整嵌入所有规则,AI 立即可用但文件较大',
2576
2560
  minimal: '仅文件参考,适合搭配 Skills 使用'
2577
2561
  },
2578
2562
  explanations: {
@@ -2581,11 +2565,6 @@ export const messages = {
2581
2565
  ' → AI 能判断"做什么任务时要读哪个规范"',
2582
2566
  ' → 平衡 Context 使用量和合规程度'
2583
2567
  ],
2584
- full: [
2585
- ' → 所有规则直接嵌入配置文件(文件约 10-15 KB)',
2586
- ' → AI 无需额外读档,合规率最高',
2587
- ' → 适合短期任务或需要严格遵循的项目'
2588
- ],
2589
2568
  minimal: [
2590
2569
  ' → 仅包含 .standards/ 文件清单',
2591
2570
  ' → AI 需要主动读取规范文件',
@@ -2795,7 +2774,6 @@ export const messages = {
2795
2774
  warning: '变更 Content Mode 将重新生成所有 AI 工具配置文件',
2796
2775
  explanations: {
2797
2776
  index: ' → AI 会根据任务对照表判断何时读取规范',
2798
- full: ' → 所有规则直接嵌入,AI 合规率最高',
2799
2777
  minimal: ' → AI 需主动读取规范,建议搭配 Skills'
2800
2778
  }
2801
2779
  },
@@ -3144,7 +3122,6 @@ export const messages = {
3144
3122
  standardsScopeLean: '精简(Skills 处理其余)',
3145
3123
  standardsScopeComplete: '完整',
3146
3124
  contentModeLabel: '内容模式',
3147
- contentModeFull: '完整嵌入',
3148
3125
  contentModeIndex: '标准(推荐)',
3149
3126
  contentModeMinimal: '最小(仅核心)',
3150
3127
  displayLanguageLabel: '显示语言',