gennady 0.8.4-next.1 → 0.8.4-next.3

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 (156) hide show
  1. package/README.md +57 -0
  2. package/ai/directives/coding/README.md +4 -0
  3. package/ai/directives/infra/README.md +2 -0
  4. package/ai/directives/infra/eslint-setup.xml +1 -1
  5. package/ai/directives/knowledge.xml +1 -1
  6. package/ai/directives/sdd/README.md +38 -16
  7. package/ai/skills/README.md +15 -4
  8. package/ai/skills/sdd-execute/scripts/README.md +2 -2
  9. package/ai/skills/sdd-execute/scripts/__tests__/verify-delegation.test.ts +119 -0
  10. package/ai/skills/sdd-execute/scripts/classify-scripts.js +6 -0
  11. package/ai/skills/sdd-execute/scripts/classify-scripts.ts +15 -1
  12. package/ai/skills/sdd-execute/scripts/verify.sh +66 -11
  13. package/ai/skills/sdd-infra/SKILL.md +4 -2
  14. package/cli/cmd/README.md +53 -29
  15. package/dist/ai/directives/coding/README.md +4 -0
  16. package/dist/ai/directives/infra/README.md +2 -0
  17. package/dist/ai/directives/infra/eslint-setup.xml +1 -1
  18. package/dist/ai/directives/knowledge.xml +1 -1
  19. package/dist/ai/directives/sdd/README.md +38 -16
  20. package/dist/ai/skills/README.md +15 -4
  21. package/dist/ai/skills/sdd-execute/scripts/README.md +2 -2
  22. package/dist/ai/skills/sdd-execute/scripts/__tests__/verify-delegation.test.ts +119 -0
  23. package/dist/ai/skills/sdd-execute/scripts/classify-scripts.js +6 -0
  24. package/dist/ai/skills/sdd-execute/scripts/classify-scripts.ts +15 -1
  25. package/dist/ai/skills/sdd-execute/scripts/verify.sh +66 -11
  26. package/dist/ai/skills/sdd-infra/SKILL.md +4 -2
  27. package/dist/chunks/{classify-mr-stage.logic-r9UoBm08.js → classify-mr-stage.logic-C9nlmo7G.js} +2 -2
  28. package/dist/chunks/help-B02LDQzW.js +18 -0
  29. package/dist/chunks/{help-BlgP1zki.js → help-CjeiaUQ_.js} +1 -1
  30. package/dist/chunks/help-DX_3WUts.js +12 -0
  31. package/dist/chunks/{help.cmd-BJ6-lc4I.js → help.cmd-Bz1YqU2V.js} +4 -0
  32. package/dist/chunks/{index-CSz4HqEu.js → index-9Bkdk7RL.js} +2 -2
  33. package/dist/chunks/{index-CL_aLkgt.js → index-BA76NeUs.js} +2 -2
  34. package/dist/chunks/{index-zy8MA-fd.js → index-BDl2IAXu.js} +3 -3
  35. package/dist/chunks/{index-Dlb8K8GQ.js → index-BGgXGXg-.js} +1 -1
  36. package/dist/chunks/{index-CDM6lQ5g.js → index-BJ1a8lhw.js} +13 -13
  37. package/dist/chunks/{index-SDjD_RBF.js → index-BK1NwQr1.js} +2 -2
  38. package/dist/chunks/{index-wvamJD3a.js → index-BLfQaUv5.js} +2 -2
  39. package/dist/chunks/index-BMLtkwzj.js +98 -0
  40. package/dist/chunks/{index-CSZFsxeM.js → index-BMWZFp4U.js} +2 -2
  41. package/dist/chunks/index-BNVroM3w.js +188 -0
  42. package/dist/chunks/{index-C5B_vY8J.js → index-BUe8xaDt.js} +3 -3
  43. package/dist/chunks/{index-BEtOYJC5.js → index-Bd51QuVH.js} +2 -2
  44. package/dist/chunks/{index-Isv3MMxW.js → index-C-y9uwFd.js} +1 -1
  45. package/dist/chunks/{index-CKHpOQ1l.js → index-C4EN2eIa.js} +2 -2
  46. package/dist/chunks/{index-N5P1Aadf.js → index-CJvv33n7.js} +2 -2
  47. package/dist/chunks/index-CM0Gf1_N.js +410 -0
  48. package/dist/chunks/index-CXRsLQR8.js +205 -0
  49. package/dist/chunks/{index-DcqdJ116.js → index-C_Cz5D_b.js} +2 -2
  50. package/dist/chunks/{index-D9zXaNK2.js → index-CgZ9VMDN.js} +2 -2
  51. package/dist/chunks/{index-DcENgDCF.js → index-ChNXCDzn.js} +2 -2
  52. package/dist/chunks/{index-DZTNIonC.js → index-CkQ3o27J.js} +2 -2
  53. package/dist/chunks/{index-qFD4Gwhm.js → index-CrpSPpC-.js} +2 -2
  54. package/dist/chunks/{index-DfS5AAVu.js → index-CvJ5NhsB.js} +1 -1
  55. package/dist/chunks/{index-CiRNZljf.js → index-DGDuSviU.js} +2 -2
  56. package/dist/chunks/{index-CatK_HzA.js → index-DJ2acfLK.js} +2 -2
  57. package/dist/chunks/{index-e6-st8zp.js → index-DPdRu-zq.js} +2 -2
  58. package/dist/chunks/{index-Bw9-54Mu.js → index-DW3WSoOG.js} +2 -2
  59. package/dist/chunks/{index-AHtpvdDo.js → index-Ddot2Nhe.js} +205 -224
  60. package/dist/chunks/{index-DHvmyJgt.js → index-DpAdFAL8.js} +2 -2
  61. package/dist/chunks/{index-fxRBsDvT.js → index-RxmZo2qu.js} +2 -2
  62. package/dist/chunks/{index-QHOWgn8q.js → index-Y-juM436.js} +2 -2
  63. package/dist/chunks/{index-BBm9zeai.js → index-e9JD7pCh.js} +1 -1
  64. package/dist/chunks/{index-D3oX4PrK.js → index-l9U1wyLq.js} +1 -1
  65. package/dist/chunks/{run-review-command.logic-CXcCegK2.js → run-review-command.logic-C08f3D9C.js} +14 -14
  66. package/dist/chunks/services-q8rLnybu.js +10151 -0
  67. package/dist/chunks/shared-DbIfVgIg.js +966 -0
  68. package/dist/cli/cmd/fix/fix.cmd.d.ts +7 -0
  69. package/dist/cli/cmd/fix/help.d.ts +4 -0
  70. package/dist/cli/cmd/fix/index.d.ts +1 -0
  71. package/dist/cli/cmd/sync/sync-core.d.ts +10 -0
  72. package/dist/cli/cmd/sync/sync.types.d.ts +2 -0
  73. package/dist/cli/cmd/sync-skills/sync-skills-core.d.ts +12 -0
  74. package/dist/cli/cmd/sync-skills/sync-skills.types.d.ts +2 -0
  75. package/dist/cli/cmd/verify/help.d.ts +4 -0
  76. package/dist/cli/cmd/verify/index.d.ts +1 -0
  77. package/dist/cli/cmd/verify/verify.cmd.d.ts +7 -0
  78. package/dist/gennady.js +47 -35
  79. package/dist/index.js +4 -4
  80. package/dist/plugins/anystack/anystack-plugin.d.ts +12 -0
  81. package/dist/plugins/golang/golang-detect.logic.d.ts +57 -0
  82. package/dist/plugins/golang/golang-plan.logic.d.ts +35 -0
  83. package/dist/plugins/golang/golang-plugin.d.ts +9 -0
  84. package/dist/plugins/golang/golang-scope.logic.d.ts +39 -0
  85. package/dist/plugins/index.d.ts +7 -0
  86. package/dist/plugins/node/classify-npm-scripts.d.ts +21 -0
  87. package/dist/plugins/node/node-plugin.d.ts +12 -0
  88. package/dist/services/config/config-loader.d.ts +68 -0
  89. package/dist/services/plugins/plugin-assets.d.ts +26 -0
  90. package/dist/services/plugins/resolve-plugins.d.ts +46 -0
  91. package/dist/services/stack/env-fail.d.ts +55 -0
  92. package/dist/services/stack/gate-runner.d.ts +32 -0
  93. package/dist/services/stack/plugin-api.d.ts +4 -0
  94. package/dist/services/stack/stack-config.d.ts +66 -0
  95. package/dist/services/stack/stack-registry.d.ts +31 -0
  96. package/dist/services/stack/stack.types.d.ts +313 -0
  97. package/dist/services/stack/tree-guard.d.ts +45 -0
  98. package/dist/shared/backend/rc/rc-config.d.ts +3 -1
  99. package/dist/shared/common/exec.d.ts +6 -0
  100. package/docs/sdd-flow.md +471 -0
  101. package/package.json +15 -6
  102. package/plugins/anystack/anystack-plugin.ts +52 -0
  103. package/plugins/anystack/plugin.json +5 -0
  104. package/plugins/golang/directives/infra/golang-setup.xml +159 -0
  105. package/plugins/golang/golang-detect.logic.ts +358 -0
  106. package/plugins/golang/golang-plan.logic.ts +379 -0
  107. package/plugins/golang/golang-plugin.ts +81 -0
  108. package/plugins/golang/golang-scope.logic.ts +503 -0
  109. package/plugins/golang/plugin.json +5 -0
  110. package/plugins/golang/skills/sdd-infra-golang/SKILL.md +114 -0
  111. package/plugins/node/classify-npm-scripts.ts +146 -0
  112. package/plugins/node/node-plugin.ts +136 -0
  113. package/plugins/node/plugin.json +5 -0
  114. package/ai/fw/v1/architecture/blueprint-factory.xml +0 -77
  115. package/ai/fw/v1/core/mental-model.xml +0 -50
  116. package/ai/fw/v1/discovery/intent-reactor.xml +0 -92
  117. package/ai/fw/v1/production/swarm-protocol.xml +0 -122
  118. package/ai/fw/v1/review/quality-pipeline.xml +0 -102
  119. package/ai/fw/v2/arch-universal.xml +0 -73
  120. package/ai/fw-draft/README.md +0 -79
  121. package/ai/fw-draft/bin/discovery.sh +0 -116
  122. package/ai/fw-draft/gennady.xml +0 -58
  123. package/ai/fw-draft/provider/claude.xml +0 -16
  124. package/ai/fw-draft/provider/cursor.xml +0 -23
  125. package/ai/fw-draft/provider/default.xml +0 -12
  126. package/ai/fw-draft/roles/developer.xml +0 -18
  127. package/ai/fw-draft/router.xml +0 -39
  128. package/ai/fw-draft/routes/development.xml +0 -32
  129. package/ai/fw-draft/routes/universal.xml +0 -58
  130. package/ai/fw-draft/rules/dev/base/file-structure-rules.xml +0 -89
  131. package/ai/fw-draft/rules/dev/typescript/contacts.xml +0 -194
  132. package/ai/skills/sdd-hooks-install/SKILL.md +0 -89
  133. package/dist/ai/fw/v1/architecture/blueprint-factory.xml +0 -77
  134. package/dist/ai/fw/v1/core/mental-model.xml +0 -50
  135. package/dist/ai/fw/v1/discovery/intent-reactor.xml +0 -92
  136. package/dist/ai/fw/v1/production/swarm-protocol.xml +0 -122
  137. package/dist/ai/fw/v1/review/quality-pipeline.xml +0 -102
  138. package/dist/ai/fw/v2/arch-universal.xml +0 -73
  139. package/dist/ai/fw-draft/README.md +0 -79
  140. package/dist/ai/fw-draft/bin/discovery.sh +0 -116
  141. package/dist/ai/fw-draft/gennady.xml +0 -58
  142. package/dist/ai/fw-draft/provider/claude.xml +0 -16
  143. package/dist/ai/fw-draft/provider/cursor.xml +0 -23
  144. package/dist/ai/fw-draft/provider/default.xml +0 -12
  145. package/dist/ai/fw-draft/roles/developer.xml +0 -18
  146. package/dist/ai/fw-draft/router.xml +0 -39
  147. package/dist/ai/fw-draft/routes/development.xml +0 -32
  148. package/dist/ai/fw-draft/routes/universal.xml +0 -58
  149. package/dist/ai/fw-draft/rules/dev/base/file-structure-rules.xml +0 -89
  150. package/dist/ai/fw-draft/rules/dev/typescript/contacts.xml +0 -194
  151. package/dist/ai/skills/sdd-hooks-install/SKILL.md +0 -89
  152. package/dist/chunks/index-B1F4er8N.js +0 -164
  153. package/dist/chunks/index-BVvD4fSE.js +0 -377
  154. package/dist/chunks/services-Bv_nk_yC.js +0 -3973
  155. package/dist/chunks/shared--i1fbMFp.js +0 -891
  156. /package/dist/{cli/cmd/orient/core → shared/common}/damerau-levenshtein.d.ts +0 -0
package/README.md CHANGED
@@ -8,6 +8,12 @@ CLI-инструмент для работы с git-изменениями, merg
8
8
 
9
9
  ---
10
10
 
11
+ ## 🧭 SDD-фреймворк
12
+
13
+ Проект развивается по **Spec-Driven Development**: сперва спека, потом тикеты, потом код с независимым аудитом. Как пользоваться скиллами и в какой последовательности — в [**едином гайде `docs/sdd-flow.md`**](docs/sdd-flow.md). Справочники: [скиллы](ai/skills/README.md) · [директивы](ai/directives/sdd/README.md).
14
+
15
+ ---
16
+
11
17
  ## ⚡ Быстрый старт
12
18
 
13
19
  ```bash
@@ -233,6 +239,57 @@ npx gennady lint ./src --autofix --verbose
233
239
 
234
240
  ---
235
241
 
242
+ ### ✅ `verify`
243
+
244
+ Стек-агностичные верификационные гейты: **одна команда для любого стека**. Плагины: `node` (гейты из npm-скриптов `package.json`), `golang` (`go generate` — drift-контроль кодогенерации до сборки, `go build`, `go vet`, `gofmt -l`, `golangci-lint`, `go test`) и `anystack` (без встроенных гейтов: весь список задаётся в `stack.anystack.extraGates` — для экзотических стеков). Стек определяется автоматически; в одном репозитории может быть активно несколько стеков.
245
+
246
+ ```bash
247
+ # План без запуска — начните с этого в незнакомом репозитории
248
+ npx gennady verify --plan
249
+
250
+ # Гейты по изменениям относительно базовой ветки (по умолчанию)
251
+ npx gennady verify
252
+
253
+ # Явная цель / весь репозиторий / подмножество гейтов
254
+ npx gennady verify internal/userapi
255
+ npx gennady verify --all
256
+ npx gennady verify --only=build,vet
257
+ npx gennady verify --skip=lint
258
+ ```
259
+
260
+ **Опции:**
261
+
262
+ - `--plan`, `--dry-run`: показать детекцию, диагностику и план, ничего не запуская
263
+ - `--all` / `--changed`: весь репозиторий / изменённые пакеты (по умолчанию)
264
+ - `--only=<a,b>` / `--skip=<a,b>`: подмножество гейтов — `stack:gate` или короткое `gate` (все активные стеки)
265
+ - `--stack=<id>`: одноразовый `stack.use` (`anystack` | `golang` | `node`)
266
+ - `--root=<path>`, `--json`
267
+
268
+ **Конфиг репозитория** — секция `stack` в `gennady.yaml` (коммитится; личные `.gennadyrc` deep-merge'атся поверх, per-key провенанс виден в `--plan`): переопределения и расширения встроенных плагинов, чтобы разные репозитории не порождали разные команды:
269
+
270
+ ```yaml
271
+ stack:
272
+ use: [golang]
273
+ golang:
274
+ skipGates: [lint]
275
+ overrideGates:
276
+ test: { argv: [make, test], timeout: 15m }
277
+ build: { env: { GOPROXY: 'https://goproxy.example.com/' } }
278
+ extraGates:
279
+ - { id: tidy-drift, argv: [go, mod, tidy, -diff], timeout: 5m }
280
+ # Полный канонический codegen-прогон: skip по умолчанию, адресно перед мерджем
281
+ # через `verify --only=golang:canonical-generate`; driftMeansFailure: true = drift-гейт.
282
+ - { id: canonical-generate, argv: [make, generate], driftMeansFailure: true, timeout: 5m }
283
+ ```
284
+
285
+ **Цикл кодогенерации:** гейт `golang:generate` исполняет `go generate` в реплике рабочего дерева и падает со списком разъехавшихся файлов; `gennady fix golang:generate` материализует результат в реальном дереве для коммита. Работает и с закоммиченным, и с gitignored сгенерированным кодом.
286
+
287
+ **Контракт:** RUN-ALL (все гейты выполняются, отказы накапливаются); SUPPRESS-ON-SUCCESS (успешные гейты молчат); гейты **не изменяют** рабочее дерево — и это принудительно: все гейты исполняются в эфемерной реплике дерева (одна на прогон), мутация без `driftMeansFailure: true` — статус `VIOLATION`, реальное дерево не затрагивается по построению; отказ инструмента (паника линтера, недоступный module proxy) помечается `ENV_FAIL` — это не findings по коду. Таймаут — обязательный per-gate (дефолты у плагина, override в конфиге); глобального нет. Невалидный конфиг останавливает команду до запуска гейтов. Коды выхода: `0` всё прошло · `1` гейт упал · `4` неверный вызов/конфиг · `5` стек не распознан.
288
+
289
+ Подробнее: [`specs/stack/stack.spec.md`](specs/stack/stack.spec.md), [`plugins/golang/directives/infra/golang-setup.xml`](plugins/golang/directives/infra/golang-setup.xml), навык `sdd-infra-golang`.
290
+
291
+ ---
292
+
236
293
  ### 🗯️ `alt-opinion`
237
294
 
238
295
  Мульти-модельные мнения с опциональным синтезом.
@@ -11,8 +11,12 @@ Distinct from:
11
11
  ## Currently available
12
12
 
13
13
  - [`typescript-rules.xml`](typescript-rules.xml) — TypeScript writing conventions.
14
+ - [`result-conventions.xml`](result-conventions.xml) — Result/Error-handling conventions: `isErr`, `must`, `success`/`fail` (v1.2).
14
15
  - [`svelte5-runes.xml`](svelte5-runes.xml) — Svelte 5 runes: $state, $derived, $effect, $props, template syntax. **Inherits typescript-rules.**
15
16
  - [`sveltekit-rules.xml`](sveltekit-rules.xml) — SvelteKit fullstack: routing, load, form actions, hooks, $app modules. **Inherits svelte5-runes + typescript-rules.**
17
+ - [`uikit-component-svelte.xml`](uikit-component-svelte.xml) — Svelte-реализация UIKit-компонентов: data-attributes, css-tokens, file-structure, a11y, token-overrides.
18
+ - [`uikit-component-storybook.xml`](uikit-component-storybook.xml) — Storybook-обвязка UIKit-компонентов: hierarchy, play-function, a11y-audit, spec-mirror.
19
+ - [`uikit-spec-drafting.xml`](uikit-spec-drafting.xml) — Драфтинг UI-спек: extraction-result, token-mapping, variant-grouping, bdd-generation, a11y-defaults.
16
20
 
17
21
  ## Planned
18
22
 
@@ -9,3 +9,5 @@
9
9
  | `git-setup.xml` | Настройка git: .gitignore, ветки, коммиты, хуки, secrets |
10
10
  | `nodejs-npm-setup.xml` | Node.js runtime: .nvmrc, engines, один package manager |
11
11
  | `storybook-setup.xml` | Storybook + MCP server: агентная установка, манифесты, Vitest addon |
12
+
13
+ > Go-тулчейн вынесен в стек-плагин: [`plugins/golang/directives/infra/golang-setup.xml`](../../../plugins/golang/directives/infra/golang-setup.xml) — stack-плагин, немутирующие гейты, скоуп, `.gennadyrc`.
@@ -391,7 +391,7 @@
391
391
  <Step id="WF_2_HANDLE_REMAINING_FINDINGS">Non-zero exit = finding remains after `--fix`. The finding belongs to a motivated non-autofix rule. Read the rule's explanatory comment in `eslint.config.ts`, fix the code accordingly, re-run. Disable comments NOT an option.</Step>
392
392
  <Step id="WF_3_PROPOSE_RULE_CHANGES_VIA_AUDIT">To add or remove a rule, run audit protocol (`PT_RULE_AUDIT_PROTOCOL`): inspect `meta.fixable`, route into autofix or motivated-non-autofix, draft explanatory comment, dry-run, present evidence + diff. Wait for explicit operator confirmation. Severity at registration always `'error'`.</Step>
393
393
  <Step id="WF_4_KEEP_THE_CONFIG_AUDITABLE">Editing `eslint.config.ts`: preserve one-block-per-concern shape. Every `'error'` rule trivially autofixable or carries explanatory comment; every `'off'` after preset spread carries one-line reason; no `'warn'` anywhere.</Step>
394
- <Step id="WF_5_VERIFY_AND_FINALIZE">Before closing a task: `npm run lint:fix && npm run typecheck && npm test` all green AND `git diff` shows only the intended change. Any environment blocker → declared EXPLICITLY in the ticket.</Step>
394
+ <Step id="WF_5_VERIFY_AND_FINALIZE">Before closing a task: the read-only pipeline `npm run lint && npm run typecheck && npm test` all green AND `git diff` shows only the intended change. Verification observes, never mutates: if lint reports autofixable findings, run the explicit fixer step (`npm run lint:fix`, or `gennady fix` where wired) first, review its diff, then re-run the read-only pipeline. Any environment blocker → declared EXPLICITLY in the ticket.</Step>
395
395
  </WorkflowOutline>
396
396
 
397
397
  <VerificationHooks>
@@ -23,7 +23,7 @@
23
23
  <Preconditions>specs/[scope]/[scope].spec.md with scope-type=product or library</Preconditions>
24
24
  </SddModuleDecomposition>
25
25
  <SddTaskScaffolding>
26
- <File>ai/directives/sdd/task-scaffolding.directive.xml</File>
26
+ <File>ai/directives/sdd/scaffold.directive.xml</File>
27
27
  <Purpose>Builds DAG of compact task tickets from scope graph. Each ticket includes BDD, Effective Rules, Verification, Execution Log template.</Purpose>
28
28
  <Triggers>all scope specs ready · break into tasks · build DAG · produce execution plan · scaffold tickets</Triggers>
29
29
  <SkipWhen>module specs lack contracts · discovery or module-decomp not closed · tasks already generated</SkipWhen>
@@ -1,29 +1,51 @@
1
1
  # SDD — Spec-Driven Development
2
2
 
3
- Фреймворк для разработки через спецификации. Каждая директива запускается в **изолированной сессии** и производит самостоятельный артефакт.
3
+ > 🧭 **Начать стоит с [единого гайда по SDD Flow](../../../docs/sdd-flow.md)** — там сценарии по шагам,
4
+ > от новичка до продвинутого, с диаграммами. Здесь — справочник директив и потока.
5
+
6
+ Фреймворк для разработки через спецификации. Каждая директива запускается в **изолированной сессии** и производит самостоятельный артефакт. Директивы читаются агентами напрямую (см. скиллы `ai/skills/sdd-*`).
4
7
 
5
8
  ## Поток
6
9
 
10
+ ```mermaid
11
+ flowchart LR
12
+ A[setup] --> B[discovery]
13
+ B --> C{product / library?}
14
+ C -->|да| D[module-decomposition]
15
+ C -->|нет| E
16
+ D --> E[scaffold]
17
+ E --> F["sdd-execute / sdd-execute-batch"]
18
+ F --> G[audit]
19
+ G -->|FAIL| F
20
+ ```
21
+
7
22
  ```
8
- setup ──► discovery ──► module-decomposition? ──► task-scaffolding ──► sdd-execute (orchestrator) ──► audit
9
- (per scope) (library/product only) (convergence) │
10
- ├─► phase-subagent (P1, P2, ...)
11
- │ under phase-execution-protocol
12
- │
13
- └─► audit-subagent
14
- (auto-dispatched after Round close)
23
+ setup ──► discovery ──► module-decomposition? ──► scaffold ──► sdd-execute (orchestrator) ──► audit
24
+ (per scope) (library/product only) │
25
+ ├─► phase-subagent (P1, P2, ...)
26
+ │ under phase-execution-protocol
27
+ └─► audit-subagent
15
28
  ```
16
29
 
30
+ Параллельно основному потоку: `sdd-critic` (критика спек/тасков до исполнения), `sdd-check`
31
+ (read-only верификация дерева), `sdd-continue`/`sdd-fix` (итерация).
32
+
17
33
  ## Директивы
18
34
 
19
- | Директива | Что делает | Входные данные | Выходные данные |
20
- | ------------------------------------ | --------------------------------------------------------------------------- | --------------------------- | ----------------------------------------- |
21
- | `setup.directive.xml` | Создаёт/обновляет портал проекта — Vision и Scope Graph | Намерение оператора | `specs/README.md` |
22
- | `discovery.directive.xml` | Проектирует scope: vision, архитектура, инструменты, Bootstrap Requirements | Название scope + scope-type | `specs/<scope>/<scope>.spec.md` |
23
- | `module-decomposition.directive.xml` | Декомпозирует scope на модули (только library/product) | scope-spec | `specs/<scope>/<module>/<module>.spec.md` |
24
- | `task-scaffolding.directive.xml` | Строит DAG task-тикетов с Phases Overview, BDD, правилами per phase | Все scope-specs | `tasks/<scope>/*.task-NN.md` |
25
- | `phase-execution-protocol.xml` | Выполняет ОДНУ фазу одного тикета (диспетчится `sdd-execute` оркестратором) | Phase ID + ticket + Handoff | Изменения в Target Files фазы + лог-блок |
26
- | `audit.directive.xml` | Проверяет выравнивание: spec ↔ тикет ↔ код; маппит finding-ы на фазы | Закрытый Round + код | Эфемерный отчёт + `phases_to_fix` |
35
+ | Директива | Что делает | Входные данные | Выходные данные |
36
+ | ------------------------------------ | ----------------------------------------------------------------------------------- | --------------------------- | ----------------------------------------------- |
37
+ | `setup.directive.xml` | Создаёт/обновляет портал проекта — Vision и Scope Graph (sole owner) | Намерение оператора | `specs/README.md` |
38
+ | `discovery.directive.xml` | Проектирует scope: vision, архитектура, инструменты; режимы greenfield/refine/pivot | Название scope + scope-type | `specs/<scope>/<scope>.spec.md` |
39
+ | `module-decomposition.directive.xml` | Декомпозирует scope на модули (только library/product) | scope-spec | `specs/<scope>/<module>/<module>.spec.md` |
40
+ | `scaffold.directive.xml` | Строит DAG task-тикетов с Phases Overview, BDD, правилами per phase | Все scope-specs | `tasks/README.md`, `tasks/<scope>/*.task-NN.md` |
41
+ | `phase-execution-protocol.xml` | Выполняет ОДНУ фазу одного тикета (диспетчится `sdd-execute` оркестратором) | Phase ID + ticket + Handoff | Изменения в Target Files фазы + лог-блок |
42
+ | `audit.directive.xml` | Проверяет выравнивание: spec ↔ тикет ↔ код; маппит finding-ы на фазы | Закрытый Round + код | Вердикт + `phases_to_fix` |
43
+ | `critic.directive.xml` | Оркестратор многораундовой критики спек/тасков (min 3 / max 5 раундов) | Артефакт (спека/таск) | Доработанный артефакт / вердикт CLEAN |
44
+ | `critic-protocol.xml` | Изолированный критик-сабагент: read-only, только артефакт + родительская спека | Артефакт | Находки (отчёт) |
45
+ | `fix.directive.xml` | Findings → классификация → план → фиксы → reopen → execute → verify | Находки (ревью/аудит/check) | Исправления + переоткрытые тикеты |
46
+ | `interview-protocol.xml` | Движок интервью оператора: coverage map, один вопрос за сообщение | scope-type + focus | Закрытая карта покрытия + ответы |
47
+ | `visual-vocabulary.xml` | Cheat-sheet диаграмм: ASCII в чате / mermaid в спеках | Контекст авторинга | Выбор диаграммы |
48
+ | `svelte-ui-discovery.directive.xml` | Компонент-спека `.ui.spec.md` из Figma SVG (component-level, дополняет flow) | Имя компонента + SVG | `specs/<scope>/components/<name>.ui.spec.md` |
27
49
 
28
50
  Оркестрация — через SKILL-ы (`sdd-execute`, `sdd-execute-batch`). Они читают только заголовок тикета + Phases Overview и диспетчат phase-subagent-ов; никогда не выполняют сами.
29
51
 
@@ -1,8 +1,11 @@
1
1
  # ai/skills — AI-навыки для агентов
2
2
 
3
- 15 навыков (13 SDD + alt-opinion + workspace-permission-setup) для Specification-Driven Development, мульти-модельного анализа и настройки автономной среды.
3
+ > 🧭 **Единый гайд по SDD-воркфлоу (сценарии по шагам, диаграммы): [docs/sdd-flow.md](../../docs/sdd-flow.md).**
4
+ > Здесь — справочник навыков: типовые сценарии вызова и паттерны исполнения.
4
5
 
5
- > `sdd-hooks-install` (хуки live-прогресса для `sdd-execute`) и `workspace-permission-setup` мигрированы в хранилище из `~/.claude/skills` — теперь под git и деплоятся через `sync-skills`.
6
+ Навыки для Specification-Driven Development, мульти-модельного анализа и настройки автономной среды: SDD-семейство (`sdd-*`) плюс agent-inbox, alt-opinion, prd-interview и workspace-permission-setup. Стековые специализации (например, `sdd-infra-golang`) живут в `plugins/<stack>/skills/` и синхронизируются тем же `sync-skills`.
7
+
8
+ > `workspace-permission-setup` мигрирован в хранилище из `~/.claude/skills` — теперь под git и деплоится через `sync-skills`.
6
9
 
7
10
  ---
8
11
 
@@ -11,7 +14,8 @@
11
14
  ### 1. Спроектировать новый модуль с нуля
12
15
 
13
16
  ```bash
14
- npx gennady sync-skills
17
+ npx gennady sync # директивы (обязательно первым)
18
+ npx gennady sync-skills # навыки
15
19
  ```
16
20
 
17
21
  Затем в агенте: «@sdd-setup создай проект» → «@sdd-discover спроектируй scope vcs-client» → «@sdd-module-decomposition разбей на модули» → «@sdd-scaffold сгенерируй таски» → «@sdd-critic проверь таски» → «@sdd-execute TSK-01»
@@ -127,8 +131,15 @@ ai/skills/<name>/
127
131
 
128
132
  ## Синхронизация в проекты
129
133
 
134
+ > ⚠️ **Порядок важен:** сначала директивы, потом навыки. Скиллы — тонкие клиенты над директивами из
135
+ > `ai/directives/`, поэтому `npx gennady sync-skills` без предварительного `npx gennady sync` развернёт
136
+ > навыки, которым нечего загружать.
137
+
130
138
  ```bash
131
- # Синхронизировать все навыки
139
+ # 1. Директивы: ai/directives/ (из npm-пакета в проект)
140
+ npx gennady sync
141
+
142
+ # 2. Навыки: ai/skills/ → .claude/skills/ проекта
132
143
  npx gennady sync-skills
133
144
 
134
145
  # Предпросмотр
@@ -35,7 +35,7 @@ Or broader:
35
35
  | `sdd` | Command dispatcher (single entry point) |
36
36
  | `extract-section.sh` | Extract `<!--SECTION:NAME-->...<!--/SECTION:NAME-->` block from markdown |
37
37
  | `lint-artifacts.sh` | Run gennady DBC AST contract lint; parse output reliably |
38
- | `verify.sh` | Three-gate verification: typecheck + gennady DBC lint + forbidden-construct grep |
38
+ | `verify.sh` | Verification gate. Delegates to `gennady verify` (stack plugins: anystack + golang + node, `.gennadyrc` overrides); legacy npm-script heuristic remains as fallback |
39
39
  | `check-blockers.sh` | Detect unresolved BLOCKER entries in ticket Execution Log per `AX_BLOCKER_RESOLUTION_TRAIL` |
40
40
  | `scan.sh` | Emit comprehensive project snapshot ([HEADER]/[TASKS]/[TRACKERS]/[SPECS]/[WARNINGS]/[SUMMARY]). Designed so triage skills make ONE call instead of many ad-hoc find/grep. Surfaces suspicious states automatically (DONE+placeholders, DONE+active-blocker, anchor mismatch, unparseable Status, broken spec links). |
41
41
  | `check.sh` | Deterministic mechanical checks — [TASKID] (collisions, orphan `@tasks`), [TRACKER_SYNC] (ticket Meta.Status vs tracker row), [HEADERS] (`--files` mode). Single source of mechanical truth shared by `sdd-check` (whole tree) and `sdd-audit` (scoped via `--task`/`--files`). Exit 0 clean / 3 findings / 2 structural / 4 bad-invocation. |
@@ -82,6 +82,6 @@ These scripts know nothing about any specific project. They expect:
82
82
  - A markdown file with anchored sections (for `extract`).
83
83
  - A TypeScript file to lint (for `lint`).
84
84
  - A ticket file with `## 7. Execution Log` section (for `check-blockers`).
85
- - A working directory with `npm` and `tsc` available (for `verify`).
85
+ - For `verify`: a runnable `gennady` (on PATH, or a checkout at `$GENNADY_HOME`); fallback needs `npm` + `node`.
86
86
 
87
87
  If the project doesn't satisfy these expectations, scripts emit actionable diagnostics; they never silently fail.
@@ -0,0 +1,119 @@
1
+ // @file: Tests for verify.sh delegation probe and the legacy classifier's mutation screen.
2
+ // @consumers: CI
3
+ // @tasks: TSK-96
4
+
5
+ import { describe, it } from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+ import fs from 'node:fs';
8
+ import os from 'node:os';
9
+ import path from 'node:path';
10
+ import { execFileSync, spawnSync } from 'node:child_process';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ const SCRIPTS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
14
+ const VERIFY_SH = path.join(SCRIPTS_DIR, 'verify.sh');
15
+ const CLASSIFIER = path.join(SCRIPTS_DIR, 'classify-scripts.js');
16
+
17
+ /** @purpose Create a temp fixture with files, run fn, clean up. */
18
+ function withFixture<T>(files: Record<string, string>, fn: (dir: string) => T): T {
19
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'verify-sh-'));
20
+ try {
21
+ for (const [rel, content] of Object.entries(files)) {
22
+ const target = path.join(dir, rel);
23
+ fs.mkdirSync(path.dirname(target), { recursive: true });
24
+ fs.writeFileSync(target, content);
25
+ }
26
+ return fn(dir);
27
+ } finally {
28
+ fs.rmSync(dir, { recursive: true, force: true });
29
+ }
30
+ }
31
+
32
+ /** @purpose Run verify.sh in dir with a fake `gennady` binary shadowing PATH. */
33
+ function runVerify(dir: string, fakeGennady: string): { status: number | null; out: string } {
34
+ const bin = path.join(dir, '_bin');
35
+ fs.mkdirSync(bin, { recursive: true });
36
+ const fake = path.join(bin, 'gennady');
37
+ fs.writeFileSync(fake, fakeGennady);
38
+ fs.chmodSync(fake, 0o755);
39
+ // GENNADY_HOME points at an empty dir so the dev-checkout path cannot rescue the probe.
40
+ const proc = spawnSync('bash', [VERIFY_SH, 'target.txt'], {
41
+ cwd: dir,
42
+ encoding: 'utf-8',
43
+ env: { ...process.env, PATH: `${bin}:${process.env.PATH}`, GENNADY_HOME: bin },
44
+ });
45
+ return { status: proc.status, out: `${proc.stdout}${proc.stderr}` };
46
+ }
47
+
48
+ describe('verify.sh capability probe', () => {
49
+ it('delegates to a gennady whose `verify --plan --json` emits JSON', () => {
50
+ withFixture({ 'target.txt': 'x' }, (dir) => {
51
+ const { status, out } = runVerify(
52
+ dir,
53
+ '#!/usr/bin/env bash\n' +
54
+ 'if [[ "$1" == "verify" ]]; then\n' +
55
+ ' case "$*" in *"--plan"*) echo "{}"; exit 0;; esac\n' +
56
+ ' echo "DELEGATED: $*"; exit 0\n' +
57
+ 'fi\n' +
58
+ 'echo "Usage: gennady <command>"; exit 0\n'
59
+ );
60
+
61
+ assert.equal(status, 0, out);
62
+ assert.match(out, /DELEGATED: verify target\.txt/);
63
+ });
64
+ });
65
+
66
+ it('does not delegate to an older gennady that answers everything with its help and exit 0', () => {
67
+ withFixture(
68
+ {
69
+ 'target.txt': 'x',
70
+ // The only npm script is mutating: the legacy fallback must screen it out,
71
+ // never run it as a gate (the pre-fix behavior rewrote the tree and passed).
72
+ 'package.json': '{"name":"x","scripts":{"lint":"eslint . --fix"}}',
73
+ },
74
+ (dir) => {
75
+ const { out } = runVerify(
76
+ dir,
77
+ '#!/usr/bin/env bash\necho "Usage: gennady <command>"\nexit 0\n'
78
+ );
79
+
80
+ assert.ok(!out.includes('DELEGATED'), `must not delegate: ${out}`);
81
+ assert.ok(!out.includes('ALL_GATES_PASS'), `mutating script must not pass as a gate: ${out}`);
82
+ assert.match(out, /NO_SCRIPTS_DISCOVERED/);
83
+ }
84
+ );
85
+ });
86
+ });
87
+
88
+ describe('classify-scripts.js mutation screen', () => {
89
+ it('classifies --fix/--autofix/--write bodies as mutating and never selects them', () => {
90
+ withFixture(
91
+ {
92
+ 'package.json': JSON.stringify({
93
+ name: 'x',
94
+ scripts: {
95
+ lint: 'eslint . --fix',
96
+ format: 'prettier --write .',
97
+ 'lint:contracts': 'gennady lint --autofix src/',
98
+ test: 'vitest run',
99
+ },
100
+ }),
101
+ },
102
+ (dir) => {
103
+ const parsed = JSON.parse(execFileSync('node', [CLASSIFIER, dir], { encoding: 'utf-8' })) as {
104
+ scripts: Array<{ name: string; classes: string[] }>;
105
+ selected: Record<string, string>;
106
+ };
107
+
108
+ for (const name of ['lint', 'format', 'lint:contracts']) {
109
+ const entry = parsed.scripts.find((script) => script.name === name);
110
+ assert.deepEqual(entry?.classes, ['mutating'], name);
111
+ }
112
+ assert.equal(parsed.selected.lint, undefined);
113
+ assert.equal(parsed.selected.format, undefined);
114
+ assert.equal(parsed.selected.gennady, undefined);
115
+ assert.equal(parsed.selected.test, 'test');
116
+ }
117
+ );
118
+ });
119
+ });
@@ -18,7 +18,13 @@ function hasCategory(body, category) {
18
18
  return patterns[category] ? patterns[category].test(body) : false;
19
19
  }
20
20
 
21
+ // Same screen the node stack plugin applies (plugins/node/node-plugin.ts): a script
22
+ // that rewrites the tree is a fixer, never a verification gate (D-STACK-005).
23
+ const MUTATING_FLAG_RE = /(^|\s)--(fix|autofix|write)(?:[=\s]|$)/;
24
+
21
25
  function classify(name, body) {
26
+ if (MUTATING_FLAG_RE.test(body)) return ['mutating'];
27
+
22
28
  const isUmbrellaName = /^(check|ci-check|check:all|verify)$/.test(name);
23
29
  if (isUmbrellaName && body.length > 0) return ['umbrella'];
24
30
 
@@ -13,7 +13,15 @@
13
13
  import { readFileSync } from 'node:fs';
14
14
  import { resolve } from 'node:path';
15
15
 
16
- type ScriptClass = 'typecheck' | 'gennady' | 'lint' | 'test' | 'format' | 'umbrella' | 'unknown';
16
+ type ScriptClass =
17
+ | 'typecheck'
18
+ | 'gennady'
19
+ | 'lint'
20
+ | 'test'
21
+ | 'format'
22
+ | 'umbrella'
23
+ | 'mutating'
24
+ | 'unknown';
17
25
 
18
26
  interface ScriptEntry {
19
27
  name: string;
@@ -36,7 +44,13 @@ function hasCategory(body: string, category: string): boolean {
36
44
  return patterns[category]?.test(body) ?? false;
37
45
  }
38
46
 
47
+ // Same screen the node stack plugin applies (plugins/node/node-plugin.ts): a script
48
+ // that rewrites the tree is a fixer, never a verification gate (D-STACK-005).
49
+ const MUTATING_FLAG_RE = /(^|\s)--(fix|autofix|write)(?:[=\s]|$)/;
50
+
39
51
  function classify(name: string, body: string): ScriptClass[] {
52
+ if (MUTATING_FLAG_RE.test(body)) return ['mutating'];
53
+
40
54
  const isUmbrellaName = /^(check|ci-check|check:all|verify)$/.test(name);
41
55
  if (isUmbrellaName && body.length > 0) return ['umbrella'];
42
56
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # @file: Smart verification gate — auto-discovers npm scripts via heuristic, runs them.
2
+ # @file: Smart verification gate — delegates to `gennady verify` (stack plugins), legacy npm fallback.
3
3
  # @consumers: phase agents (STEP_5_VERIFY); orchestrators; CI hooks
4
4
  # @contract: AX_BASH_NO_SILENT_EMPTY. All discovered gates MUST pass for exit 0.
5
5
  # RUN-ALL: every gate executes regardless of previous failures.
@@ -7,6 +7,10 @@
7
7
  # On all-pass: single line "[verify] ALL_GATES_PASS (N/N)". Exit 0.
8
8
  # On any-fail: each failed gate dumps its command + exit code + captured output. Exit 1.
9
9
  #
10
+ # Preferred path is `gennady verify` — the stack-agnostic plugin system
11
+ # (node + golang, .gennadyrc overrides). The npm classifier below remains
12
+ # as a fallback for environments where gennady itself is not runnable.
13
+ #
10
14
  # Usage:
11
15
  # verify.sh <file1> [<file2> ...]
12
16
  #
@@ -14,7 +18,7 @@
14
18
  # 0 — all gates PASS
15
19
  # 1 — one or more gates failed
16
20
  # 4 — bad invocation
17
- # 5 — environment failure
21
+ # 5 — environment failure / no stack detected
18
22
 
19
23
  set -uo pipefail
20
24
 
@@ -34,6 +38,61 @@ EOF
34
38
  exit 4
35
39
  fi
36
40
 
41
+ for file in "$@"; do
42
+ if [[ ! -f "$file" ]]; then
43
+ echo "[$PROG] FILE_NOT_FOUND: $file"
44
+ exit 4
45
+ fi
46
+ done
47
+
48
+ # -----------------------------------------------------------
49
+ # Step 0: Delegate to `gennady verify` (stack plugin system)
50
+ #
51
+ # Handles node AND golang repos through one interface, honours
52
+ # .gennadyrc stack overrides. File targets are forwarded — the
53
+ # golang plugin narrows to their packages; the node plugin runs
54
+ # its repo-level scripts either way.
55
+ # -----------------------------------------------------------
56
+
57
+ # Repo root of the gennady checkout: scripts → sdd-execute → skills → ai → root.
58
+ GENNADY_HOME="${GENNADY_HOME:-$SCRIPT_DIR/../../../..}"
59
+
60
+ # Capability probe: an older installed gennady without `verify` prints its generic
61
+ # help and exits 0, silently swallowing the delegation. Probe the machine surface,
62
+ # not the human help table: `verify --plan --json` emits JSON (command exists, planned,
63
+ # exit 0), or exits 4/5 (command exists and ran: bad config / no stack). A gennady that
64
+ # is BROKEN (clipped deps, too-old Node, wrong arch) exits 1/126/127 with no JSON —
65
+ # delegating to it would `exec` the same broken binary and hide the working checkout and
66
+ # npm fallback below. So delegate ONLY on a positive capability signal, never on a bare
67
+ # non-zero. A `timeout` guards a hung binary from blocking verify forever.
68
+ run_probe() {
69
+ if command -v timeout &>/dev/null; then
70
+ timeout 10 gennady verify --plan --json 2>/dev/null
71
+ elif command -v gtimeout &>/dev/null; then
72
+ gtimeout 10 gennady verify --plan --json 2>/dev/null
73
+ else
74
+ gennady verify --plan --json 2>/dev/null
75
+ fi
76
+ }
77
+ if command -v gennady &>/dev/null; then
78
+ probe_out="$(run_probe)"
79
+ probe_exit=$?
80
+ if [[ "${probe_out:0:1}" == "{" || $probe_exit -eq 4 || $probe_exit -eq 5 ]]; then
81
+ exec gennady verify "$@"
82
+ fi
83
+ fi
84
+
85
+ # Checkout path: use the checkout's own tsx — npx would hit the registry, which
86
+ # sandboxed/corp environments block.
87
+ GENNADY_TSX="$GENNADY_HOME/node_modules/.bin/tsx"
88
+ if [[ -x "$GENNADY_TSX" && -f "$GENNADY_HOME/cli/gennady.ts" ]]; then
89
+ exec "$GENNADY_TSX" "$GENNADY_HOME/cli/gennady.ts" verify "$@"
90
+ fi
91
+
92
+ # -----------------------------------------------------------
93
+ # Legacy fallback: npm-script heuristic (gennady not runnable)
94
+ # -----------------------------------------------------------
95
+
37
96
  if ! command -v npm &>/dev/null; then
38
97
  echo "[$PROG] ENV_MISSING: npm not in PATH"
39
98
  exit 5
@@ -44,13 +103,6 @@ if ! command -v node &>/dev/null; then
44
103
  exit 5
45
104
  fi
46
105
 
47
- for file in "$@"; do
48
- if [[ ! -f "$file" ]]; then
49
- echo "[$PROG] FILE_NOT_FOUND: $file"
50
- exit 4
51
- fi
52
- done
53
-
54
106
  # -----------------------------------------------------------
55
107
  # Step 1: Discover scripts via heuristic (silent)
56
108
  # -----------------------------------------------------------
@@ -79,8 +131,11 @@ for cls in ['typecheck','gennady','lint','test','format']:
79
131
  " 2>/dev/null)
80
132
 
81
133
  if [[ -z "$discovered" ]]; then
82
- echo "[$PROG] NO_SCRIPTS_DISCOVERED"
83
- exit 0
134
+ # Zero discovered gates verifies nothing — it must not read as success, exactly as the
135
+ # delegated `gennady verify` reports ZERO_GATES with exit 1 (this file's own contract:
136
+ # "All discovered gates MUST pass for exit 0"; an empty set satisfies that vacuously).
137
+ echo "[$PROG] NO_SCRIPTS_DISCOVERED: nothing to verify — declare gates in gennady.yaml or add npm scripts"
138
+ exit 1
84
139
  fi
85
140
 
86
141
  # -----------------------------------------------------------
@@ -6,8 +6,10 @@ compatibility: opencode
6
6
 
7
7
  1. **Extract intent.** Operator wants to bootstrap or evolve infrastructure scope. Scope-type is fixed: `infrastructure`. Resolve scope name from intake.
8
8
 
9
- 2. **Load & activate directive.** Read in full: `~/Developer/gennady/ai/directives/sdd/discovery.directive.xml`
9
+ 2. **Route by language.** If the scope is a Go service or library — `go.mod` present, or the operator named Go — hand off to `sdd-infra-golang` instead of continuing here. It carries the stack plugin gate model (`gennady verify`), `.gennadyrc` overrides and `plugins/golang/directives/infra/golang-setup.xml`. Do not improvise Go tooling from this generic path.
10
+
11
+ 3. **Load & activate directive.** Read in full: `~/Developer/gennady/ai/directives/sdd/discovery.directive.xml`
10
12
  Announce: `🔒 DIRECTIVE ACTIVATED: SddDiscovery | infrastructure`
11
13
  You ARE this directive now.
12
14
 
13
- 3. **Apply directive to intent.** Force scope-type=`infrastructure`. Mode auto-detected per `AX_MODE_AUTO_DETECT_OR_HALT`. Follow Execution_Plan end-to-end.
15
+ 4. **Apply directive to intent.** Force scope-type=`infrastructure`. Mode auto-detected per `AX_MODE_AUTO_DETECT_OR_HALT`. Follow Execution_Plan end-to-end.