bmad-plus 0.14.0 → 0.17.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 (66) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +55 -18
  3. package/SECURITY.md +71 -0
  4. package/THIRD-PARTY-LICENSES.md +349 -0
  5. package/osint-agent-package/README.md +1 -1
  6. package/package.json +11 -3
  7. package/readme-international/README.de.md +20 -9
  8. package/readme-international/README.es.md +21 -10
  9. package/readme-international/README.fr.md +20 -9
  10. package/src/bmad-plus/agents/agent-architect-dev/SKILL.md +11 -13
  11. package/src/bmad-plus/agents/agent-orchestrator/SKILL.md +147 -8
  12. package/src/bmad-plus/agents/agent-quality/SKILL.md +41 -11
  13. package/src/bmad-plus/data/role-triggers.yaml +19 -0
  14. package/src/bmad-plus/module-help.csv +1 -0
  15. package/src/bmad-plus/module.yaml +1 -0
  16. package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/create-story.md +3 -1
  17. package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/dev-story-checklist.md +2 -0
  18. package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/dev-story.md +5 -1
  19. package/src/bmad-plus/packs/pack-memory/README.md +29 -4
  20. package/src/bmad-plus/packs/pack-memory/memory-orchestrator.md +21 -1
  21. package/src/bmad-plus/packs/pack-memory/shared/karpathy-guardrails.md +3 -3
  22. package/src/bmad-plus/packs/pack-memory/shared/memory-protocol.md +27 -3
  23. package/src/bmad-plus/packs/pack-memory/zecher-agent.md +18 -2
  24. package/src/bmad-plus/skills/bmad-plus-autopilot/SKILL.md +47 -10
  25. package/src/bmad-plus/skills/bmad-plus-parallel/SKILL.md +17 -3
  26. package/src/bmad-plus/skills/bmad-plus-sync/SKILL.md +76 -67
  27. package/src/bmad-plus/skills/bmad-plus-uat/SKILL.md +158 -0
  28. package/src/bmad-plus/skills/bmad-plus-uat/ref/uat-results.schema.json +60 -0
  29. package/src/bmad-plus/skills/bmad-plus-uat/ref/uat-spec.schema.json +121 -0
  30. package/src/bmad-plus/skills/bmad-plus-uat/ref/uat-triage.schema.json +60 -0
  31. package/src/bmad-plus/skills/bmad-plus-uat/template/page.html +628 -0
  32. package/src/bmad-plus/skills/bmad-plus-uat/template/strings.json +442 -0
  33. package/src/bmad-plus/skills/bmad-plus-uat/templates/README.md +63 -0
  34. package/src/bmad-plus/skills/bmad-plus-uat/templates/example-uat-spec.json +95 -0
  35. package/src/bmad-plus/skills/bmad-plus-uat/templates/uat-release-gate.mjs +127 -0
  36. package/src/bmad-plus/skills/bmad-plus-uat/templates/uat-spec-present.mjs +77 -0
  37. package/tools/build/check-install-contract.js +202 -4
  38. package/tools/build/generate.js +16 -0
  39. package/tools/build/generated-adapters/.codex/AGENTS.md +1 -1
  40. package/tools/build/generated-adapters/.cursor/rules/bmad-plus.mdc +1 -1
  41. package/tools/build/generated-adapters/.opencode/AGENTS.md +1 -1
  42. package/tools/build/generated-adapters/AGENTS.md +1 -1
  43. package/tools/build/generated-adapters/CLAUDE.md +1 -1
  44. package/tools/build/generated-adapters/CONVENTIONS.md +1 -1
  45. package/tools/build/generated-adapters/GEMINI.md +1 -1
  46. package/tools/cli/bmad-plus-cli.js +15 -12
  47. package/tools/cli/commands/autoconfig.js +4 -2
  48. package/tools/cli/commands/doctor.js +1 -0
  49. package/tools/cli/commands/install.js +21 -2
  50. package/tools/cli/commands/memory-journal-cmd.js +119 -19
  51. package/tools/cli/commands/nexus.js +111 -0
  52. package/tools/cli/commands/uat.js +405 -0
  53. package/tools/cli/i18n.js +10 -0
  54. package/tools/cli/lib/README-memory-journal.md +19 -8
  55. package/tools/cli/lib/installation-health.js +6 -0
  56. package/tools/cli/lib/memory-journal.js +0 -0
  57. package/tools/cli/lib/memory-outcomes.js +293 -0
  58. package/tools/cli/lib/memory-store.js +139 -0
  59. package/tools/cli/lib/nexus-process.js +377 -0
  60. package/tools/cli/lib/nexus.js +1532 -0
  61. package/tools/cli/lib/pack-copy.js +39 -11
  62. package/tools/cli/lib/packs.js +17 -3
  63. package/tools/cli/lib/uat.js +887 -0
  64. package/tools/maintain/upstream-candidate.js +456 -0
  65. package/tools/release/publication-content.js +4 -1
  66. package/tools/release/supply-chain.js +282 -0
@@ -0,0 +1,442 @@
1
+ {
2
+ "en": {
3
+ "name": "English",
4
+ "dir": "ltr",
5
+ "uiLanguage": "Page language",
6
+ "before": "Before you start",
7
+ "tester": "Your first name — it signs this run",
8
+ "start": "Start a new run",
9
+ "resume": "Or resume a run already started",
10
+ "stepsLabel": "steps",
11
+ "seen": "Seen",
12
+ "notSeen": "Not seen",
13
+ "blocked": "Blocked",
14
+ "skip": "Skip this optional step",
15
+ "optional": "Optional step",
16
+ "where": "Where",
17
+ "doIt": "Do",
18
+ "expect": "What you must see — tick every line",
19
+ "note": "What you see instead, or any remark (word for word if you can)",
20
+ "whyNot": "What did you see instead?",
21
+ "todo": "to do",
22
+ "finish": "Finish",
23
+ "finishRun": "Finish this run",
24
+ "finished": "Run finished",
25
+ "overall": "Overall remarks",
26
+ "saveJson": "Save the JSON on my device",
27
+ "copyJson": "Copy the JSON",
28
+ "copied": "JSON copied.",
29
+ "confirmUnanswered": "{n} line(s) are not ticked. Finish anyway?",
30
+ "writesWarning": "This step writes for real on",
31
+ "intended": "It is intended.",
32
+ "savedLocal": "Saved in this browser — remember to save the JSON at the end",
33
+ "savedRemote": "Saved ·",
34
+ "localMode": "This page is a local file: at the end, save the JSON and hand the file over — that is what the agent reads.",
35
+ "dbMode": "Your answers are saved as you go; the agent reads them directly, you have nothing to send.",
36
+ "serveMode": "Your answers are saved straight into the project as you tick; you have nothing to send.",
37
+ "startFirst": "Enter your first name and start a run first — nothing is recorded before that.",
38
+ "copyCommand": "Click to copy",
39
+ "commandCopied": "Copied",
40
+ "runBy": "Run by {tester}",
41
+ "finishedOn": "finished on {date}",
42
+ "countSeen": "seen",
43
+ "countNotSeen": "not seen",
44
+ "countBlocked": "blocked"
45
+ },
46
+ "fr": {
47
+ "name": "Français",
48
+ "dir": "ltr",
49
+ "uiLanguage": "Langue de la page",
50
+ "before": "Avant de commencer",
51
+ "tester": "Ton prénom — il signe la recette",
52
+ "start": "Commencer une nouvelle recette",
53
+ "resume": "Ou reprendre une recette déjà commencée",
54
+ "stepsLabel": "étapes",
55
+ "seen": "Vu",
56
+ "notSeen": "Pas vu",
57
+ "blocked": "Bloqué",
58
+ "skip": "Sauter cette étape facultative",
59
+ "optional": "Étape facultative",
60
+ "where": "Où",
61
+ "doIt": "Fais",
62
+ "expect": "Ce que tu dois voir — coche chaque ligne",
63
+ "note": "Ce que tu vois à la place, ou toute remarque (mot pour mot si possible)",
64
+ "whyNot": "Qu'est-ce que tu vois à la place ?",
65
+ "todo": "à faire",
66
+ "finish": "Terminer",
67
+ "finishRun": "Terminer la recette",
68
+ "finished": "Recette terminée",
69
+ "overall": "Remarques d'ensemble",
70
+ "saveJson": "Enregistrer le JSON sur mon appareil",
71
+ "copyJson": "Copier le JSON",
72
+ "copied": "JSON copié.",
73
+ "confirmUnanswered": "{n} ligne(s) ne sont pas cochées. Terminer quand même ?",
74
+ "writesWarning": "Cette étape écrit pour de vrai sur",
75
+ "intended": "C'est voulu.",
76
+ "savedLocal": "Enregistré dans ce navigateur — pense à « Enregistrer le JSON » à la fin",
77
+ "savedRemote": "Enregistré ·",
78
+ "localMode": "Cette page est un fichier local : à la fin, enregistre le JSON et transmets le fichier — c'est lui que l'agent lit.",
79
+ "dbMode": "Tes réponses sont enregistrées au fur et à mesure : l'agent les lit directement, tu n'as rien à envoyer.",
80
+ "serveMode": "Tes réponses sont enregistrées directement dans le projet à chaque coche ; tu n'as rien à envoyer.",
81
+ "startFirst": "Écris ton prénom et commence la recette d’abord — rien n’est enregistré avant.",
82
+ "copyCommand": "Cliquer pour copier",
83
+ "commandCopied": "Copié",
84
+ "runBy": "Recette de {tester}",
85
+ "finishedOn": "terminée le {date}",
86
+ "countSeen": "vus",
87
+ "countNotSeen": "pas vus",
88
+ "countBlocked": "bloqués"
89
+ },
90
+ "es": {
91
+ "name": "Español",
92
+ "dir": "ltr",
93
+ "uiLanguage": "Idioma de la página",
94
+ "before": "Antes de empezar",
95
+ "tester": "Tu nombre — firma esta prueba",
96
+ "start": "Empezar una nueva prueba",
97
+ "resume": "O retomar una prueba ya empezada",
98
+ "stepsLabel": "pasos",
99
+ "seen": "Visto",
100
+ "notSeen": "No visto",
101
+ "blocked": "Bloqueado",
102
+ "skip": "Omitir este paso opcional",
103
+ "optional": "Paso opcional",
104
+ "where": "Dónde",
105
+ "doIt": "Haz",
106
+ "expect": "Lo que debes ver — marca cada línea",
107
+ "note": "Lo que ves en su lugar, o cualquier observación (palabra por palabra si puedes)",
108
+ "whyNot": "¿Qué ves en su lugar?",
109
+ "todo": "por hacer",
110
+ "finish": "Terminar",
111
+ "finishRun": "Terminar la prueba",
112
+ "finished": "Prueba terminada",
113
+ "overall": "Observaciones generales",
114
+ "saveJson": "Guardar el JSON en mi dispositivo",
115
+ "copyJson": "Copiar el JSON",
116
+ "copied": "JSON copiado.",
117
+ "confirmUnanswered": "{n} línea(s) sin marcar. ¿Terminar de todos modos?",
118
+ "writesWarning": "Este paso escribe de verdad en",
119
+ "intended": "Es intencionado.",
120
+ "savedLocal": "Guardado en este navegador — acuérdate de guardar el JSON al final",
121
+ "savedRemote": "Guardado ·",
122
+ "localMode": "Esta página es un archivo local: al final, guarda el JSON y entrega el archivo — es lo que lee el agente.",
123
+ "dbMode": "Tus respuestas se guardan sobre la marcha; el agente las lee directamente, no tienes que enviar nada.",
124
+ "serveMode": "Tus respuestas se guardan directamente en el proyecto con cada marca; no tienes que enviar nada.",
125
+ "startFirst": "Escribe tu nombre y empieza la prueba primero: nada se guarda antes.",
126
+ "copyCommand": "Clic para copiar",
127
+ "commandCopied": "Copiado",
128
+ "runBy": "Prueba de {tester}",
129
+ "finishedOn": "terminada el {date}",
130
+ "countSeen": "vistos",
131
+ "countNotSeen": "no vistos",
132
+ "countBlocked": "bloqueados"
133
+ },
134
+ "de": {
135
+ "name": "Deutsch",
136
+ "dir": "ltr",
137
+ "uiLanguage": "Sprache der Seite",
138
+ "before": "Bevor du beginnst",
139
+ "tester": "Dein Vorname — er unterschreibt diesen Durchlauf",
140
+ "start": "Neuen Durchlauf starten",
141
+ "resume": "Oder einen begonnenen Durchlauf fortsetzen",
142
+ "stepsLabel": "Schritte",
143
+ "seen": "Gesehen",
144
+ "notSeen": "Nicht gesehen",
145
+ "blocked": "Blockiert",
146
+ "skip": "Diesen optionalen Schritt überspringen",
147
+ "optional": "Optionaler Schritt",
148
+ "where": "Wo",
149
+ "doIt": "Tu",
150
+ "expect": "Was du sehen musst — jede Zeile abhaken",
151
+ "note": "Was du stattdessen siehst, oder eine Bemerkung (wörtlich, wenn möglich)",
152
+ "whyNot": "Was hast du stattdessen gesehen?",
153
+ "todo": "offen",
154
+ "finish": "Abschließen",
155
+ "finishRun": "Durchlauf abschließen",
156
+ "finished": "Durchlauf abgeschlossen",
157
+ "overall": "Allgemeine Bemerkungen",
158
+ "saveJson": "JSON auf meinem Gerät speichern",
159
+ "copyJson": "JSON kopieren",
160
+ "copied": "JSON kopiert.",
161
+ "confirmUnanswered": "{n} Zeile(n) sind nicht abgehakt. Trotzdem abschließen?",
162
+ "writesWarning": "Dieser Schritt schreibt wirklich auf",
163
+ "intended": "Das ist so gewollt.",
164
+ "savedLocal": "In diesem Browser gespeichert — denk am Ende an „JSON speichern“",
165
+ "savedRemote": "Gespeichert ·",
166
+ "localMode": "Diese Seite ist eine lokale Datei: speichere am Ende das JSON und gib die Datei weiter — sie ist es, die der Agent liest.",
167
+ "dbMode": "Deine Antworten werden laufend gespeichert; der Agent liest sie direkt, du musst nichts senden.",
168
+ "serveMode": "Deine Antworten werden bei jedem Klick direkt im Projekt gespeichert; du musst nichts senden.",
169
+ "startFirst": "Gib zuerst deinen Vornamen ein und starte den Durchlauf — vorher wird nichts gespeichert.",
170
+ "copyCommand": "Zum Kopieren klicken",
171
+ "commandCopied": "Kopiert",
172
+ "runBy": "Durchlauf von {tester}",
173
+ "finishedOn": "abgeschlossen am {date}",
174
+ "countSeen": "gesehen",
175
+ "countNotSeen": "nicht gesehen",
176
+ "countBlocked": "blockiert"
177
+ },
178
+ "pt-br": {
179
+ "name": "Português (Brasil)",
180
+ "dir": "ltr",
181
+ "uiLanguage": "Idioma da página",
182
+ "before": "Antes de começar",
183
+ "tester": "Seu primeiro nome — ele assina esta rodada",
184
+ "start": "Começar uma nova rodada",
185
+ "resume": "Ou retomar uma rodada já iniciada",
186
+ "stepsLabel": "etapas",
187
+ "seen": "Visto",
188
+ "notSeen": "Não visto",
189
+ "blocked": "Bloqueado",
190
+ "skip": "Pular esta etapa opcional",
191
+ "optional": "Etapa opcional",
192
+ "where": "Onde",
193
+ "doIt": "Faça",
194
+ "expect": "O que você deve ver — marque cada linha",
195
+ "note": "O que você vê no lugar, ou qualquer observação (palavra por palavra, se possível)",
196
+ "whyNot": "O que você viu no lugar?",
197
+ "todo": "a fazer",
198
+ "finish": "Encerrar",
199
+ "finishRun": "Encerrar a rodada",
200
+ "finished": "Rodada encerrada",
201
+ "overall": "Observações gerais",
202
+ "saveJson": "Salvar o JSON no meu dispositivo",
203
+ "copyJson": "Copiar o JSON",
204
+ "copied": "JSON copiado.",
205
+ "confirmUnanswered": "{n} linha(s) sem marcação. Encerrar mesmo assim?",
206
+ "writesWarning": "Esta etapa grava de verdade em",
207
+ "intended": "É intencional.",
208
+ "savedLocal": "Salvo neste navegador — lembre-se de salvar o JSON no final",
209
+ "savedRemote": "Salvo ·",
210
+ "localMode": "Esta página é um arquivo local: no final, salve o JSON e entregue o arquivo — é ele que o agente lê.",
211
+ "dbMode": "Suas respostas são salvas conforme você avança; o agente as lê diretamente, você não precisa enviar nada.",
212
+ "serveMode": "Suas respostas são salvas direto no projeto a cada marcação; você não precisa enviar nada.",
213
+ "startFirst": "Digite seu nome e comece a rodada primeiro — nada é salvo antes disso.",
214
+ "copyCommand": "Clique para copiar",
215
+ "commandCopied": "Copiado",
216
+ "runBy": "Rodada de {tester}",
217
+ "finishedOn": "encerrada em {date}",
218
+ "countSeen": "vistos",
219
+ "countNotSeen": "não vistos",
220
+ "countBlocked": "bloqueados"
221
+ },
222
+ "ru": {
223
+ "name": "Русский",
224
+ "dir": "ltr",
225
+ "uiLanguage": "Язык страницы",
226
+ "before": "Перед началом",
227
+ "tester": "Ваше имя — оно подписывает этот прогон",
228
+ "start": "Начать новый прогон",
229
+ "resume": "Или продолжить начатый прогон",
230
+ "stepsLabel": "шагов",
231
+ "seen": "Видно",
232
+ "notSeen": "Не видно",
233
+ "blocked": "Недоступно",
234
+ "skip": "Пропустить этот необязательный шаг",
235
+ "optional": "Необязательный шаг",
236
+ "where": "Где",
237
+ "doIt": "Сделайте",
238
+ "expect": "Что вы должны увидеть — отметьте каждую строку",
239
+ "note": "Что вы видите вместо этого, или любое замечание (дословно, если можно)",
240
+ "whyNot": "Что вы увидели вместо этого?",
241
+ "todo": "осталось",
242
+ "finish": "Завершить",
243
+ "finishRun": "Завершить прогон",
244
+ "finished": "Прогон завершён",
245
+ "overall": "Общие замечания",
246
+ "saveJson": "Сохранить JSON на устройство",
247
+ "copyJson": "Скопировать JSON",
248
+ "copied": "JSON скопирован.",
249
+ "confirmUnanswered": "Строк без отметки: {n}. Всё равно завершить?",
250
+ "writesWarning": "Этот шаг реально пишет в",
251
+ "intended": "Так задумано.",
252
+ "savedLocal": "Сохранено в этом браузере — в конце не забудьте сохранить JSON",
253
+ "savedRemote": "Сохранено ·",
254
+ "localMode": "Эта страница — локальный файл: в конце сохраните JSON и передайте файл — именно его читает агент.",
255
+ "dbMode": "Ваши ответы сохраняются по ходу; агент читает их напрямую, отправлять ничего не нужно.",
256
+ "serveMode": "Ваши ответы сохраняются прямо в проект при каждой отметке; отправлять ничего не нужно.",
257
+ "startFirst": "Сначала введите имя и начните прогон — до этого ничего не сохраняется.",
258
+ "copyCommand": "Нажмите, чтобы скопировать",
259
+ "commandCopied": "Скопировано",
260
+ "runBy": "Прогон: {tester}",
261
+ "finishedOn": "завершён {date}",
262
+ "countSeen": "видно",
263
+ "countNotSeen": "не видно",
264
+ "countBlocked": "недоступно"
265
+ },
266
+ "zh": {
267
+ "name": "中文 (简体)",
268
+ "dir": "ltr",
269
+ "uiLanguage": "页面语言",
270
+ "before": "开始之前",
271
+ "tester": "你的名字 — 它为这次验收签名",
272
+ "start": "开始一次新的验收",
273
+ "resume": "或继续已开始的验收",
274
+ "stepsLabel": "个步骤",
275
+ "seen": "看到了",
276
+ "notSeen": "没看到",
277
+ "blocked": "无法进行",
278
+ "skip": "跳过这个可选步骤",
279
+ "optional": "可选步骤",
280
+ "where": "在哪里",
281
+ "doIt": "怎么做",
282
+ "expect": "你应该看到什么 — 请逐行勾选",
283
+ "note": "你实际看到的内容,或任何备注(尽量逐字记录)",
284
+ "whyNot": "你实际看到了什么?",
285
+ "todo": "待办",
286
+ "finish": "结束",
287
+ "finishRun": "结束这次验收",
288
+ "finished": "验收已结束",
289
+ "overall": "总体备注",
290
+ "saveJson": "把 JSON 保存到我的设备",
291
+ "copyJson": "复制 JSON",
292
+ "copied": "JSON 已复制。",
293
+ "confirmUnanswered": "还有 {n} 行没有勾选。仍然结束吗?",
294
+ "writesWarning": "这一步会真实写入",
295
+ "intended": "这是有意为之。",
296
+ "savedLocal": "已保存在此浏览器 — 结束时记得保存 JSON",
297
+ "savedRemote": "已保存 ·",
298
+ "localMode": "本页是本地文件:结束时请保存 JSON 并把文件交出去 — 代理读取的正是这个文件。",
299
+ "dbMode": "你的回答会即时保存,代理直接读取,你无需发送任何东西。",
300
+ "serveMode": "你的每次勾选都会直接保存到项目中,你无需发送任何东西。",
301
+ "startFirst": "请先输入名字并开始验收——在此之前不会保存任何内容。",
302
+ "copyCommand": "点击复制",
303
+ "commandCopied": "已复制",
304
+ "runBy": "{tester} 的验收",
305
+ "finishedOn": "完成于 {date}",
306
+ "countSeen": "看到",
307
+ "countNotSeen": "没看到",
308
+ "countBlocked": "无法进行"
309
+ },
310
+ "he": {
311
+ "name": "עברית",
312
+ "dir": "rtl",
313
+ "uiLanguage": "שפת הדף",
314
+ "before": "לפני שמתחילים",
315
+ "tester": "השם שלך — הוא חותם על ההרצה הזאת",
316
+ "start": "להתחיל הרצה חדשה",
317
+ "resume": "או להמשיך הרצה שכבר התחילה",
318
+ "stepsLabel": "שלבים",
319
+ "seen": "נראה",
320
+ "notSeen": "לא נראה",
321
+ "blocked": "חסום",
322
+ "skip": "לדלג על השלב הרשות הזה",
323
+ "optional": "שלב רשות",
324
+ "where": "איפה",
325
+ "doIt": "מה לעשות",
326
+ "expect": "מה צריך לראות — סמן כל שורה",
327
+ "note": "מה ראית במקום, או כל הערה (מילה במילה אם אפשר)",
328
+ "whyNot": "מה ראית במקום?",
329
+ "todo": "נותר",
330
+ "finish": "לסיים",
331
+ "finishRun": "לסיים את ההרצה",
332
+ "finished": "ההרצה הסתיימה",
333
+ "overall": "הערות כלליות",
334
+ "saveJson": "לשמור את ה‑JSON במכשיר שלי",
335
+ "copyJson": "להעתיק את ה‑JSON",
336
+ "copied": "ה‑JSON הועתק.",
337
+ "confirmUnanswered": "{n} שורות לא סומנו. לסיים בכל זאת?",
338
+ "writesWarning": "השלב הזה כותב באמת אל",
339
+ "intended": "זה מכוון.",
340
+ "savedLocal": "נשמר בדפדפן הזה — זכור לשמור את ה‑JSON בסוף",
341
+ "savedRemote": "נשמר ·",
342
+ "localMode": "הדף הזה הוא קובץ מקומי: בסוף שמור את ה‑JSON והעבר את הקובץ — זה מה שהסוכן קורא.",
343
+ "dbMode": "התשובות נשמרות תוך כדי, והסוכן קורא אותן ישירות. אין מה לשלוח.",
344
+ "serveMode": "כל סימון נשמר ישירות בפרויקט. אין מה לשלוח.",
345
+ "startFirst": "קודם כתוב את שמך והתחל הרצה — לפני כן שום דבר לא נשמר.",
346
+ "copyCommand": "לחץ להעתקה",
347
+ "commandCopied": "הועתק",
348
+ "runBy": "הרצה של {tester}",
349
+ "finishedOn": "הסתיימה ב-{date}",
350
+ "countSeen": "נראו",
351
+ "countNotSeen": "לא נראו",
352
+ "countBlocked": "חסומים"
353
+ },
354
+ "ja": {
355
+ "name": "日本語",
356
+ "dir": "ltr",
357
+ "uiLanguage": "ページの言語",
358
+ "before": "はじめる前に",
359
+ "tester": "あなたの名前 — この実施に署名します",
360
+ "start": "新しい実施を始める",
361
+ "resume": "または開始済みの実施を再開する",
362
+ "stepsLabel": "ステップ",
363
+ "seen": "見えた",
364
+ "notSeen": "見えない",
365
+ "blocked": "実施できない",
366
+ "skip": "この任意ステップを飛ばす",
367
+ "optional": "任意のステップ",
368
+ "where": "どこで",
369
+ "doIt": "何をする",
370
+ "expect": "見えるはずのこと — 各行にチェック",
371
+ "note": "代わりに見えたもの、または気づいたこと(できれば一字一句)",
372
+ "whyNot": "代わりに何が見えましたか?",
373
+ "todo": "未実施",
374
+ "finish": "終了",
375
+ "finishRun": "この実施を終了する",
376
+ "finished": "実施を終了しました",
377
+ "overall": "全体の所見",
378
+ "saveJson": "JSON を端末に保存する",
379
+ "copyJson": "JSON をコピーする",
380
+ "copied": "JSON をコピーしました。",
381
+ "confirmUnanswered": "未チェックの行が {n} 件あります。それでも終了しますか?",
382
+ "writesWarning": "このステップは実際に書き込みます:",
383
+ "intended": "意図した動作です。",
384
+ "savedLocal": "このブラウザに保存しました — 最後に JSON の保存を忘れずに",
385
+ "savedRemote": "保存済み ·",
386
+ "localMode": "このページはローカルファイルです。最後に JSON を保存してファイルを渡してください — エージェントが読むのはそれです。",
387
+ "dbMode": "回答は随時保存され、エージェントが直接読みます。送信は不要です。",
388
+ "serveMode": "チェックするたびに回答がプロジェクトへ直接保存されます。送信は不要です。",
389
+ "startFirst": "まず名前を入力して実施を開始してください。それまでは何も保存されません。",
390
+ "copyCommand": "クリックしてコピー",
391
+ "commandCopied": "コピーしました",
392
+ "runBy": "{tester} の実施",
393
+ "finishedOn": "{date} に終了",
394
+ "countSeen": "見えた",
395
+ "countNotSeen": "見えない",
396
+ "countBlocked": "実施不可"
397
+ },
398
+ "it": {
399
+ "name": "Italiano",
400
+ "dir": "ltr",
401
+ "uiLanguage": "Lingua della pagina",
402
+ "before": "Prima di iniziare",
403
+ "tester": "Il tuo nome — firma questa sessione",
404
+ "start": "Iniziare una nuova sessione",
405
+ "resume": "Oppure riprendere una sessione già iniziata",
406
+ "stepsLabel": "passaggi",
407
+ "seen": "Visto",
408
+ "notSeen": "Non visto",
409
+ "blocked": "Bloccato",
410
+ "skip": "Saltare questo passaggio facoltativo",
411
+ "optional": "Passaggio facoltativo",
412
+ "where": "Dove",
413
+ "doIt": "Fai",
414
+ "expect": "Ciò che devi vedere — spunta ogni riga",
415
+ "note": "Ciò che vedi al suo posto, o qualsiasi osservazione (parola per parola se puoi)",
416
+ "whyNot": "Che cosa hai visto al suo posto?",
417
+ "todo": "da fare",
418
+ "finish": "Terminare",
419
+ "finishRun": "Terminare la sessione",
420
+ "finished": "Sessione terminata",
421
+ "overall": "Osservazioni generali",
422
+ "saveJson": "Salvare il JSON sul mio dispositivo",
423
+ "copyJson": "Copiare il JSON",
424
+ "copied": "JSON copiato.",
425
+ "confirmUnanswered": "{n} riga/righe non spuntate. Terminare comunque?",
426
+ "writesWarning": "Questo passaggio scrive davvero su",
427
+ "intended": "È voluto.",
428
+ "savedLocal": "Salvato in questo browser — ricordati di salvare il JSON alla fine",
429
+ "savedRemote": "Salvato ·",
430
+ "localMode": "Questa pagina è un file locale: alla fine salva il JSON e consegna il file — è quello che legge l'agente.",
431
+ "dbMode": "Le tue risposte vengono salvate man mano; l'agente le legge direttamente, non devi inviare nulla.",
432
+ "serveMode": "Le tue risposte vengono salvate direttamente nel progetto a ogni spunta; non devi inviare nulla.",
433
+ "startFirst": "Scrivi il tuo nome e inizia prima la sessione: prima non viene salvato nulla.",
434
+ "copyCommand": "Clic per copiare",
435
+ "commandCopied": "Copiato",
436
+ "runBy": "Sessione di {tester}",
437
+ "finishedOn": "terminata il {date}",
438
+ "countSeen": "visti",
439
+ "countNotSeen": "non visti",
440
+ "countBlocked": "bloccati"
441
+ }
442
+ }
@@ -0,0 +1,63 @@
1
+ # Project gates for human acceptance
2
+
3
+ BMAD+ installs no lifecycle hook, so an instruction can be skipped and a Nexus task
4
+ can be bypassed. These two scripts are the layer that cannot: they run inside your
5
+ own checks and fail the command that calls them. Copy the ones you want into your
6
+ project — for example under `scripts/` — and wire them where they bite.
7
+
8
+ Both need nothing but Node 20 and are safe to read before you run them.
9
+
10
+ ## G1 — a version does not leave without its recipe
11
+
12
+ `uat-spec-present.mjs` fails when no recipe names the version in `package.json`.
13
+
14
+ ```jsonc
15
+ // package.json
16
+ {
17
+ "scripts": {
18
+ "uat:spec": "node scripts/uat-spec-present.mjs",
19
+ "pretest": "npm run uat:spec" // or call it from your CI step
20
+ }
21
+ }
22
+ ```
23
+
24
+ A grouped recipe covers a version because it **names** it in `versions`, never
25
+ because its file name suggests a range. That is deliberate: deducing coverage from
26
+ a range makes a version look checked when nobody wrote anything about it.
27
+
28
+ Where to run it: the same place your tests run, and before the push, not after the
29
+ deployment. A reminder printed once the version is live only records the miss.
30
+
31
+ ## G3 — production waits for a run that was read
32
+
33
+ `uat-release-gate.mjs` resolves the recipe covering the current version and runs
34
+ `bmad-plus uat gate` on it. It exits 0 only when the latest run is finished, answers
35
+ the current revision of the recipe, leaves no expectation unanswered, has every
36
+ failure classified with a decision, and has every passed writing step confirmed
37
+ read-only.
38
+
39
+ ```sh
40
+ # deploy-production.sh
41
+ node scripts/uat-release-gate.mjs || exit 1
42
+ # … deploy only below this line
43
+ ```
44
+
45
+ Exit codes: `0` passed · `1` failed · `2` no finished run yet · `3` the run answered
46
+ another revision of the recipe · `4` the gate itself could not run. The last one is
47
+ not a pass: a missing gate is a missing gate.
48
+
49
+ The script runs the CLI's own entry point with the Node that started it: `BMAD_PLUS_CLI`
50
+ if you set it, otherwise `node_modules/bmad-plus/` if the project installed it. No shell
51
+ and no `npx`: a Windows `.cmd` shim cannot be spawned without a shell, and a release gate
52
+ must not depend on a download. If neither exists it exits 4 and says so.
53
+
54
+ ## What these gates do and do not establish
55
+
56
+ They establish that a recipe exists for the version, and that a human run covering
57
+ it is complete, current and classified. They do not establish that the tester looked
58
+ at the right place, and they do not judge the product. Every report says
59
+ *human-observed* for that reason.
60
+
61
+ A failure classified as a defect of the recipe is not a product fix: amend the spec,
62
+ rebuild it, replay the affected steps, and say so. A failure nobody could classify
63
+ keeps the gate red on purpose — ask the tester what they saw instead of guessing.
@@ -0,0 +1,95 @@
1
+ {
2
+ "schema": "bmad-plus/uat-spec/2",
3
+ "id": "example-1.0.0",
4
+ "product": "Example",
5
+ "versions": ["1.0.0"],
6
+ "date": "2026-09-16",
7
+ "language": "en",
8
+ "title": "What this delivery changes, in one sentence — this becomes the page title",
9
+ "subtitle": "Example · TEST environment · version 1.0.0 · 2026-09-16",
10
+ "environment": { "name": "TEST", "url": "https://test.example.com" },
11
+ "estimate": "5 min",
12
+ "intro": [
13
+ "<b>What the measurement showed.</b> The numbers taken before the delivery: how many cases change, where, production included. \"0\" is a number and gets said."
14
+ ],
15
+ "warnings": [
16
+ "<b>Step 2 writes for real on TEST</b> (a button that persists). It is intended."
17
+ ],
18
+ "witnesses": [
19
+ {
20
+ "id": "TEST-001",
21
+ "proof": "select updated_at, funder from folder where reference = 'TEST-001'",
22
+ "reads": ["1-nominal"],
23
+ "writes": ["2-the-gesture"]
24
+ }
25
+ ],
26
+ "steps": [
27
+ {
28
+ "id": "0-setup",
29
+ "title": "Setup",
30
+ "duration": "1 min",
31
+ "where": [
32
+ "Open <a href=\"https://test.example.com\" target=\"_blank\" rel=\"noopener\">test.example.com</a> and sign in."
33
+ ],
34
+ "do": ["Find the <span class=\"ecran\">Folders</span> menu."],
35
+ "expect": [{ "id": "a", "text": "I am signed in and I can see the list." }]
36
+ },
37
+ {
38
+ "id": "1-nominal",
39
+ "title": "The nominal case (TEST-001)",
40
+ "duration": "2 min",
41
+ "stories": [{ "ref": "story-12", "criteria": ["AC-3"] }],
42
+ "where": [
43
+ "Folder <code>TEST-001</code> → tab <span class=\"ecran\">Technical</span> → the card named exactly as on screen."
44
+ ],
45
+ "do": [
46
+ "One click per line: click <span class=\"ecran\">Analyse</span>.",
47
+ "Wait until the button reads <span class=\"ecran\">Analyse</span> again."
48
+ ],
49
+ "expect": [
50
+ {
51
+ "id": "a",
52
+ "text": "The line reads exactly: <span class=\"ecran\">Label copied from the code, accents included or not</span>."
53
+ },
54
+ {
55
+ "id": "b",
56
+ "text": "One fact per line: the <span class=\"ecran\">My box</span> checkbox is <b>ticked</b>."
57
+ }
58
+ ]
59
+ },
60
+ {
61
+ "id": "2-the-gesture",
62
+ "title": "The gesture that lifts the red",
63
+ "duration": "2 min",
64
+ "writes": true,
65
+ "verify": {
66
+ "kind": "sql",
67
+ "text": "select updated_at, funder from folder where reference = 'TEST-001' — updated_at must be later than the run"
68
+ },
69
+ "where": ["Same folder, same card."],
70
+ "do": [
71
+ "Click <span class=\"ecran\">Confirm</span>. <b>This writes for real.</b>",
72
+ "Come back to the folder with the browser's back button."
73
+ ],
74
+ "expect": [
75
+ {
76
+ "id": "a",
77
+ "text": "The <span class=\"ecran\">My box</span> checkbox is now <b>ticked</b>."
78
+ },
79
+ {
80
+ "id": "b",
81
+ "text": "Positive control: <code>TEST-002</code> is <b>unchanged</b> — its box was already ticked and no link appeared."
82
+ }
83
+ ]
84
+ }
85
+ ],
86
+ "closing": {
87
+ "text": [
88
+ "<b>What did not change</b>: no migration, and the deployment touched no data.",
89
+ "<b>What waits for a decision</b>: name it here, or say there is none."
90
+ ]
91
+ },
92
+ "authorNotes": [
93
+ "Free field for the agent who wrote this: doubts, witnesses not yet measured, labels to confirm. The page ignores it; the reviewer reads it."
94
+ ]
95
+ }