@nitra/cursor 12.8.6 → 12.8.8

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 (263) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/rules/abie/main.mdc +9 -5
  4. package/rules/abie/policy/base_deployment_preem/base_deployment_preem.mdc +22 -0
  5. package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
  6. package/rules/abie/policy/health_check_policy/health_check_policy.mdc +17 -0
  7. package/rules/abie/policy/http_route_base/http_route_base.mdc +9 -0
  8. package/rules/abie/policy/package_json_shared/package_json_shared.mdc +17 -0
  9. package/rules/adr/js/hooks.mdc +32 -0
  10. package/rules/adr/js/madr_format.mdc +96 -0
  11. package/rules/adr/js/settings_policy.mdc +34 -0
  12. package/rules/adr/main.mdc +17 -95
  13. package/rules/adr/policy/settings_json/settings_json.mdc +7 -0
  14. package/rules/adr/policy/settings_local_json/settings_local_json.mdc +7 -0
  15. package/rules/bun/js/bunfig.mdc +12 -0
  16. package/rules/bun/js/layout.mdc +60 -0
  17. package/rules/bun/js/lint.mdc +9 -0
  18. package/rules/bun/js/package_json.mdc +19 -0
  19. package/rules/bun/main.mdc +7 -60
  20. package/rules/bun/policy/bunfig/bunfig.mdc +12 -0
  21. package/rules/bun/policy/package_json/package_json.mdc +14 -0
  22. package/rules/capacitor/js/ios_spm.mdc +69 -0
  23. package/rules/capacitor/js/version.mdc +29 -0
  24. package/rules/capacitor/main.mdc +6 -22
  25. package/rules/capacitor/policy/package_json/package_json.mdc +9 -0
  26. package/rules/changelog/js/agent-workflow.mdc +15 -0
  27. package/rules/changelog/js/changelog-format.mdc +33 -0
  28. package/rules/changelog/js/comparison-models.mdc +40 -0
  29. package/rules/changelog/main.mdc +4 -98
  30. package/rules/ci4/js/marksman_config.mdc +31 -0
  31. package/rules/ci4/js/vscode_extensions.mdc +33 -0
  32. package/rules/ci4/main.mdc +16 -14
  33. package/rules/ci4/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  34. package/rules/docker/js/compile.mdc +44 -0
  35. package/rules/docker/js/hadolint.mdc +50 -0
  36. package/rules/docker/js/mirror.mdc +13 -0
  37. package/rules/docker/js/multistage.mdc +13 -0
  38. package/rules/docker/js/native-addon.mdc +43 -0
  39. package/rules/docker/js/nginx-tag.mdc +7 -0
  40. package/rules/docker/js/nginx-user.mdc +37 -0
  41. package/rules/docker/js/non-root.mdc +39 -0
  42. package/rules/docker/main.mdc +13 -196
  43. package/rules/docker/policy/lint_docker_yml/lint_docker_yml.mdc +14 -0
  44. package/rules/efes/main.mdc +1 -1
  45. package/rules/efes/policy/package_json_shared/package_json_shared.mdc +30 -0
  46. package/rules/ga/js/lint_toolchain.mdc +15 -0
  47. package/rules/ga/js/required_workflows.mdc +35 -0
  48. package/rules/ga/js/vscode.mdc +17 -0
  49. package/rules/ga/js/workflow_common.mdc +108 -0
  50. package/rules/ga/js/workflows.mdc +32 -0
  51. package/rules/ga/js/zizmor.mdc +7 -0
  52. package/rules/ga/main.mdc +16 -119
  53. package/rules/ga/policy/clean_ga_workflows/clean_ga_workflows.mdc +18 -0
  54. package/rules/ga/policy/clean_merged_branch/clean_merged_branch.mdc +22 -0
  55. package/rules/ga/policy/git_ai/git_ai.mdc +19 -0
  56. package/rules/ga/policy/lint_ga/lint_ga.mdc +21 -0
  57. package/rules/ga/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  58. package/rules/ga/policy/vscode_settings/vscode_settings.mdc +9 -0
  59. package/rules/ga/policy/workflow_common/workflow_common.mdc +18 -0
  60. package/rules/ga/policy/zizmor_yml/zizmor_yml.mdc +9 -0
  61. package/rules/graphql/js/tooling.mdc +13 -0
  62. package/rules/graphql/js/vscode_extensions.mdc +13 -0
  63. package/rules/graphql/main.mdc +4 -21
  64. package/rules/graphql/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  65. package/rules/hasura/js/internal_urls.mdc +27 -0
  66. package/rules/hasura/js/migrations.mdc +13 -0
  67. package/rules/hasura/js/svc_hl.mdc +17 -0
  68. package/rules/hasura/main.mdc +6 -30
  69. package/rules/hasura/policy/svc_hl/svc_hl.mdc +15 -0
  70. package/rules/image-avif/js/avif_generation.mdc +26 -0
  71. package/rules/image-avif/js/package_json_optout.mdc +21 -0
  72. package/rules/image-avif/main.mdc +5 -34
  73. package/rules/image-avif/policy/package_json/package_json.mdc +18 -0
  74. package/rules/image-compress/js/package_json.mdc +7 -0
  75. package/rules/image-compress/js/package_setup.mdc +13 -0
  76. package/rules/image-compress/main.mdc +4 -12
  77. package/rules/image-compress/policy/package_json/package_json.mdc +13 -0
  78. package/rules/js/docs/index.md +3 -3
  79. package/rules/js/js/dep-policy.mdc +17 -0
  80. package/rules/js/js/eslint-config.mdc +28 -0
  81. package/rules/js/js/extensions.mdc +8 -0
  82. package/rules/js/js/file-extensions.mdc +12 -0
  83. package/rules/js/js/for-in.mdc +26 -0
  84. package/rules/js/js/jscpd.mdc +42 -0
  85. package/rules/js/js/knip.mdc +15 -0
  86. package/rules/js/js/lint-js-workflow.mdc +58 -0
  87. package/rules/js/js/oxlintrc.mdc +20 -0
  88. package/rules/js/js/package-json.mdc +31 -0
  89. package/rules/js/js/tests.mdc +9 -0
  90. package/rules/js/js/utils-lib-structure.mdc +15 -0
  91. package/rules/js/main.mdc +19 -211
  92. package/rules/js/policy/jscpd/jscpd.mdc +14 -0
  93. package/rules/js/policy/lint_js_yml/lint_js_yml.mdc +14 -0
  94. package/rules/js/policy/package_json/package_json.mdc +15 -0
  95. package/rules/js/policy/vscode_extensions/vscode_extensions.mdc +11 -0
  96. package/rules/js-bun-db/js/bun-sql-migration.mdc +15 -0
  97. package/rules/js-bun-db/js/connection.mdc +42 -0
  98. package/rules/js-bun-db/js/pg-format-identifiers.mdc +102 -0
  99. package/rules/js-bun-db/js/pg-format-shim.mdc +99 -0
  100. package/rules/js-bun-db/js/pg-leftover.mdc +27 -0
  101. package/rules/js-bun-db/js/pg-listen-notify.mdc +51 -0
  102. package/rules/js-bun-db/js/query-safety.mdc +117 -0
  103. package/rules/js-bun-db/js/sql-array.mdc +88 -0
  104. package/rules/js-bun-db/js/unsafe.mdc +65 -0
  105. package/rules/js-bun-db/main.mdc +12 -607
  106. package/rules/js-bun-db/policy/package_json/package_json.mdc +17 -0
  107. package/rules/js-bun-redis/js/imports.mdc +47 -0
  108. package/rules/js-bun-redis/js/package_json.mdc +44 -0
  109. package/rules/js-bun-redis/main.mdc +4 -10
  110. package/rules/js-bun-redis/policy/package_json/package_json.mdc +11 -0
  111. package/rules/js-mssql/js/mssql-in-list.mdc +38 -0
  112. package/rules/js-mssql/js/mssql-pool.mdc +56 -0
  113. package/rules/js-mssql/js/mssql-query-template.mdc +33 -0
  114. package/rules/js-mssql/js/mssql-tvp.mdc +75 -0
  115. package/rules/js-mssql/js/mssql-version.mdc +7 -0
  116. package/rules/js-mssql/main.mdc +10 -198
  117. package/rules/js-mssql/policy/package_json/package_json.mdc +9 -0
  118. package/rules/js-run/js/check-env.mdc +35 -0
  119. package/rules/js-run/js/conn-aliases.mdc +109 -0
  120. package/rules/js-run/js/jsconfig.mdc +20 -0
  121. package/rules/js-run/js/otel-configmap.mdc +6 -0
  122. package/rules/js-run/js/pino.mdc +6 -0
  123. package/rules/js-run/js/project-structure.mdc +11 -0
  124. package/rules/js-run/js/runtime.mdc +14 -0
  125. package/rules/js-run/js/scope.mdc +11 -0
  126. package/rules/js-run/js/settimeout.mdc +11 -0
  127. package/rules/js-run/js/temporal.mdc +5 -0
  128. package/rules/js-run/main.mdc +16 -216
  129. package/rules/js-run/policy/configmap/configmap.mdc +31 -0
  130. package/rules/js-run/policy/jsconfig/jsconfig.mdc +25 -0
  131. package/rules/js-run/policy/package_json/package_json.mdc +38 -0
  132. package/rules/k8s/js/configmap.mdc +41 -0
  133. package/rules/k8s/js/deployment_resources.mdc +49 -0
  134. package/rules/k8s/js/hasura_httproute.mdc +91 -0
  135. package/rules/k8s/js/hpa_apiversion.mdc +27 -0
  136. package/rules/k8s/js/ingress_gateway.mdc +16 -0
  137. package/rules/k8s/js/kustomize_structure.mdc +144 -0
  138. package/rules/k8s/js/lint_k8s.mdc +72 -0
  139. package/rules/k8s/js/multidoc_yaml.mdc +5 -0
  140. package/rules/k8s/js/network_policy.mdc +136 -0
  141. package/rules/k8s/js/schema_modeline.mdc +57 -0
  142. package/rules/k8s/js/service.mdc +44 -0
  143. package/rules/k8s/js/topology_hpa_pdb.mdc +181 -0
  144. package/rules/k8s/main.mdc +29 -834
  145. package/rules/k8s/policy/base_kustomization/base_kustomization.mdc +12 -0
  146. package/rules/k8s/policy/base_manifest/base_manifest.mdc +14 -0
  147. package/rules/k8s/policy/gateway/gateway.mdc +17 -0
  148. package/rules/k8s/policy/hasura_configmap/hasura_configmap.mdc +20 -0
  149. package/rules/k8s/policy/hasura_httproute/hasura_httproute.mdc +16 -0
  150. package/rules/k8s/policy/hpa_pdb/hpa_pdb.mdc +23 -0
  151. package/rules/k8s/policy/kustomization/kustomization.mdc +20 -0
  152. package/rules/k8s/policy/manifest/manifest.mdc +17 -0
  153. package/rules/k8s/policy/network_policy/network_policy.mdc +22 -0
  154. package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
  155. package/rules/k8s/policy/svc_yaml/svc_yaml.mdc +12 -0
  156. package/rules/nginx-default-tpl/js/dockerfile.mdc +36 -0
  157. package/rules/nginx-default-tpl/js/http-route.mdc +41 -0
  158. package/rules/nginx-default-tpl/js/ini-keys.mdc +21 -0
  159. package/rules/nginx-default-tpl/js/template-structure.mdc +86 -0
  160. package/rules/nginx-default-tpl/js/vscode.mdc +37 -0
  161. package/rules/nginx-default-tpl/main.mdc +8 -110
  162. package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions.mdc +11 -0
  163. package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings.mdc +15 -0
  164. package/rules/npm-module/js/docs/index.md +5 -5
  165. package/rules/npm-module/js/docs/rule_meta.md +6 -6
  166. package/rules/npm-module/js/docs/skill_meta.md +8 -8
  167. package/rules/npm-module/js/header_doc_pointer.mdc +18 -0
  168. package/rules/npm-module/js/package_structure.mdc +62 -0
  169. package/rules/npm-module/js/rule_meta.mdc +11 -0
  170. package/rules/npm-module/js/skill_meta.mdc +11 -0
  171. package/rules/npm-module/main.mdc +10 -52
  172. package/rules/npm-module/policy/emit_types_config/emit_types_config.mdc +40 -0
  173. package/rules/npm-module/policy/npm_package_json/npm_package_json.mdc +50 -0
  174. package/rules/npm-module/policy/root_package_json/root_package_json.mdc +37 -0
  175. package/rules/php/js/lint_php_yml.mdc +12 -0
  176. package/rules/php/js/tooling.mdc +66 -0
  177. package/rules/php/main.mdc +5 -66
  178. package/rules/php/policy/lint_php_yml/lint_php_yml.mdc +21 -0
  179. package/rules/python/js/lint_python_yml.mdc +23 -0
  180. package/rules/python/js/pyproject_toml.mdc +32 -0
  181. package/rules/python/js/tooling.mdc +23 -0
  182. package/rules/python/main.mdc +7 -32
  183. package/rules/python/policy/lint_python_yml/lint_python_yml.mdc +12 -0
  184. package/rules/python/policy/pyproject_toml/pyproject_toml.mdc +13 -0
  185. package/rules/rego/js/rego-lint.mdc +31 -0
  186. package/rules/rego/js/vscode_extensions.mdc +11 -0
  187. package/rules/rego/js/vscode_settings.mdc +13 -0
  188. package/rules/rego/main.mdc +10 -22
  189. package/rules/rego/policy/vscode_extensions/vscode_extensions.mdc +11 -0
  190. package/rules/rego/policy/vscode_settings/vscode_settings.mdc +19 -0
  191. package/rules/rust/js/coverage.mdc +28 -0
  192. package/rules/rust/js/lint.mdc +22 -0
  193. package/rules/rust/js/tauri_composition.mdc +8 -0
  194. package/rules/rust/js/vscode_extensions.mdc +12 -0
  195. package/rules/rust/main.mdc +8 -38
  196. package/rules/rust/policy/lint_rust_yml/lint_rust_yml.mdc +12 -0
  197. package/rules/rust/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  198. package/rules/security/js/rego_policies.mdc +15 -0
  199. package/rules/security/js/sample_secret.mdc +19 -0
  200. package/rules/security/js/trufflehog.mdc +21 -0
  201. package/rules/security/main.mdc +7 -34
  202. package/rules/security/policy/lint_security_yml/lint_security_yml.mdc +7 -0
  203. package/rules/security/policy/package_json/package_json.mdc +7 -0
  204. package/rules/style/js/admin-table.mdc +88 -0
  205. package/rules/style/js/colors.mdc +21 -0
  206. package/rules/style/js/gap.mdc +22 -0
  207. package/rules/style/js/quasar-fixes.mdc +32 -0
  208. package/rules/style/js/quasar.mdc +7 -0
  209. package/rules/style/js/tooling.mdc +85 -0
  210. package/rules/style/main.mdc +12 -251
  211. package/rules/style/policy/lint_style_yml/lint_style_yml.mdc +13 -0
  212. package/rules/style/policy/package_json/package_json.mdc +18 -0
  213. package/rules/style/policy/vscode_extensions/vscode_extensions.mdc +13 -0
  214. package/rules/style/policy/vscode_settings/vscode_settings.mdc +19 -0
  215. package/rules/tauri/js/cargo_mutants_config.mdc +39 -0
  216. package/rules/tauri/js/tool_surface.mdc +21 -0
  217. package/rules/tauri/js/tooling.mdc +25 -0
  218. package/rules/tauri/main.mdc +6 -78
  219. package/rules/tauri/policy/vscode_extensions/vscode_extensions.mdc +21 -0
  220. package/rules/test/js/cargo_mutants_config.mdc +18 -0
  221. package/rules/test/js/docs/index.md +7 -7
  222. package/rules/test/js/location.mdc +52 -0
  223. package/rules/test/js/no-console-store-restore.mdc +11 -0
  224. package/rules/test/js/no-process-chdir.mdc +15 -0
  225. package/rules/test/js/no-relative-fs-path.mdc +22 -0
  226. package/rules/test/js/sandbox-aware-test.mdc +28 -0
  227. package/rules/test/js/stryker_config.mdc +26 -0
  228. package/rules/test/js/vitest-config-pool-forks.mdc +33 -0
  229. package/rules/test/main.mdc +16 -184
  230. package/rules/test/policy/package_json/package_json.mdc +16 -0
  231. package/rules/text/js/ci-lint-text.mdc +15 -0
  232. package/rules/text/js/cspell.mdc +81 -0
  233. package/rules/text/js/dotenv-linter.mdc +16 -0
  234. package/rules/text/js/forbidden-prettier.mdc +13 -0
  235. package/rules/text/js/markdownlint.mdc +25 -0
  236. package/rules/text/js/oxfmt.mdc +35 -0
  237. package/rules/text/js/package-json.mdc +26 -0
  238. package/rules/text/js/shellcheck.mdc +18 -0
  239. package/rules/text/js/v8r.mdc +23 -0
  240. package/rules/text/js/vscode.mdc +86 -0
  241. package/rules/text/main.mdc +20 -231
  242. package/rules/text/policy/cspell/cspell.mdc +34 -0
  243. package/rules/text/policy/lint_text/lint_text.mdc +19 -0
  244. package/rules/text/policy/markdownlint/markdownlint.mdc +38 -0
  245. package/rules/text/policy/oxfmtrc/oxfmtrc.mdc +11 -0
  246. package/rules/text/policy/package_json/package_json.mdc +33 -0
  247. package/rules/text/policy/vscode_extensions/vscode_extensions.mdc +13 -0
  248. package/rules/text/policy/vscode_settings/vscode_settings.mdc +13 -0
  249. package/rules/vue/js/composition-api.mdc +82 -0
  250. package/rules/vue/js/nheader-layout.mdc +171 -0
  251. package/rules/vue/js/node-imports.mdc +25 -0
  252. package/rules/vue/js/quasar-ui.mdc +32 -0
  253. package/rules/vue/js/structure.mdc +101 -0
  254. package/rules/vue/js/testing.mdc +32 -0
  255. package/rules/vue/js/tfm-translations.mdc +26 -0
  256. package/rules/vue/js/vite-config.mdc +126 -0
  257. package/rules/vue/js/vite-env.mdc +55 -0
  258. package/rules/vue/js/vue-imports.mdc +25 -0
  259. package/rules/vue/main.mdc +15 -641
  260. package/rules/vue/policy/package_json/package_json.mdc +30 -0
  261. package/scripts/docs/index.md +16 -16
  262. package/scripts/lib/docs/index.md +36 -36
  263. package/scripts/utils/docs/index.md +14 -14
@@ -0,0 +1,108 @@
1
+ ## Універсальні правила для всіх workflow-файлів
2
+
3
+ Перевіряє кожен `.github/workflows/*.yml` через Rego-пакет `ga.workflow_common`.
4
+
5
+ ### Блок `concurrency` — обов'язковий
6
+
7
+ **Кожен** workflow у `.github/workflows/*.yml` **обов'язково** містить блок `concurrency` з фіксованим `group` та `cancel-in-progress: true`:
8
+
9
+ ```yaml
10
+ concurrency:
11
+ group: ${{ github.ref }}-${{ github.workflow }}
12
+ cancel-in-progress: true
13
+ ```
14
+
15
+ Без винятків — у scheduled cleanup-воркфлоу, у `pull_request: types: [closed]`, у publish-воркфлоу теж. Це уникає паралельних запусків того самого workflow на тій самій ref і скасовує попередні в чергу нових.
16
+
17
+ ### Локальний composite `setup-bun-deps` — обов'язковий
18
+
19
+ **ЗАБОРОНЕНО** дублювати кроки встановлення Bun та кешування безпосередньо у workflow файлах. Завжди використовуй локальний composite action.
20
+
21
+ **Локальний composite** (`uses: ./.github/actions/setup-bun-deps` або `./npm/github-actions/setup-bun-deps`): **спочатку** обов'язковий крок **`actions/checkout@v6`** (`persist-credentials: false`), інакше runner не знайде `action.yml`. Сам composite: **`actions/setup-node@v6`** (**Node 24**), **Bun**, **`actions/cache@v5`**, **`bun install --frozen-lockfile`**.
22
+
23
+ ### Приклад (НЕПРАВИЛЬНО)
24
+
25
+ ```yaml
26
+ steps:
27
+ - uses: actions/checkout@v6
28
+ - uses: oven-sh/setup-bun@v2
29
+ - uses: actions/cache@v5
30
+ # ... багато рядків кешування ...
31
+ - run: bun install --frozen-lockfile
32
+ ```
33
+
34
+ ### Приклад (ПРАВИЛЬНО)
35
+
36
+ ```yaml
37
+ steps:
38
+ - uses: actions/checkout@v6
39
+ with:
40
+ persist-credentials: false
41
+ - uses: ./.github/actions/setup-bun-deps
42
+ ```
43
+
44
+ ### Крок `run:` — folded block `>-`
45
+
46
+ **Кроки `run`:** не розбивай команду shell-продовженням через зворотний сліш у кінці рядка (`… \` у `run: |`). Замість багаторядкового буквального блока з `\\` оформ довгу одну shell-команду як **folded block** `>-` (рядки з'єднаються в один рядок із пробілами).
47
+
48
+ **Читабельність `run: >-` з циклами/умовами:** оскільки `>-` **згортає рядки в один shell-рядок**, відступи потрібні **лише для читабельності** й не впливають на виконання. Але для конструкцій bash на кшталт `while …; do … done` та `if …; then … fi` **обов'язково**:
49
+
50
+ - став явні роздільники команд **`;`** або **`&&`** там, де при згортанні рядків інакше "злипнуться" токени (`do`/`then`/`fi`/`done` з наступною командою);
51
+ - тримай `do` і `then` в одному логічному рядку як `…; do` / `…; then`, щоб після згортання це гарантовано лишалось валідним bash;
52
+ - додавай відступи всередині `do/then/else` блоків, навіть якщо це один рядок після згортання — так workflow лишається читабельним у diff.
53
+
54
+ ### Приклад (ПРАВИЛЬНО — читабельно, `run: >-`, з `while`/`if`)
55
+
56
+ ```yaml
57
+ - name: Apply changes
58
+ shell: bash
59
+ run: >-
60
+ echo "$FILES" |
61
+ while read -r FILE; do
62
+ [ -z "$FILE" ] && continue;
63
+ dirname "$FILE";
64
+ done |
65
+ sort -u |
66
+ while read -r DIR; do
67
+ (
68
+ if [ -f "$DIR/kustomization.yaml" ]; then
69
+ printf 'Applying %s\n' "$DIR" &&
70
+ cd "$DIR" &&
71
+ kubectl apply -k .;
72
+ else
73
+ echo "Skip $DIR - no kustomization.yaml";
74
+ fi
75
+ );
76
+ done
77
+ ```
78
+
79
+ ### Приклад run (НЕПРАВИЛЬНО — `\\` на кінцях)
80
+
81
+ ```yaml
82
+ - run: |
83
+ docker build \
84
+ --push \
85
+ --build-arg BRANCH=${{ github.ref_name }}
86
+ ```
87
+
88
+ ### Приклад run (ПРАВИЛЬНО — `>-`)
89
+
90
+ ```yaml
91
+ - run: >-
92
+ docker build
93
+ --push
94
+ --build-arg BRANCH=${{ github.ref_name }}
95
+ ```
96
+
97
+ ### Мінімальні версії marketplace actions
98
+
99
+ Канон: [uses-min-versions.snippet.json](./policy/workflow_common/template/uses-min-versions.snippet.json)
100
+
101
+ - `actions/checkout` — **не нижче major `v6`** (`@v6`, `@v6.0.2` тощо дозволені; `@v5` — ні);
102
+ - `Infisical/secrets-action` — **не нижче `v1.0.16`** (Node 24; нижчі теги лишаються на Node 20, deprecated з червня 2026).
103
+
104
+ SHA-pin (40 hex) semver-політику не застосовує. Для checkout рекомендується **`v6.0.2+`** (Node 24 у action), але мінімум політики — лише major **6**.
105
+
106
+ ### Заборона `depcheck` у workflow
107
+
108
+ **`depcheck`:** не використовувати у `.github/workflows/*.yml` — мігровано на `knip` (div. `js.mdc`). Перевірка невикористаних залежностей виконується разом з рештою лінтерів у `lint-js`, окремий крок `npx depcheck` у workflow не потрібен і блокується полісі `ga.workflow_common`.
@@ -0,0 +1,32 @@
1
+ ## Структура workflow-файлів та обов'язкові workflows
2
+
3
+ У `.github/workflows/` лише **`.yml`** (не `.yaml`). Обов'язкові файли:
4
+
5
+ - **`clean-ga-workflows.yml`**
6
+ - **`clean-merged-branch.yml`**
7
+ - **`lint-ga.yml`**
8
+ - **`git-ai.yml`**
9
+
10
+ Якщо є **`apply-k8s.yml`** — тригер `on.push.paths` має містити `**/k8s/**/*.yaml`.
11
+ Якщо є **`apply-nats-consumer.yml`** — тригер `on.push.paths` має містити `**/consumer.yaml`.
12
+
13
+ ## Перевірка glob-патернів `on.push.paths`
14
+
15
+ Кожен позитивний glob у `on.push.paths` / `on.pull_request.paths` (крім `!`-негацій та `*`-extension-фільтрів) має матчитися хоча б на один tracked файл у репозиторії (`git ls-files`). Шаблони на кшталт `*.vue` чи `{*.ts,*.js}` пропускаються — вони можуть бути заготовками для майбутніх файлів. Конкретні директорії (`some-dir/**`) — перевіряються.
16
+
17
+ ## Заборона MegaLinter
18
+
19
+ **MegaLinter** не використовувати. Треба видалити:
20
+
21
+ - workflow-файли з `oxsecurity/megalinter-action` або `megalinter/megalinter`
22
+ - конфіги: `.mega-linter.yml`, `.megalinter.yaml`, `.mega-linter.yaml`
23
+ - будь-які залежності та згадки в CI / pre-commit / документації
24
+
25
+ ## Shellcheck у PATH
26
+
27
+ `actionlint` (через `bunx github-actionlint`) запускає shell-перевірки в кроках `run:` лише коли `shellcheck` доступний у PATH — інакше мовчки пропускає SC-правила. Локальний `bun lint-ga` лишається зеленим, а CI на `ubuntu-latest` (де shellcheck передвстановлений) падає.
28
+
29
+ Встанови `shellcheck`:
30
+ - macOS: `brew install shellcheck`
31
+ - Debian/Ubuntu: `sudo apt-get install -y shellcheck`
32
+ - Arch: `sudo pacman -S shellcheck`
@@ -0,0 +1,7 @@
1
+ ## `.github/zizmor.yml` — конфігурація zizmor
2
+
3
+ Для [unpinned-uses](https://docs.zizmor.sh/audits/#unpinned-uses) — політика **`ref-pin`**, якщо в `uses:` семантичні теги. За потреби вимкни [template-injection](https://docs.zizmor.sh/audits/#template-injection).
4
+
5
+ - Канон `.github/zizmor.yml`: [zizmor.yml.snippet.yml](./policy/zizmor_yml/template/zizmor.yml.snippet.yml)
6
+
7
+ Rego-пакет `ga.zizmor_yml`: перевіряє `rules.unpinned-uses.config.policies["*"]` відповідно до значення з template.
package/rules/ga/main.mdc CHANGED
@@ -5,137 +5,34 @@ globs: ".github/workflows/*.yml"
5
5
  alwaysApply: false
6
6
  ---
7
7
 
8
- У `.github/workflows/` лише **`.yml`**. Мають бути **`clean-ga-workflows.yml`**, **`clean-merged-branch.yml`**, **`lint-ga.yml`**, **`git-ai.yml`**. Якщо є **`apply-k8s.yml`** / **`apply-nats-consumer.yml`** paths у тригері як у фрагментах.
8
+ Правило **ga** перевіряє структуру `.github/workflows/`, наявність обов'язкових workflow-файлів і їх відповідність канонам, а також налаштування VS Code та zizmor для роботи з GitHub Actions.
9
9
 
10
- **Кожен** workflow у `.github/workflows/*.yml` **обов'язково** містить блок `concurrency` з фіксованим `group` та `cancel-in-progress: true`:
10
+ [ga-workflows](./js/workflows.mdc)
11
11
 
12
- ```yaml
13
- concurrency:
14
- group: ${{ github.ref }}-${{ github.workflow }}
15
- cancel-in-progress: true
16
- ```
12
+ [ga-workflow_common](./js/workflow_common.mdc)
17
13
 
18
- Без винятків — у scheduled cleanup-воркфлоу, у `pull_request: types: [closed]`, у publish-воркфлоу теж. Це уникає паралельних запусків того самого workflow на тій самій ref і скасовує попередні в чергу нових.
14
+ [ga-required_workflows](./js/required_workflows.mdc)
19
15
 
20
- Повинен бути файл `.github/workflows/clean-ga-workflows.yml`:
16
+ [ga-vscode](./js/vscode.mdc)
21
17
 
22
- - Канон: [clean-ga-workflows.yml.snippet.yml](./policy/clean_ga_workflows/template/clean-ga-workflows.yml.snippet.yml)
18
+ [ga-zizmor](./js/zizmor.mdc)
23
19
 
24
- Повинен бути файл `.github/workflows/clean-merged-branch.yml`:
20
+ [ga-lint_toolchain](./js/lint_toolchain.mdc)
25
21
 
26
- - Канон: [clean-merged-branch.yml.snippet.yml](./policy/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml)
22
+ ## Швидкий gate через conftest
27
23
 
28
- Інші гілки в `ignore_branches` — допустимо.
24
+ [ga-workflow_common](./policy/workflow_common/workflow_common.mdc)
29
25
 
30
- Повинен бути файл `.github/workflows/lint-ga.yml`:
26
+ [ga-clean_ga_workflows](./policy/clean_ga_workflows/clean_ga_workflows.mdc)
31
27
 
32
- - Канон: [lint-ga.yml.snippet.yml](./policy/lint_ga/template/lint-ga.yml.snippet.yml)
28
+ [ga-clean_merged_branch](./policy/clean_merged_branch/clean_merged_branch.mdc)
33
29
 
34
- Повинен бути файл `.github/workflows/git-ai.yml`:
30
+ [ga-lint_ga](./policy/lint_ga/lint_ga.mdc)
35
31
 
36
- - Канон: [git-ai.yml.snippet.yml](./policy/git_ai/template/git-ai.yml.snippet.yml)
32
+ [ga-git_ai](./policy/git_ai/git_ai.mdc)
37
33
 
38
- **Мінімальні версії marketplace actions** у `uses:` (перевіряє `ga.workflow_common`):
34
+ [ga-vscode_extensions](./policy/vscode_extensions/vscode_extensions.mdc)
39
35
 
40
- - `actions/checkout` — **не нижче major `v6`** (`@v6`, `@v6.0.2` тощо дозволені; `@v5` — ні);
41
- - `Infisical/secrets-action` — **не нижче `v1.0.16`** (Node 24; нижчі теги лишаються на Node 20, deprecated з червня 2026).
36
+ [ga-vscode_settings](./policy/vscode_settings/vscode_settings.mdc)
42
37
 
43
- Канон: [uses-min-versions.snippet.json](./policy/workflow_common/template/uses-min-versions.snippet.json). SHA-pin (40 hex) semver-політику не застосовує. Для checkout рекомендується **`v6.0.2+`** (Node 24 у action), але мінімум політики — лише major **6**.
44
-
45
- **Локальний composite** (`uses: ./.github/actions/setup-bun-deps` або `./npm/github-actions/setup-bun-deps`): **спочатку** обов’язковий крок **`actions/checkout@v6`** (`persist-credentials: false`), інакше runner не знайде `action.yml`. Сам composite: **`actions/setup-node@v6`** (**Node 24**), **Bun**, **`actions/cache@v5`**, **`bun install --frozen-lockfile`**.
46
-
47
- **ЗАБОРОНЕНО** дублювати кроки встановлення Bun та кешування безпосередньо у workflow файлах. Завжди використовуй локальний composite action.
48
-
49
- **Кроки `run`:** не розбивай команду shell-продовженням через зворотний сліш у кінці рядка (`… \` у `run: |`). Замість багаторядкового буквального блока з `\\` оформ довгу одну shell-команду як **folded block** `>-` (рядки з’єднаються в один рядок із пробілами).
50
-
51
- **Читабельність `run: >-` з циклам/умовами:** оскільки `>-` **згортає рядки в один shell-рядок**, відступи потрібні **лише для читабельності** й не впливають на виконання. Але для конструкцій bash на кшталт `while …; do … done` та `if …; then … fi` **обовʼязково**:
52
-
53
- - став явні роздільники команд **`;`** або **`&&`** там, де при згортанні рядків інакше “злипнуться” токени (`do`/`then`/`fi`/`done` з наступною командою);
54
- - тримай `do` і `then` в одному логічному рядку як `…; do` / `…; then`, щоб після згортання це гарантовано лишалось валідним bash;
55
- - додавай відступи всередині `do/then/else` блоків, навіть якщо це один рядок після згортання — так workflow лишається читабельним у diff.
56
-
57
- ### Приклад (ПРАВИЛЬНО — читабельно, `run: >-`, з `while`/`if`)
58
-
59
- ```yaml
60
- - name: Apply changes
61
- shell: bash
62
- run: >-
63
- echo "$FILES" |
64
- while read -r FILE; do
65
- [ -z "$FILE" ] && continue;
66
- dirname "$FILE";
67
- done |
68
- sort -u |
69
- while read -r DIR; do
70
- (
71
- if [ -f "$DIR/kustomization.yaml" ]; then
72
- printf 'Applying %s\n' "$DIR" &&
73
- cd "$DIR" &&
74
- kubectl apply -k .;
75
- else
76
- echo "Skip $DIR - no kustomization.yaml";
77
- fi
78
- );
79
- done
80
- ```
81
-
82
- ### Приклад run (НЕПРАВИЛЬНО — `\\` на кінцях)
83
-
84
- ```yaml
85
- - run: |
86
- docker build \
87
- --push \
88
- --build-arg BRANCH=${{ github.ref_name }}
89
- ```
90
-
91
- ### Приклад run (ПРАВИЛЬНО — `>-`)
92
-
93
- ```yaml
94
- - run: >-
95
- docker build
96
- --push
97
- --build-arg BRANCH=${{ github.ref_name }}
98
- ```
99
-
100
- ### Приклад (НЕПРАВИЛЬНО)
101
-
102
- ```yaml
103
- steps:
104
- - uses: actions/checkout@v6
105
- - uses: oven-sh/setup-bun@v2
106
- - uses: actions/cache@v5
107
- # ... багато рядків кешування ...
108
- - run: bun install --frozen-lockfile
109
- ```
110
-
111
- ### Приклад (ПРАВИЛЬНО)
112
-
113
- ```yaml
114
- steps:
115
- - uses: actions/checkout@v6
116
- with:
117
- persist-credentials: false
118
- - uses: ./.github/actions/setup-bun-deps
119
- ```
120
-
121
- **Лінт:** [actionlint](https://github.com/rhysd/actionlint) через [github-actionlint](https://www.npmjs.com/package/github-actionlint); [zizmor](https://docs.zizmor.sh) — `uvx`, офлайн. Запуск — через **`n-cursor lint ga`** (CI — `--read-only`; бінарка з `node_modules/.bin/` пакету `@nitra/cursor`), який робить preflight на `shellcheck` і послідовно запускає `actionlint` та `zizmor`. Окремого `package.json`-скрипта немає.
122
-
123
- > Виклик через bin-ім’я `n-cursor` (а **не** `npx @nitra/cursor`): `bun x`/`npx` для скоупованого пакету з одним bin-ім’ям повертає 0 без виконання, тому в CI-кроці `run:` використовуй саме `n-cursor lint <rule>`.
124
-
125
- CLI робить preflight на `shellcheck` і `uv` (`uvx`) у `PATH`, потім запускає `bunx github-actionlint` і `uvx zizmor --offline --collect=workflows .`.
126
-
127
- **`.github/zizmor.yml`:** для [unpinned-uses](https://docs.zizmor.sh/audits/#unpinned-uses) — політика **`ref-pin`**, якщо в `uses:` семантичні теги. За потреби вимкни [template-injection](https://docs.zizmor.sh/audits/#template-injection):
128
-
129
- - Канон `.github/zizmor.yml`: [zizmor.yml.snippet.yml](./policy/zizmor_yml/template/zizmor.yml.snippet.yml)
130
-
131
- **`.vscode/extensions.json`** має рекомендувати `github.vscode-github-actions`:
132
-
133
- - Канон: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
134
-
135
- **`.vscode/settings.json`** для мови `github-actions-workflow` має `editor.defaultFormatter = "oxc.oxc-vscode"`:
136
-
137
- - Канон: [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
138
-
139
- **MegaLinter:** не використовувати; прибрати workflow, конфіги (`.mega-linter.yml`, `.megalinter.yaml`, `.mega-linter.yaml`), залежності та згадки в CI / pre-commit / документації.
140
-
141
- **`depcheck`:** не використовувати у `.github/workflows/*.yml` — мігровано на `knip` (див. `js.mdc`). Перевірка невикористаних залежностей виконується разом з рештою лінтерів у `lint-js`, окремий крок `npx depcheck` у workflow не потрібен і блокується полісі `ga.workflow_common`.
38
+ [ga-zizmor_yml](./policy/zizmor_yml/zizmor_yml.mdc)
@@ -0,0 +1,18 @@
1
+ ## Структура `clean-ga-workflows.yml` — видалення завершених workflow runs
2
+
3
+ Rego-пакет: `ga.clean_ga_workflows`
4
+
5
+ **Цільовий файл:** `.github/workflows/clean-ga-workflows.yml`
6
+
7
+ ### Що перевіряється
8
+
9
+ - `name` — точна відповідність значенню з template
10
+ - `on.schedule[].cron` — має містити cron із template (`0 1 16 * *`)
11
+ - `on.workflow_dispatch` — має бути об'єктом `{}`
12
+ - `jobs.cleanup_old_workflows` — job має існувати
13
+ - `jobs.cleanup_old_workflows.runs-on` — відповідно до template (`ubuntu-latest`)
14
+ - `jobs.cleanup_old_workflows.permissions` — `actions: write`, `contents: read`
15
+ - `steps[0].name` і `steps[0].uses` — відповідно до template (`dmvict/clean-workflow-runs@v1`)
16
+ - `steps[0].with` — `token`, `save_period`, `save_min_runs_number` як у template
17
+
18
+ Канон: [clean-ga-workflows.yml.snippet.yml](./template/clean-ga-workflows.yml.snippet.yml)
@@ -0,0 +1,22 @@
1
+ ## Структура `clean-merged-branch.yml` — видалення злитих гілок
2
+
3
+ Rego-пакет: `ga.clean_merged_branch`
4
+
5
+ **Цільовий файл:** `.github/workflows/clean-merged-branch.yml`
6
+
7
+ ### Що перевіряється
8
+
9
+ - `name` — точна відповідність значенню з template
10
+ - `on.schedule[].cron` — має містити cron із template (`0 1 15 * *`)
11
+ - `on.workflow_dispatch` — має бути об'єктом `{}`
12
+ - `jobs.cleanup_old_branches` — job має існувати
13
+ - `jobs.cleanup_old_branches.permissions` — кожне поле із template (`contents: write`, `pull-requests: read`)
14
+ - `steps` — має бути рівно 2 кроки
15
+ - `steps[0].id` — `delete_stuff`; `steps[0].uses` — `phpdocker-io/github-actions-delete-abandoned-branches@v2.0.3`
16
+ - `steps[0].with.github_token`, `last_commit_age_days` — за template
17
+ - `steps[0].with.ignore_branches` — має містити всі гілки з template (`main,dev`)
18
+ - `steps[0].with.dry_run` — `no` (нормалізується: YAML 1.1 `no` → boolean `false` у conftest)
19
+ - `steps[1].name` — за template; `steps[1].env.DELETED_BRANCHES` — за template
20
+ - `steps[1].run` — містить `Deleted branches:` та `${DELETED_BRANCHES}`
21
+
22
+ Канон: [clean-merged-branch.yml.snippet.yml](./template/clean-merged-branch.yml.snippet.yml)
@@ -0,0 +1,19 @@
1
+ ## Структура `git-ai.yml` — автоматичний запуск git-ai після мержу PR
2
+
3
+ Rego-пакет: `ga.git_ai`
4
+
5
+ **Цільовий файл:** `.github/workflows/git-ai.yml`
6
+
7
+ ### Що перевіряється
8
+
9
+ - `name` — точна відповідність значенню з template (`Git AI`)
10
+ - `on.pull_request.types` — має містити `closed`
11
+ - `jobs.git-ai` — job має існувати
12
+ - `jobs.git-ai.if` — містить `github.event.pull_request.merged == true`
13
+ - `jobs.git-ai.permissions.contents` — за template (`write`)
14
+ - `steps[*].run` (сукупно) — містить substring `https://usegitai.com/install.sh` (інсталяція)
15
+ - `steps[*].run` (сукупно) — містить substring `git-ai ci github run` (запуск)
16
+
17
+ Substring-перевірки замість exact-match через крихкість multi-line `run:` блоків.
18
+
19
+ Канон: [git-ai.yml.snippet.yml](./template/git-ai.yml.snippet.yml)
@@ -0,0 +1,21 @@
1
+ ## Структура `lint-ga.yml` — CI-лінт GitHub Actions файлів
2
+
3
+ Rego-пакет: `ga.lint_ga`
4
+
5
+ **Цільовий файл:** `.github/workflows/lint-ga.yml`
6
+
7
+ ### Що перевіряється
8
+
9
+ - `name` — точна відповідність значенню з template (`Lint GA`)
10
+ - `on.push.branches` — superset: містить `dev` і `main`
11
+ - `on.pull_request.branches` — superset: містить `dev` і `main`
12
+ - `on.push.paths` — superset: містить `.github/actions/**` і `.github/workflows/**`
13
+ - `jobs.lint-ga` — job має існувати
14
+ - `jobs.lint-ga.runs-on` — за template (`ubuntu-latest`)
15
+ - `jobs.lint-ga.permissions.contents` — `read`
16
+ - `jobs.lint-ga.steps` — не порожній
17
+ - `steps[*].uses` — кожен `uses:` з template має бути присутнім у кроках
18
+ - `steps[*].run` (сукупно) — містить `open-policy-agent/conftest` (Install conftest)
19
+ - `steps[*].run` (сукупно) — містить `n-cursor lint ga --read-only`
20
+
21
+ Канон: [lint-ga.yml.snippet.yml](./template/lint-ga.yml.snippet.yml)
@@ -0,0 +1,9 @@
1
+ ## `.vscode/extensions.json` — розширення для GitHub Actions
2
+
3
+ Rego-пакет: `ga.vscode_extensions`
4
+
5
+ **Цільовий файл:** `.vscode/extensions.json`
6
+
7
+ Кожне розширення з template має бути присутнє у `recommendations`. Додаткові розширення від інших правил — допустимі (subset-перевірка).
8
+
9
+ Канон: [extensions.json.snippet.json](./template/extensions.json.snippet.json)
@@ -0,0 +1,9 @@
1
+ ## `.vscode/settings.json` — налаштування форматування GitHub Actions workflow
2
+
3
+ Rego-пакет: `ga.vscode_settings`
4
+
5
+ **Цільовий файл:** `.vscode/settings.json`
6
+
7
+ Перевіряє 2-рівневу структуру: для кожного `<block-key>` з template кожен `<leaf-key>` у відповідному блоці input має точно відповідати очікуваному значенню. Ключі можуть містити дужки та крапки (VS Code-конвенція, наприклад `[github-actions-workflow]`).
8
+
9
+ Канон: [settings.json.snippet.json](./template/settings.json.snippet.json)
@@ -0,0 +1,18 @@
1
+ ## Універсальні Rego-перевірки для всіх workflow-файлів
2
+
3
+ Rego-пакет: `ga.workflow_common`
4
+
5
+ **Цільові файли:** `.github/workflows/*.yml` (кожен файл окремо)
6
+
7
+ ### Що перевіряється
8
+
9
+ - **concurrency** — обов'язкова наявність блоку; `group` = `${{ github.ref }}-${{ github.workflow }}`; `cancel-in-progress: true`
10
+ - **Заборонені кроки** — `oven-sh/setup-bun`, `actions/cache`, `bun install` у будь-якому `uses:`/`run:` (мають бути інкапсульовані у composite `setup-bun-deps`)
11
+ - **Порядок кроків** — якщо є `setup-bun-deps`, перед ним обов'язковий `actions/checkout@`
12
+ - **Shell-продовження** — `\` перед переносом рядка у `run:` заборонено; треба `run: >-`
13
+ - **Заборонені команди** — `depcheck` у `run:` (мігровано на `knip`)
14
+ - **Мінімальні версії** — `uses:` з marketplace-actions перевіряються за канонічним JSON
15
+
16
+ Канон мінімальних версій: [uses-min-versions.snippet.json](./template/uses-min-versions.snippet.json)
17
+
18
+ Детальна документація поведінки — у [ga-workflow_common](../../js/workflow_common.mdc).
@@ -0,0 +1,9 @@
1
+ ## `.github/zizmor.yml` — конфігурація zizmor для unpinned-uses
2
+
3
+ Rego-пакет: `ga.zizmor_yml`
4
+
5
+ **Цільовий файл:** `.github/zizmor.yml`
6
+
7
+ Перевіряє `rules.unpinned-uses.config.policies["*"]` — значення має точно відповідати template (`ref-pin`). Всі вкладені об'єкти читаються через `object.get` із дефолтами, тож відсутні ключі коректно детектуються як порушення.
8
+
9
+ Канон: [zizmor.yml.snippet.yml](./template/zizmor.yml.snippet.yml)
@@ -0,0 +1,13 @@
1
+ ## Умовна вимога `.graphqlrc.yml`
2
+
3
+ Якщо у `.vue` або в JavaScript / TypeScript джерелах (`.js`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.jsx` тощо) зустрічається **tagged template literal** з тегом **`gql`** (типово `gql\`query …\`` для GraphQL-запиту), у **корені репозиторію** має бути файл **`.graphqlrc.yml`** ([GraphQL Config](https://the-guild.dev/graphql/config/docs)).
4
+
5
+ Перевірка є **умовною**: якщо жодного `gql\`…\`` у дереві не знайдено — `.graphqlrc.yml` не вимагається.
6
+
7
+ Підстав свої шляхи до схеми та до файлів з операціями; приклад орієнтиру:
8
+
9
+ ```yaml title=".graphqlrc.yml"
10
+ schema: node_modules/@nitra/efes-shared/schema/maya.graphql
11
+ documents:
12
+ - '**/*.{vue,js,ts,tsx}'
13
+ ```
@@ -0,0 +1,13 @@
1
+ ## Розширення VS Code для GraphQL
2
+
3
+ Якщо у проєкті є `gql\`…\`` tagged template literals, у **`.vscode/extensions.json`** в масиві **`recommendations`** має бути запис **`graphql.vscode-graphql`**.
4
+
5
+ Канон задає мінімум — інші записи (від markdownlint, oxc тощо) дозволені. Перевірка виконується Rego-пакетом `graphql.vscode_extensions` через `conftest` і запускається лише після того, як JS-сканер виявив `gql` у дереві.
6
+
7
+ Додай `graphql.vscode-graphql` до наявного списку `recommendations` (не замінюй інші записи):
8
+
9
+ ```json title=".vscode/extensions.json"
10
+ {
11
+ "recommendations": ["graphql.vscode-graphql"]
12
+ }
13
+ ```
@@ -5,27 +5,10 @@ globs: "**/*.{vue,js,mjs,cjs,ts,tsx,jsx}"
5
5
  alwaysApply: false
6
6
  ---
7
7
 
8
- Якщо в **`.vue`** або в **JavaScript / TypeScript** джерелах (`.js`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.jsx` тощо) зустрічається **tagged template literal** з тегом **`gql`** (типово `gql\`query …\`` для GraphQL-запиту), у **корені репозиторію** мають бути:
8
+ Якщо у `.vue` або JavaScript / TypeScript джерелах зустрічається **tagged template literal** з тегом **`gql`**, у корені репозиторію мають бути `.graphqlrc.yml` та запис `graphql.vscode-graphql` у `.vscode/extensions.json`.
9
9
 
10
- - файл **`.graphqlrc.yml`** ([GraphQL Config](https://the-guild.dev/graphql/config/docs));
11
- - у **`.vscode/extensions.json`** в масиві **`recommendations`** — запис **`graphql.vscode-graphql`**.
10
+ [graphql-tooling](./js/tooling.mdc)
12
11
 
13
- ## `.graphqlrc.yml`
12
+ [graphql-vscode-extensions](./js/vscode_extensions.mdc)
14
13
 
15
- Підстав свої шляхи до схеми та до файлів з операціями; приклад орієнтиру:
16
-
17
- ```yaml title=".graphqlrc.yml"
18
- schema: node_modules/@nitra/efes-shared/schema/maya.graphql
19
- documents:
20
- - '**/*.{vue,js,ts,tsx}'
21
- ```
22
-
23
- ## `.vscode/extensions.json`
24
-
25
- Додай **`graphql.vscode-graphql`** до наявного списку **`recommendations`** (не замінюй інші записи):
26
-
27
- ```json title=".vscode/extensions.json"
28
- {
29
- "recommendations": ["graphql.vscode-graphql"]
30
- }
31
- ```
14
+ [graphql-vscode-extensions-policy](./policy/vscode_extensions/vscode_extensions.mdc)
@@ -0,0 +1,9 @@
1
+ ## Rego-перевірка наявності graphql.vscode-graphql у recommendations
2
+
3
+ Rego-пакет: `graphql.vscode_extensions`
4
+
5
+ Цільовий файл: `.vscode/extensions.json` (передається явно через `runConftestBatch` — без `target.json`, тому не auto-discoverable).
6
+
7
+ Перевіряє: поле `recommendations` містить рядок `"graphql.vscode-graphql"`. Порожній масив або відсутнє поле — deny. Додаткові записи дозволені.
8
+
9
+ Запускається умовно — лише якщо JS-сканер виявив `gql\`…\`` у джерелах проєкту.
@@ -0,0 +1,27 @@
1
+ ## Внутрішній кластерний URL для HASURA_GRAPHQL_ENDPOINT
2
+
3
+ У `*.env` для атрибута `HASURA_GRAPHQL_ENDPOINT` підключення має бути **усередині кластера**, а не через публічний домен — інакше CI кладе метадані через зовнішній бекенд і ламає перевипуск/міграції.
4
+
5
+ Правило застосовується лише до проєктів **nitra** (у кореневому `package.json` `"repository": "https://github.com/nitra/*"`) і **abie** (`"repository": "https://github.com/abinbevefes/*"`); для інших репозиторіїв перевірка пропускається.
6
+
7
+ Файл `.env` (без імені) — виключення з цього правила, його змінювати не потрібно.
8
+
9
+ Приклад **неправильного** значення:
10
+
11
+ ```env
12
+ HASURA_GRAPHQL_ENDPOINT=https://vybeerai.com.ua/contract/ql
13
+ ```
14
+
15
+ Правильне значення:
16
+
17
+ ```env
18
+ HASURA_GRAPHQL_ENDPOINT=http://contract-h-hl.ua-contract.svc.abie-ua.internal:8080
19
+ ```
20
+
21
+ де `contract-h-hl` — це `metadata.name` headless Service з `hasura/k8s/base/svc-hl.yaml` (пара з clusterIP `contract-h` у `svc.yaml`, якщо є; узгоджено з k8s: суфікс `-hl` на базі `-h`), а `ua-contract` — `metadata.name` namespace з `hasura/k8s/base/namespace.yaml`.
22
+
23
+ Формат URL: `http://<service>.<namespace>.svc.<cluster>.internal:<port>`
24
+
25
+ - `http://` обов'язковий (TLS усередині кластера зайвий)
26
+ - DNS-суфікс — `<cluster>.internal` (GKE/GCP)
27
+ - Сервіс і namespace звіряються з `hasura/k8s/base/svc-hl.yaml` та `hasura/k8s/base/namespace.yaml`
@@ -0,0 +1,13 @@
1
+ ## Міграції: лише `up.sql`, без `down.sql`
2
+
3
+ При створенні будь-якої нової директорії міграції у `hasura/migrations/` **не створювати файл `down.sql`**.
4
+ У директорії міграції має бути **тільки `up.sql`**.
5
+
6
+ Приклад коректної структури:
7
+
8
+ ```
9
+ hasura/migrations/default/1781247030100_add_foo/
10
+ └── up.sql ✓
11
+ ```
12
+
13
+ Файл `down.sql` у цьому проєкті **не використовується** і не повинен з'являтися.
@@ -0,0 +1,17 @@
1
+ ## Іменування headless та clusterIP Service у hasura/k8s/base
2
+
3
+ Hasura-конвенція іменування Service у `hasura/k8s/base/svc.yaml` та `svc-hl.yaml`:
4
+
5
+ - **clusterIP Service** (`svc.yaml`) — базовий сегмент закінчується на **`-h`** (наприклад, `contract-h`)
6
+ - **Headless Service** (`svc-hl.yaml`) — закінчується на **`-h-hl`** (наприклад, `contract-h-hl`)
7
+
8
+ Пара: `contract-h` (clusterIP) + `contract-h-hl` (headless) — обидва імені мають бути узгоджені між собою та з `HASURA_GRAPHQL_ENDPOINT` у `*.env`.
9
+
10
+ Перевірка виконується Rego-полісі `hasura.svc_hl` (package `hasura.svc_hl`):
11
+
12
+ ```
13
+ conftest test hasura/k8s/base/svc-hl.yaml -p npm/rules/hasura/policy/svc_hl \
14
+ --namespace hasura.svc_hl
15
+ ```
16
+
17
+ Cross-file перевірку (узгодженість `HASURA_GRAPHQL_ENDPOINT` ↔ YAML) виконує `js/internal_urls.mjs`.
@@ -5,38 +5,14 @@ globs: "**/hasura/**,**/*.env"
5
5
  alwaysApply: false
6
6
  ---
7
7
 
8
- ## Підключення для оновлення метаданих у CI (Nitra та Abinbevefes)
8
+ Правило охоплює: коректність підключення Hasura у CI-середовищі (внутрішній URL кластера), конвенцію іменування k8s-сервісів та структуру директорій міграцій.
9
9
 
10
- У `*.env` для атрибута `HASURA_GRAPHQL_ENDPOINT` підключення має бути **усередині кластера**, а не через публічний домен — інакше CI кладе метадані через зовнішній бекенд і ламає перевипуск/міграції.
10
+ [hasura-internal_urls](./js/internal_urls.mdc)
11
11
 
12
- Приклад **неправильного** значення:
12
+ [hasura-svc_hl](./js/svc_hl.mdc)
13
13
 
14
- ```env
15
- HASURA_GRAPHQL_ENDPOINT=https://vybeerai.com.ua/contract/ql
16
- ```
14
+ [hasura-migrations](./js/migrations.mdc)
17
15
 
18
- Правильне значення:
16
+ ## Швидкий gate через conftest
19
17
 
20
- ```env
21
- HASURA_GRAPHQL_ENDPOINT=http://contract-h-hl.ua-contract.svc.abie-ua.internal:8080
22
- ```
23
-
24
- де `contract-h-hl` — це `metadata.name` headless Service з `hasura/k8s/base/svc-hl.yaml` (пара з clusterIP `contract-h` у `svc.yaml`, якщо є; узгоджено з k8s: суфікс `-hl` на базі `-h`), а `ua-contract` — `metadata.name` namespace з `hasura/k8s/base/namespace.yaml`.
25
-
26
- Правило застосовується для проєктів **nitra** (у кореневому `package.json` `"repository": "https://github.com/nitra/*"`) і **abie** (`"repository": "https://github.com/abinbevefes/*"`); для інших репозиторіїв перевірка пропускається.
27
-
28
- Файл .env це (без імені) це виключення з цього правила, його змінювати не потрібно
29
-
30
- ## Міграції: лише `up.sql`, без `down.sql`
31
-
32
- При створенні будь-якої нової директорії міграції у `hasura/migrations/` **не створювати файл `down.sql`**.
33
- У директорії міграції має бути **тільки `up.sql`**.
34
-
35
- Приклад коректної структури:
36
-
37
- ```
38
- hasura/migrations/default/1781247030100_add_foo/
39
- └── up.sql ✓
40
- ```
41
-
42
- Файл `down.sql` у цьому проєкті **не використовується** і не повинен з'являтися.
18
+ [hasura-svc_hl](./policy/svc_hl/svc_hl.mdc)