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.
- package/README.md +57 -0
- package/ai/directives/coding/README.md +4 -0
- package/ai/directives/infra/README.md +2 -0
- package/ai/directives/infra/eslint-setup.xml +1 -1
- package/ai/directives/knowledge.xml +1 -1
- package/ai/directives/sdd/README.md +38 -16
- package/ai/skills/README.md +15 -4
- package/ai/skills/sdd-execute/scripts/README.md +2 -2
- package/ai/skills/sdd-execute/scripts/__tests__/verify-delegation.test.ts +119 -0
- package/ai/skills/sdd-execute/scripts/classify-scripts.js +6 -0
- package/ai/skills/sdd-execute/scripts/classify-scripts.ts +15 -1
- package/ai/skills/sdd-execute/scripts/verify.sh +66 -11
- package/ai/skills/sdd-infra/SKILL.md +4 -2
- package/cli/cmd/README.md +53 -29
- package/dist/ai/directives/coding/README.md +4 -0
- package/dist/ai/directives/infra/README.md +2 -0
- package/dist/ai/directives/infra/eslint-setup.xml +1 -1
- package/dist/ai/directives/knowledge.xml +1 -1
- package/dist/ai/directives/sdd/README.md +38 -16
- package/dist/ai/skills/README.md +15 -4
- package/dist/ai/skills/sdd-execute/scripts/README.md +2 -2
- package/dist/ai/skills/sdd-execute/scripts/__tests__/verify-delegation.test.ts +119 -0
- package/dist/ai/skills/sdd-execute/scripts/classify-scripts.js +6 -0
- package/dist/ai/skills/sdd-execute/scripts/classify-scripts.ts +15 -1
- package/dist/ai/skills/sdd-execute/scripts/verify.sh +66 -11
- package/dist/ai/skills/sdd-infra/SKILL.md +4 -2
- package/dist/chunks/{classify-mr-stage.logic-r9UoBm08.js → classify-mr-stage.logic-C9nlmo7G.js} +2 -2
- package/dist/chunks/help-B02LDQzW.js +18 -0
- package/dist/chunks/{help-BlgP1zki.js → help-CjeiaUQ_.js} +1 -1
- package/dist/chunks/help-DX_3WUts.js +12 -0
- package/dist/chunks/{help.cmd-BJ6-lc4I.js → help.cmd-Bz1YqU2V.js} +4 -0
- package/dist/chunks/{index-CSz4HqEu.js → index-9Bkdk7RL.js} +2 -2
- package/dist/chunks/{index-CL_aLkgt.js → index-BA76NeUs.js} +2 -2
- package/dist/chunks/{index-zy8MA-fd.js → index-BDl2IAXu.js} +3 -3
- package/dist/chunks/{index-Dlb8K8GQ.js → index-BGgXGXg-.js} +1 -1
- package/dist/chunks/{index-CDM6lQ5g.js → index-BJ1a8lhw.js} +13 -13
- package/dist/chunks/{index-SDjD_RBF.js → index-BK1NwQr1.js} +2 -2
- package/dist/chunks/{index-wvamJD3a.js → index-BLfQaUv5.js} +2 -2
- package/dist/chunks/index-BMLtkwzj.js +98 -0
- package/dist/chunks/{index-CSZFsxeM.js → index-BMWZFp4U.js} +2 -2
- package/dist/chunks/index-BNVroM3w.js +188 -0
- package/dist/chunks/{index-C5B_vY8J.js → index-BUe8xaDt.js} +3 -3
- package/dist/chunks/{index-BEtOYJC5.js → index-Bd51QuVH.js} +2 -2
- package/dist/chunks/{index-Isv3MMxW.js → index-C-y9uwFd.js} +1 -1
- package/dist/chunks/{index-CKHpOQ1l.js → index-C4EN2eIa.js} +2 -2
- package/dist/chunks/{index-N5P1Aadf.js → index-CJvv33n7.js} +2 -2
- package/dist/chunks/index-CM0Gf1_N.js +410 -0
- package/dist/chunks/index-CXRsLQR8.js +205 -0
- package/dist/chunks/{index-DcqdJ116.js → index-C_Cz5D_b.js} +2 -2
- package/dist/chunks/{index-D9zXaNK2.js → index-CgZ9VMDN.js} +2 -2
- package/dist/chunks/{index-DcENgDCF.js → index-ChNXCDzn.js} +2 -2
- package/dist/chunks/{index-DZTNIonC.js → index-CkQ3o27J.js} +2 -2
- package/dist/chunks/{index-qFD4Gwhm.js → index-CrpSPpC-.js} +2 -2
- package/dist/chunks/{index-DfS5AAVu.js → index-CvJ5NhsB.js} +1 -1
- package/dist/chunks/{index-CiRNZljf.js → index-DGDuSviU.js} +2 -2
- package/dist/chunks/{index-CatK_HzA.js → index-DJ2acfLK.js} +2 -2
- package/dist/chunks/{index-e6-st8zp.js → index-DPdRu-zq.js} +2 -2
- package/dist/chunks/{index-Bw9-54Mu.js → index-DW3WSoOG.js} +2 -2
- package/dist/chunks/{index-AHtpvdDo.js → index-Ddot2Nhe.js} +205 -224
- package/dist/chunks/{index-DHvmyJgt.js → index-DpAdFAL8.js} +2 -2
- package/dist/chunks/{index-fxRBsDvT.js → index-RxmZo2qu.js} +2 -2
- package/dist/chunks/{index-QHOWgn8q.js → index-Y-juM436.js} +2 -2
- package/dist/chunks/{index-BBm9zeai.js → index-e9JD7pCh.js} +1 -1
- package/dist/chunks/{index-D3oX4PrK.js → index-l9U1wyLq.js} +1 -1
- package/dist/chunks/{run-review-command.logic-CXcCegK2.js → run-review-command.logic-C08f3D9C.js} +14 -14
- package/dist/chunks/services-q8rLnybu.js +10151 -0
- package/dist/chunks/shared-DbIfVgIg.js +966 -0
- package/dist/cli/cmd/fix/fix.cmd.d.ts +7 -0
- package/dist/cli/cmd/fix/help.d.ts +4 -0
- package/dist/cli/cmd/fix/index.d.ts +1 -0
- package/dist/cli/cmd/sync/sync-core.d.ts +10 -0
- package/dist/cli/cmd/sync/sync.types.d.ts +2 -0
- package/dist/cli/cmd/sync-skills/sync-skills-core.d.ts +12 -0
- package/dist/cli/cmd/sync-skills/sync-skills.types.d.ts +2 -0
- package/dist/cli/cmd/verify/help.d.ts +4 -0
- package/dist/cli/cmd/verify/index.d.ts +1 -0
- package/dist/cli/cmd/verify/verify.cmd.d.ts +7 -0
- package/dist/gennady.js +47 -35
- package/dist/index.js +4 -4
- package/dist/plugins/anystack/anystack-plugin.d.ts +12 -0
- package/dist/plugins/golang/golang-detect.logic.d.ts +57 -0
- package/dist/plugins/golang/golang-plan.logic.d.ts +35 -0
- package/dist/plugins/golang/golang-plugin.d.ts +9 -0
- package/dist/plugins/golang/golang-scope.logic.d.ts +39 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/node/classify-npm-scripts.d.ts +21 -0
- package/dist/plugins/node/node-plugin.d.ts +12 -0
- package/dist/services/config/config-loader.d.ts +68 -0
- package/dist/services/plugins/plugin-assets.d.ts +26 -0
- package/dist/services/plugins/resolve-plugins.d.ts +46 -0
- package/dist/services/stack/env-fail.d.ts +55 -0
- package/dist/services/stack/gate-runner.d.ts +32 -0
- package/dist/services/stack/plugin-api.d.ts +4 -0
- package/dist/services/stack/stack-config.d.ts +66 -0
- package/dist/services/stack/stack-registry.d.ts +31 -0
- package/dist/services/stack/stack.types.d.ts +313 -0
- package/dist/services/stack/tree-guard.d.ts +45 -0
- package/dist/shared/backend/rc/rc-config.d.ts +3 -1
- package/dist/shared/common/exec.d.ts +6 -0
- package/docs/sdd-flow.md +471 -0
- package/package.json +15 -6
- package/plugins/anystack/anystack-plugin.ts +52 -0
- package/plugins/anystack/plugin.json +5 -0
- package/plugins/golang/directives/infra/golang-setup.xml +159 -0
- package/plugins/golang/golang-detect.logic.ts +358 -0
- package/plugins/golang/golang-plan.logic.ts +379 -0
- package/plugins/golang/golang-plugin.ts +81 -0
- package/plugins/golang/golang-scope.logic.ts +503 -0
- package/plugins/golang/plugin.json +5 -0
- package/plugins/golang/skills/sdd-infra-golang/SKILL.md +114 -0
- package/plugins/node/classify-npm-scripts.ts +146 -0
- package/plugins/node/node-plugin.ts +136 -0
- package/plugins/node/plugin.json +5 -0
- package/ai/fw/v1/architecture/blueprint-factory.xml +0 -77
- package/ai/fw/v1/core/mental-model.xml +0 -50
- package/ai/fw/v1/discovery/intent-reactor.xml +0 -92
- package/ai/fw/v1/production/swarm-protocol.xml +0 -122
- package/ai/fw/v1/review/quality-pipeline.xml +0 -102
- package/ai/fw/v2/arch-universal.xml +0 -73
- package/ai/fw-draft/README.md +0 -79
- package/ai/fw-draft/bin/discovery.sh +0 -116
- package/ai/fw-draft/gennady.xml +0 -58
- package/ai/fw-draft/provider/claude.xml +0 -16
- package/ai/fw-draft/provider/cursor.xml +0 -23
- package/ai/fw-draft/provider/default.xml +0 -12
- package/ai/fw-draft/roles/developer.xml +0 -18
- package/ai/fw-draft/router.xml +0 -39
- package/ai/fw-draft/routes/development.xml +0 -32
- package/ai/fw-draft/routes/universal.xml +0 -58
- package/ai/fw-draft/rules/dev/base/file-structure-rules.xml +0 -89
- package/ai/fw-draft/rules/dev/typescript/contacts.xml +0 -194
- package/ai/skills/sdd-hooks-install/SKILL.md +0 -89
- package/dist/ai/fw/v1/architecture/blueprint-factory.xml +0 -77
- package/dist/ai/fw/v1/core/mental-model.xml +0 -50
- package/dist/ai/fw/v1/discovery/intent-reactor.xml +0 -92
- package/dist/ai/fw/v1/production/swarm-protocol.xml +0 -122
- package/dist/ai/fw/v1/review/quality-pipeline.xml +0 -102
- package/dist/ai/fw/v2/arch-universal.xml +0 -73
- package/dist/ai/fw-draft/README.md +0 -79
- package/dist/ai/fw-draft/bin/discovery.sh +0 -116
- package/dist/ai/fw-draft/gennady.xml +0 -58
- package/dist/ai/fw-draft/provider/claude.xml +0 -16
- package/dist/ai/fw-draft/provider/cursor.xml +0 -23
- package/dist/ai/fw-draft/provider/default.xml +0 -12
- package/dist/ai/fw-draft/roles/developer.xml +0 -18
- package/dist/ai/fw-draft/router.xml +0 -39
- package/dist/ai/fw-draft/routes/development.xml +0 -32
- package/dist/ai/fw-draft/routes/universal.xml +0 -58
- package/dist/ai/fw-draft/rules/dev/base/file-structure-rules.xml +0 -89
- package/dist/ai/fw-draft/rules/dev/typescript/contacts.xml +0 -194
- package/dist/ai/skills/sdd-hooks-install/SKILL.md +0 -89
- package/dist/chunks/index-B1F4er8N.js +0 -164
- package/dist/chunks/index-BVvD4fSE.js +0 -377
- package/dist/chunks/services-Bv_nk_yC.js +0 -3973
- package/dist/chunks/shared--i1fbMFp.js +0 -891
- /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
|
|
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/
|
|
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? ──►
|
|
9
|
-
(per scope) (library/product only)
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
22
|
-
| `discovery.directive.xml` | Проектирует scope: vision, архитектура,
|
|
23
|
-
| `module-decomposition.directive.xml` | Декомпозирует scope на модули (только library/product)
|
|
24
|
-
| `
|
|
25
|
-
| `phase-execution-protocol.xml` | Выполняет ОДНУ фазу одного тикета (диспетчится `sdd-execute` оркестратором)
|
|
26
|
-
| `audit.directive.xml` | Проверяет выравнивание: spec ↔ тикет ↔ код; маппит finding-ы на фазы
|
|
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
|
|
package/ai/skills/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# ai/skills — AI-навыки для агентов
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 🧭 **Единый гайд по SDD-воркфлоу (сценарии по шагам, диаграммы): [docs/sdd-flow.md](../../docs/sdd-flow.md).**
|
|
4
|
+
> Здесь — справочник навыков: типовые сценарии вызова и паттерны исполнения.
|
|
4
5
|
|
|
5
|
-
|
|
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
|
|
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` |
|
|
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
|
-
-
|
|
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 =
|
|
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 —
|
|
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
|
-
|
|
83
|
-
exit
|
|
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. **
|
|
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
|
-
|
|
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.
|