@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
@@ -7,69 +7,16 @@ version: '2.1'
7
7
 
8
8
  Проект використовує тільки Bun для керування залежностями та запуску скриптів.
9
9
 
10
- **Одноразові CLI (hasura, eslint, vite, cypress тощо):**
10
+ [bun-layout](./js/layout.mdc)
11
11
 
12
- - Якщо в проєкті вже використовується **`npx`** (скрипти, CI, Dockerfile) — **залишай `npx`**, не замінюй на `bunx`.
13
- - Якщо новий виклик CLI додається з нуля і в цьому репозиторії прийнято лише Bun — можна `bunx <tool>`.
12
+ [bun-bunfig](./js/bunfig.mdc)
14
13
 
15
- Заборонено використовувати як менеджер пакетів / lockfile:
14
+ [bun-package_json](./js/package_json.mdc)
16
15
 
17
- - `npm install`, `yarn`, `pnpm` (і відповідні lockfile, крім `bun.lock`)
16
+ [bun-lint](./js/lint.mdc)
18
17
 
19
- Дозволені команди:
18
+ ## Швидкий gate через conftest
20
19
 
21
- - `bun i`
22
- - `bun run <script>`
23
- - `bun add <pkg>`
24
- - `bun add -d <pkg>`
25
- - `bun remove <pkg>`
26
- - `bunx <tool>`
27
- - `npx <tool>`
20
+ [bun-policy-bunfig](./policy/bunfig/bunfig.mdc)
28
21
 
29
- **Не додавай** у `dependencies` / `devDependencies` пакети, які **використовуються лише як CLI** і їх достатньо викликати через **`bunx <pkg>`** (або **`npx`**, якщо в проєкті так прийнято): наприклад **oxlint**, **jscpd**, **eslint** у корені тощо. Виняток — пакет потрібен як **бібліотека** (імпорт у коді), peer для іншого пакета, або інструмент **не** покривається `bunx` у вашому CI.
30
-
31
- Lockfile у репозиторії: `bun.lock`.
32
- Не створювати `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`.
33
- Видалити якщо вони є. Видалити .yarn та .yarnrc.yml якщо вони є.
34
-
35
- У корені репозиторію має бути **`bunfig.toml`** з **hoisted** лінкером (пласке `node_modules`, сумісне з інструментами, які не розуміють ізольований layout Bun):
36
-
37
- - Канон `bunfig.toml`: [bunfig.toml.snippet.toml](./policy/bunfig/template/bunfig.toml.snippet.toml)
38
-
39
- Для Bun monorepo:
40
-
41
- - Встановлювати залежності у відповідному пакеті, а не в корені без потреби.
42
- - Якщо залежність потрібна лише одному пакету, додавати її в директорії цього пакета.
43
- - У CI та локально запускати скрипти через `bun run`.
44
-
45
- В кореневому `package.json` не повинно бути `dependencies`, а в `devDependencies` — тільки модулі `@nitra/*`. **Виняток (root-only)** — Vitest/Stryker peer/tools для `n-cursor coverage`: `vitest`, `@vitest/coverage-v8`, `@stryker-mutator/vitest-runner`; а також `@playwright/test` для e2e-тестів. Тримати їх **у корені** доводиться у будь-якому монорепо-споживачі, бо правило `test` enabled завжди (`test/auto.md` = `завжди`), а класти ці пакети у workspace-и не можна: published пакети (`npm-module.mdc`) не мають мати `devDependencies`, а інші workspace-и однаково запускають coverage оркестратор з кореня. Якщо в package.json є поля `packageManager`, то прибрати їх, також прибрати всі директорії та файли для yarn.
46
-
47
- - Заборонені top-level поля у root `package.json` (з причинами): [package.json.deny.json](./policy/package_json/template/package.json.deny.json)
48
-
49
- Коли зміна відбувається в Dockerfile, то використовувати
50
-
51
- ```dockerfile
52
- FROM oven/bun:alpine AS build-env
53
- ```
54
-
55
- замість образу node
56
-
57
- У **GitHub Actions** не вставляй у workflow окремі кроки **`actions/setup-node`**, **`oven-sh/setup-bun`**, **`actions/cache`** та **`bun install`** — їх **заборонено** дублювати в кожному job; завжди використовуй **локальний composite** (деталі й заборона дублювання — **ga.mdc**). Під капотом composite уже містить Node **24**, Bun, кеш і **`bun install --frozen-lockfile`**.
58
-
59
- Після **`actions/checkout@v6`** (`persist-credentials: false`):
60
-
61
- ```yaml
62
- - uses: ./.github/actions/setup-bun-deps
63
- ```
64
-
65
- Якщо в репозиторії action збережено під **`./npm/github-actions/setup-bun-deps`**, у `uses:` вкажи цей шлях замість `.github/actions/…` (**ga.mdc**).
66
-
67
- ## lint
68
-
69
- Лінт запускається через CLI **`n-cursor`**, **не** через `package.json`-скрипти:
70
-
71
- - **`n-cursor lint --full`** — весь репо: активні у `.n-cursor.json` правила (per-file + full лінтери за `meta.json#lint` scope, конформність) + `oxfmt` у кінці (fix-режим);
72
- - **`n-cursor lint`** — дельта vs origin (активні у `.n-cursor.json` per-file лінтери лише змінених файлів);
73
- - **`n-cursor lint <rule…>`** — конкретні правила (лінтер + конформність), напр. **`n-cursor lint ga`**.
74
-
75
- У кореневому `package.json` **не повинно бути** `lint`/`lint-*` скриптів — єдина точка лінту — CLI `n-cursor`. У CI кожен workflow викликає **`n-cursor lint <rule> --read-only`** напряму (без обгорток).
22
+ [bun-policy-package_json](./policy/package_json/package_json.mdc)
@@ -0,0 +1,12 @@
1
+ ## Rego-gate: відповідність bunfig.toml канонічному шаблону
2
+
3
+ Rego-пакет: `bun.bunfig`
4
+
5
+ Цільовий файл: `bunfig.toml` (корінь репо).
6
+
7
+ Шаблон (leaf-значення, які gate порівнює): [bunfig.toml.snippet.toml](./template/bunfig.toml.snippet.toml)
8
+
9
+ Gate порівнює кожен leaf-ключ у кожній секції шаблону з фактичним значенням у `bunfig.toml`. Зайві ключі та секції — ігноруються. Deny-повідомлення виникає, якщо:
10
+
11
+ - секція відсутня або не є обʼєктом (`bunfig.toml: відсутня секція [install]`)
12
+ - leaf-ключ має інше значення (`bunfig.toml: у секції [install] має бути linker = "hoisted"`)
@@ -0,0 +1,14 @@
1
+ ## Rego-gate: заборонені поля та devDependencies у кореневому package.json
2
+
3
+ Rego-пакет: `bun.package_json`
4
+
5
+ Цільовий файл: кореневий `package.json`.
6
+
7
+ Список заборонених top-level полів (template-driven): [package.json.deny.json](./template/package.json.deny.json)
8
+
9
+ Gate виносить два класи deny:
10
+
11
+ 1. **Заборонені top-level поля** — будь-яке поле з `package.json.deny.json` присутнє у файлі (навіть із порожнім значенням `{}`).
12
+ 2. **devDependencies не з білого списку** — дозволені лише `@nitra/*` та root-only тестові peer/tools (`vitest`, `@vitest/coverage-v8`, `@stryker-mutator/vitest-runner`, `@playwright/test`). Будь-який інший пакет → deny.
13
+
14
+ Перевірки, що потребують FS або cross-file контексту (наприклад наявність `yarn.lock`), лишаються у JS-шарі.
@@ -0,0 +1,69 @@
1
+ ## iOS: лише SPM, виняток через Podfile
2
+
3
+ ### Правило за замовчуванням
4
+
5
+ Не залишай `Podfile` (поза `Pods/`) у вихідному iOS-шарі, **якщо** уся потрібна
6
+ iOS-функціональність (нативні плагіни/модулі) може працювати **лише** через **SPM** (Swift Package Manager).
7
+
8
+ Перевірка рекурсивно шукає `Podfile` у `ios/`, пропускаючи `Pods/`, `build/`, `DerivedData/`.
9
+
10
+ ### Плагіни @nitra/
11
+
12
+ Плагіни зі скоупу `@nitra/` за політикою **підтримують SPM** — перевіряти їх на SPM **не потрібно**
13
+ (check не обходить `package.json` на предмет `@nitra/`).
14
+
15
+ ### Коли Podfile дозволений
16
+
17
+ Якщо не вся потрібна iOS-функціональність поза `@nitra/` (сторонні Capacitor-плагіни, інша
18
+ нативна залежність) доступна через SPM — `Podfile` дозволяється, але це **обов'язково** треба
19
+ явно задати в кореневому **`package.json`** або в **`capacitor.config.json` / `capacitor.config.ts` / `capacitor.config.mjs`**:
20
+
21
+ - **`"iosCocoaPodsBecausePluginsLackSpm": true`** — семантика: не вся потрібна нативна частина
22
+ поза `@nitra/` на SPM; `@nitra/` у це не входить;
23
+ - або **`"iosCocoaPodsAllowed": true`** — короткий alias для того самого винятку.
24
+
25
+ Без одного з цих прапорів `true` наявний `Podfile` поза `Pods/` вважається порушенням правила «лише SPM».
26
+
27
+ **Де задати виняток у `package.json`:**
28
+
29
+ ```json
30
+ {
31
+ "nitra": {
32
+ "iosCocoaPodsBecausePluginsLackSpm": true
33
+ }
34
+ }
35
+ ```
36
+
37
+ або коротший alias:
38
+
39
+ ```json
40
+ {
41
+ "nitra": {
42
+ "iosCocoaPodsAllowed": true
43
+ }
44
+ }
45
+ ```
46
+
47
+ **Де задати виняток у `capacitor.config.json`:**
48
+
49
+ ```json
50
+ {
51
+ "nitra": {
52
+ "iosCocoaPodsAllowed": true
53
+ }
54
+ }
55
+ ```
56
+
57
+ **Де задати виняток у `capacitor.config.ts` / `capacitor.config.mjs`:**
58
+
59
+ ```ts
60
+ const config = {
61
+ // ...
62
+ nitra: {
63
+ iosCocoaPodsAllowed: true,
64
+ },
65
+ }
66
+ ```
67
+
68
+ Перевірка читає **лише** кореневі файли: `package.json`, потім capacitor-конфіги у корені.
69
+ У `.ts` / `.mjs`: шукається блок `nitra { ... }` і на його тілі перевіряються ці boolean-поля.
@@ -0,0 +1,29 @@
1
+ ## Версія Capacitor
2
+
3
+ У `package.json` (у **корені** репозиторію чи **workspace**-пакеті) оголошення **`@capacitor/core`**
4
+ має вказувати діапазон, **сумісний лише з мажорною версією 8 і вище** (наприклад `^8.0.0`).
5
+ **`*`**, `latest` і діапазони, де можлива 7-мажор, — неприйнятні.
6
+
7
+ Перевірка обходить усі `package.json` у дереві (крім `node_modules`, `.git`, `dist`, `coverage`,
8
+ `Pods`, `.turbo`, `.next`, `build`) і перевіряє нижню межу діапазону через `capacitorVersionRangeMinMajor`.
9
+ Підтримуються `||`-частини, hyphen-range (`7 - 9`), `^`, `~`, `>=`, `>`, `=`, bare-version;
10
+ `workspace:*` / `*` / `x` / `latest` — пропускаються (не блокують).
11
+
12
+ **Приклади допустимих діапазонів:**
13
+
14
+ ```
15
+ "@capacitor/core": "^8.0.0"
16
+ "@capacitor/core": ">=8"
17
+ "@capacitor/core": "8.x"
18
+ "@capacitor/core": "workspace:*"
19
+ ```
20
+
21
+ **Приклади неприйнятних діапазонів:**
22
+
23
+ ```
24
+ "@capacitor/core": "^7.0.0" // мажор 7 — занадто старий
25
+ "@capacitor/core": "*" // будь-яка — неприйнятна
26
+ "@capacitor/core": "latest" // неприйнятна
27
+ "@capacitor/core": ">=6" // нижня межа 6 — занадто старий
28
+ "@capacitor/core": "6 - 9" // hyphen-range: нижня межа 6 — неприйнятна
29
+ ```
@@ -5,30 +5,14 @@ alwaysApply: false
5
5
  version: '1.1'
6
6
  ---
7
7
 
8
- ## Версія Capacitor
8
+ Правило перевіряє версію `@capacitor/core` у `package.json` та коректність використання CocoaPods/SPM у iOS-шарі Capacitor-проєкту.
9
9
 
10
- У `package.json` (у **корені** репозиторію чи **workspace**-пакеті) оголошення **`@capacitor/core`**
11
- має вказувати діапазон, **сумісний лише з мажорною версією 8 і вище** (наприклад `^8.0.0`).
12
- **`*`**, `latest` і діапазони, де можлива 7-мажор, — неприйнятні.
10
+ [capacitor-version](./js/version.mdc)
13
11
 
14
- ## iOS: зазвичай лише SPM, виняток Podfile
12
+ [capacitor-ios-spm](./js/ios_spm.mdc)
15
13
 
16
- - **Правило за замовчуванням:** не залишай `Podfile` (поза `Pods/`) у вихідному iOS-шарі, **якщо** уся потрібна
17
- iOS-функціональність (нативні плагіни/модулі) може працювати **лише** через **SPM** (Swift Package Manager).
14
+ ## Швидкий gate через conftest
18
15
 
19
- - **Плагіни зі скоупу @nitra/:** за політикою вони **підтримуюють SPM**; **перевіряти** їх на **SPM** **не
20
- потрібно** (і **check** цього **не** робить — **немає** обходу `package.json` на предмет **@nitra/**).
16
+ [capacitor-package_json](./policy/package_json/package_json.mdc)
21
17
 
22
- - **Коли `Podfile` дозволений:** якщо **не** вся потрібна iOS-функціональність **поза** **@nitra/** (сторонні
23
- **Capacitor**-плагіни, інша нативна залежність) **доступна** через **SPM** — `Podfile` **дозволяється**,
24
- але це **обов’язково** треба явно задати в кореневому **`package.json`** або в
25
- **`capacitor.config.json` / `capacitor.config.ts` / `capacitor.config.mjs`**
26
-
27
- - **`"iosCocoaPodsBecausePluginsLackSpm": true`** (семантика: **не** **вся** потрібна нативна частина
28
- **поза** **@nitra/** **на** **SPM**; **@nitra/** у це **не** входить);
29
- - або **`"iosCocoaPodsAllowed": true`** (короткий **alias** для того самого **винятку**);
30
-
31
- Без **одного** з цих прапорів `true` наявний **Podfile** поза **`Pods/`** вважається **порушенням** правила **«лише** **SPM**».
32
-
33
- - Перевірка читає **лише** кореневі файли: **`package.json`**, потім **capacitor-конфіги** у **корені** (див. вище).
34
- У **`.ts` / `.mjs`**: шукається блок **nitra** `{ ... }` і **на його тілі** перевіряються ці **boolean**-поля.
18
+ JS-перевірка (`platforms.mjs`) authoritative: підтримує `||`-діапазони, hyphen-range, workspace-monorepo та iOS-специфічну логіку (Podfile).
@@ -0,0 +1,9 @@
1
+ ## Rego-gate: версія `@capacitor/core` у `package.json`
2
+
3
+ Rego-пакет: `capacitor.package_json`
4
+
5
+ Цільовий файл: `package.json` (один файл, `target.json` → `files.single`).
6
+
7
+ Перевіряє наявність `dependencies["@capacitor/core"]` і вимагає, щоб перша мажорна цифра діапазону була ≥ 8. Значення `workspace:*` пропускається без помилки.
8
+
9
+ Спрощений порт JS-логіки: `||`-діапазони та hyphen-range — лише у JS (`fix.mjs`). Цей gate — швидка перевірка одиничного `package.json` (наприклад, через IDE або conftest у CI).
@@ -0,0 +1,15 @@
1
+ ## STOP — перед завершенням відповіді агента
2
+
3
+ > **Якщо в цій сесії ти змінив(ла) файли в пакетному workspace** (код, rego, правила, скіли, скрипти, конфіги, тести — **не** лише `docs/` / `doc/`) — **не завершуй задачу**, поки не виконаєш **усі три** кроки нижче в **тому ж** наборі змін. Це не «опційно після синку» — це частина PR.
4
+
5
+ 1. **Поклади change-файл** `<ws>/.changes/YYMMDD-HHMM.md` з frontmatter `bump:` (`major|minor|patch`) + `section:` (`Added|Changed|Fixed|Removed`) і текстом опису. Команда: `npx @nitra/cursor change --bump <…> --section <…> --message "<…>" [--ws <шлях>]`. Якщо файл за ту саму хвилину вже існує, CLI атомарно створює `YYMMDD-HHMM-2.md`, потім `-3` тощо.
6
+ 2. **Ніколи** не редагуй `version` і `CHANGELOG.md` вручну — навіть для hotfix. Єдиний артефакт зміни — change-файл; `version`/CHANGELOG формує `n-cursor release` у CI на `main` (агрегує change-файли, ставить git-тег `<name>@<version>`). Будь-яка зміна `version` поза CI (drift від бази чи опублікованої) завалює `check changelog` — навіть якщо поряд є change-файл.
7
+ 3. **`npx @nitra/cursor fix changelog`** → exit **`0`** (достатньо наявності change-файлу; `version` лишається незмінним).
8
+
9
+ **Це правило релевантне завжди після будь-якої зміни** коду/конфігу/тестів/воркспейсу — **не** класифікуй його як «лише для релізу». Уже запущені тести чи білд **не** знімають вимогу changelog. Операційно перед фінальною відповіддю: `git status --short` → зіставити змінені шляхи з workspace-ами → change-файл для кожного релевантного workspace → `npx @nitra/cursor fix changelog` (exit `0`). Якщо у фінальній відповіді не можеш заповнити рядок `Changelog: …`, отже ти пропустив(ла) цей крок.
10
+
11
+ **Тригер шляхів (приклади):** `npm/**`, `packages/foo/**`, будь-який каталог з власним `package.json` / `pyproject.toml`, куди потрапили правки.
12
+
13
+ **Інверсія (change-файл не потрібен):** лише `docs/` / `doc/`; синхронізований із `@nitra/cursor` інструментарій (`.cursor/`, `.claude/`); лише `.gitignore`. **Корінь монорепо** (воркспейс `.` за наявності підпакетів) не перевіряється взагалі — отже й кореневі `AGENTS.md` / `CLAUDE.md` та bump `@nitra/cursor` у `devDependencies`. Окремого «релізного кроку» у feature-флоу немає — `version`/`CHANGELOG.md` змінює лише CI.
14
+
15
+ **Pre-commit (людина):** `hk` у цьому репо запускає `fix changelog` при змінах під `npm/**` в **autofix-режимі** (env `N_CURSOR_CHANGELOG_AUTOFIX=1`): за відсутності change-файлу хук **сам** його створює (дефолти `patch`/`Changed`, опис = subject останнього коміту) і ставить у git-індекс, тож коміт не падає. Це лише підстраховка — агент не покладайся на неї: виконуй кроки 1–3 **до** фінальної відповіді, бо автоген ставить осмислений опис лише випадково (subject попереднього коміту), і `bump`/`section`/текст майже завжди треба відредагувати. Autofix-режим також **не робить мережевих викликів** (`npm view` / PyPI fetch пропускаються) — реєстрова drift-перевірка `version` у хуці не виконується (її ловить CI / ручний `fix`). Поза хуком (CI, ручний `fix`/`check`) autofix вимкнено — поведінка лишається fail-on-missing з повною drift-перевіркою.
@@ -0,0 +1,33 @@
1
+ ## Формат CHANGELOG.md
2
+
3
+ [Keep a Changelog 1.1.0](https://keepachangelog.com/uk/1.1.0/), мова — українська, новіші версії зверху.
4
+
5
+ ```md title="<ws>/CHANGELOG.md"
6
+ # Changelog
7
+
8
+ Усі помітні зміни цього пакета документуються тут.
9
+
10
+ Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
11
+
12
+ ## [1.2.3] - 2026-05-05
13
+
14
+ ### Added
15
+
16
+ - ...
17
+
18
+ ### Changed
19
+
20
+ - ...
21
+
22
+ ### Fixed
23
+
24
+ - ...
25
+ ```
26
+
27
+ Секції — підмножина `### Added`, `### Changed`, `### Fixed`, `### Removed` (одна або кілька).
28
+
29
+ ## Post-release інваріант (гарантує CI)
30
+
31
+ Перша (верхня) секція `## [version]` у `CHANGELOG.md` дорівнює полю `version` у маніфесті — але це **post-release** твердження, яке забезпечує `n-cursor release` у CI, агрегуючи change-файли (bump `version` + генерація секції + git-тег `<name>@<version>`). **Локально цю рівність руками не підтримують**: у feature-флоу `version`/`CHANGELOG.md` не чіпають, тож верхня секція може відставати від майбутньої версії — це нормально. Drift `version` поза CI (vs реєстр / vs git-база) ловить `check changelog` як заборонений ручний bump.
32
+
33
+ Інструкції щодо bump `version` і редагування `CHANGELOG.md` живуть **лише** в правилі `changelog` — джерелі істини. Інші правила (зокрема `n-npm-module.mdc`) їй підпорядковані й власних інструкцій bump/CHANGELOG не дублюють.
@@ -0,0 +1,40 @@
1
+ ## Дві моделі бази порівняння
2
+
3
+ Режим визначається автоматично з маніфесту.
4
+
5
+ ### registry-published (npm / PyPI)
6
+
7
+ **npm:** непорожнє `name`, не `private: true`, масив `files`.
8
+
9
+ **Python:** статичні `project.name` і `project.version` у `pyproject.toml` (або Poetry-секція).
10
+
11
+ 1. **Локальна `version` ≠ опублікованій** (npm / PyPI): drift поза CI → **fail** (ручний bump заборонено; навіть із change-файлом). Відкоти `version`.
12
+ 2. **Версії збігаються**, але в git є **релевантні** зміни без change-файлу → fail. Для npm `"CHANGELOG.md"` має бути в `files` (публікується разом із пакетом).
13
+ 3. **Реєстр недосяжний** — fail-safe pass.
14
+ 4. **Немає релевантних змін** — pass.
15
+
16
+ ### local-only
17
+
18
+ **npm:** `private: true` або без `files`. **Python:** без пари name+version для реєстру. База залежить від гілки:
19
+
20
+ 1. На **`dev`** local-only не активний (крім незакомічених registry-published).
21
+ 2. На **`main`** — diff від **`origin/main`** (попередній опублікований `main`); без remote — від `HEAD~1`. **`dev` не використовується** як база на `main`.
22
+ 3. На **feature-гілці** — `merge-base` з **`dev`**, якщо є; інакше з **`main`** (репо без `dev`).
23
+ 4. Drift `version` від бази → **fail** (ручний bump заборонено). Зміни фіксуй change-файлом; bump зробить CI.
24
+
25
+ Якщо немає git або немає `dev`/`main`/`origin/main` — local-only пропускається.
26
+
27
+ ## Чеклист агента (деталі)
28
+
29
+ Повний алгоритм — у блоці **STOP** (changelog-agent-workflow); тут лише уточнення.
30
+
31
+ **Інверсія (за замовчуванням не вимагають change-файлу):**
32
+
33
+ - зміни **лише** під `docs/` або `doc/`;
34
+ - синхронізований із `@nitra/cursor` інструментарій під `.cursor/` (канонічні правила й скіли) і `.claude/` (ADR-хуки) — це дзеркало tooling-пакета, а не логіка воркспейсу;
35
+ - будь-які зміни в **корені монорепо** (воркспейс `.` за наявності підпакетів) — корінь веде glue/конфіг/tooling, власного CHANGELOG не має; помітні зміни документують підпакети. Сюди потрапляють і кореневі `AGENTS.md` / `CLAUDE.md`, і bump `@nitra/cursor` у `devDependencies`;
36
+ - файли під **`.gitignore`**.
37
+
38
+ **Вимагають change-файл** — усі інші зміни в каталозі workspace (код, rego, правила, скіли, конфіги, тести тощо). Виняток `.cursor/` / `.claude/` **не** поширюється на джерело правил у репо `@nitra/cursor` — воно лежить під `npm/`, тож зміни в ньому далі вимагають change-файлу.
39
+
40
+ Перевірка програмна (`changelog/js/consistency.mjs`).
@@ -4,104 +4,10 @@ version: '3.4'
4
4
  alwaysApply: true
5
5
  ---
6
6
 
7
- ## STOPперед завершенням відповіді агента
7
+ У кожному **пакетному** workspace (каталог із `package.json` або `pyproject.toml`) має бути власний **`CHANGELOG.md`**. Спільного на репозиторій змісту змін **не існує** кожен пакет веде свій. Маніфест версії: **JS/Bun/npm** — `package.json` (`version`); **Python** — `pyproject.toml` (`[project].version` або `[tool.poetry].version`).
8
8
 
9
- > **Якщо в цій сесії ти змінив(ла) файли в пакетному workspace** (код, rego, правила, скіли, скрипти, конфіги, тести — **не** лише `docs/` / `doc/`) — **не завершуй задачу**, поки не виконаєш **усі три** кроки нижче в **тому ж** наборі змін. Це не «опційно після синку» — це частина PR.
9
+ [changelog-agent-workflow](./js/agent-workflow.mdc)
10
10
 
11
- 1. **Поклади change-файл** `<ws>/.changes/YYMMDD-HHMM.md` з frontmatter `bump:` (`major|minor|patch`) + `section:` (`Added|Changed|Fixed|Removed`) і текстом опису. Команда: `npx @nitra/cursor change --bump <…> --section <…> --message "<…>" [--ws <шлях>]`. Якщо файл за ту саму хвилину вже існує, CLI атомарно створює `YYMMDD-HHMM-2.md`, потім `-3` тощо.
12
- 2. **Ніколи** не редагуй `version` і `CHANGELOG.md` вручну — навіть для hotfix. Єдиний артефакт зміни — change-файл; `version`/CHANGELOG формує `n-cursor release` у CI на `main` (агрегує change-файли, ставить git-тег `<name>@<version>`). Будь-яка зміна `version` поза CI (drift від бази чи опублікованої) завалює `check changelog` — навіть якщо поряд є change-файл.
13
- 3. **`npx @nitra/cursor fix changelog`** → exit **`0`** (достатньо наявності change-файлу; `version` лишається незмінним).
11
+ [changelog-comparison-models](./js/comparison-models.mdc)
14
12
 
15
- **Це правило релевантне завжди після будь-якої зміни** коду/конфігу/тестів/воркспейсу — **не** класифікуй його як «лише для релізу». Уже запущені тести чи білд **не** знімають вимогу changelog. Операційно перед фінальною відповіддю: `git status --short` → зіставити змінені шляхи з workspace-ами → change-файл для кожного релевантного workspace → `npx @nitra/cursor fix changelog` (exit `0`). Якщо у фінальній відповіді не можеш заповнити рядок `Changelog: …`, отже ти пропустив(ла) цей крок.
16
-
17
- **Тригер шляхів (приклади):** `npm/**`, `packages/foo/**`, будь-який каталог з власним `package.json` / `pyproject.toml`, куди потрапили правки.
18
-
19
- **Інверсія (change-файл не потрібен):** лише `docs/` / `doc/`; синхронізований із `@nitra/cursor` інструментарій (`.cursor/`, `.claude/`); лише `.gitignore`. **Корінь монорепо** (воркспейс `.` за наявності підпакетів) не перевіряється взагалі — отже й кореневі `AGENTS.md` / `CLAUDE.md` та bump `@nitra/cursor` у `devDependencies`. Окремого «релізного кроку» у feature-флоу немає — `version`/`CHANGELOG.md` змінює лише CI.
20
-
21
- **Pre-commit (людина):** `hk` у цьому репо запускає `fix changelog` при змінах під `npm/**` в **autofix-режимі** (env `N_CURSOR_CHANGELOG_AUTOFIX=1`): за відсутності change-файлу хук **сам** його створює (дефолти `patch`/`Changed`, опис = subject останнього коміту) і ставить у git-індекс, тож коміт не падає. Це лише підстраховка — агент не покладайся на неї: виконуй кроки 1–3 **до** фінальної відповіді, бо автоген ставить осмислений опис лише випадково (subject попереднього коміту), і `bump`/`section`/текст майже завжди треба відредагувати. Autofix-режим також **не робить мережевих викликів** (`npm view` / PyPI fetch пропускаються) — реєстрова drift-перевірка `version` у хуці не виконується (її ловить CI / ручний `fix`). Поза хуком (CI, ручний `fix`/`check`) autofix вимкнено — поведінка лишається fail-on-missing з повною drift-перевіркою.
22
-
23
- ---
24
-
25
- У кожному **пакетному** workspace (каталог із `package.json` або `pyproject.toml`) має бути власний **`CHANGELOG.md`**. Спільного на репозиторій змісту змін **не існує** — кожен пакет веде свій.
26
-
27
- **Маніфест версії:**
28
-
29
- - **JS / Bun / npm** — `<ws>/package.json` (`version`, для монорепо ще `workspaces` у кореневому `package.json`).
30
- - **Python** — `<ws>/pyproject.toml`: `[project].name` / `[project].version` (PEP 621) або `[tool.poetry].name` / `[tool.poetry].version`.
31
-
32
- Каталоги лише з `pyproject.toml` (без `package.json`) теж враховуються; `node_modules/`, `.venv/`, `venv/` при пошуку ігноруються.
33
-
34
- ## Чеклист агента (деталі)
35
-
36
- Повний алгоритм — у блоці **STOP** вище; тут лише уточнення.
37
-
38
- **Інверсія (за замовчуванням не вимагають change-файлу):**
39
-
40
- - зміни **лише** під `docs/` або `doc/`;
41
- - синхронізований із `@nitra/cursor` інструментарій під `.cursor/` (канонічні правила та скіли) і `.claude/` (ADR-хуки) — це дзеркало tooling-пакета, а не логіка воркспейсу;
42
- - будь-які зміни в **корені монорепо** (воркспейс `.` за наявності підпакетів) — корінь веде glue/конфіг/tooling, власного CHANGELOG не має; помітні зміни документують підпакети. Сюди потрапляють і кореневі `AGENTS.md` / `CLAUDE.md`, і bump `@nitra/cursor` у `devDependencies`;
43
- - файли під **`.gitignore`**.
44
-
45
- **Вимагають change-файл** — усі інші зміни в каталозі workspace (код, rego, правила, скіли, конфіги, тести тощо). Виняток `.cursor/` / `.claude/` **не** поширюється на джерело правил у репо `@nitra/cursor` — воно лежить під `npm/`, тож зміни в ньому далі вимагають change-файлу.
46
-
47
- Перевірка програмна (`changelog/js/consistency.mjs`).
48
-
49
- ## Дві моделі бази порівняння
50
-
51
- Режим визначається автоматично з маніфесту.
52
-
53
- ### registry-published (npm / PyPI)
54
-
55
- **npm:** непорожнє `name`, не `private: true`, масив `files`.
56
-
57
- **Python:** статичні `project.name` і `project.version` у `pyproject.toml` (або Poetry-секція).
58
-
59
- 1. **Локальна `version` ≠ опублікованій** (npm / PyPI): drift поза CI → **fail** (ручний bump заборонено; навіть із change-файлом). Відкоти `version`.
60
- 2. **Версії збігаються**, але в git є **релевантні** зміни без change-файлу → fail. Для npm `"CHANGELOG.md"` має бути в `files` (публікується разом із пакетом).
61
- 3. **Реєстр недосяжний** — fail-safe pass.
62
- 4. **Немає релевантних змін** — pass.
63
-
64
- ### local-only
65
-
66
- **npm:** `private: true` або без `files`. **Python:** без пари name+version для реєстру. База залежить від гілки:
67
-
68
- 1. На **`dev`** local-only не активний (крім незакомічених registry-published).
69
- 2. На **`main`** — diff від **`origin/main`** (попередній опублікований `main`); без remote — від `HEAD~1`. **`dev` не використовується** як база на `main`.
70
- 3. На **feature-гілці** — `merge-base` з **`dev`**, якщо є; інакше з **`main`** (репо без `dev`).
71
- 4. Drift `version` від бази → **fail** (ручний bump заборонено). Зміни фіксуй change-файлом; bump зробить CI.
72
-
73
- Якщо немає git або немає `dev`/`main`/`origin/main` — local-only пропускається.
74
-
75
- ## Формат CHANGELOG.md
76
-
77
- [Keep a Changelog 1.1.0](https://keepachangelog.com/uk/1.1.0/), мова — українська, новіші версії зверху.
78
-
79
- ```md title="<ws>/CHANGELOG.md"
80
- # Changelog
81
-
82
- Усі помітні зміни цього пакета документуються тут.
83
-
84
- Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
85
-
86
- ## [1.2.3] - 2026-05-05
87
-
88
- ### Added
89
-
90
- - ...
91
-
92
- ### Changed
93
-
94
- - ...
95
-
96
- ### Fixed
97
-
98
- - ...
99
- ```
100
-
101
- Секції — підмножина `### Added`, `### Changed`, `### Fixed`, `### Removed` (одна або кілька).
102
-
103
- ## Post-release інваріант (гарантує CI)
104
-
105
- Перша (верхня) секція `## [version]` у `CHANGELOG.md` дорівнює полю `version` у маніфесті — але це **post-release** твердження, яке забезпечує `n-cursor release` у CI, агрегуючи change-файли (bump `version` + генерація секції + git-тег `<name>@<version>`). **Локально цю рівність руками не підтримують**: у feature-флоу `version`/`CHANGELOG.md` не чіпають, тож верхня секція може відставати від майбутньої версії — це нормально. Drift `version` поза CI (vs реєстр / vs git-база) ловить `check changelog` як заборонений ручний bump.
106
-
107
- Інструкції щодо bump `version` і редагування `CHANGELOG.md` живуть **лише** в цьому правилі — джерелі істини. Інші правила (зокрема `n-npm-module.mdc`) їй підпорядковані й власних інструкцій bump/CHANGELOG не дублюють.
13
+ [changelog-format](./js/changelog-format.mdc)
@@ -0,0 +1,31 @@
1
+ ## Конфіг marksman LSP (`.marksman.toml`)
2
+
3
+ Правило перевіряє наявність `.marksman.toml` у корені проєкту. Якщо файл відсутній — автоматично створює його з canonical baseline, що постачається разом із пакетом (`js/data/marksman_config/marksman.baseline.toml`). Повторні прогони ідемпотентні: існуючий файл не перетирається, ручні правки зберігаються.
4
+
5
+ ### Baseline-конфіг
6
+
7
+ Canonical baseline ([data/marksman_config/marksman.baseline.toml](./data/marksman_config/marksman.baseline.toml)) містить такі налаштування:
8
+
9
+ ```toml
10
+ [core]
11
+ markdown.file_extensions = ["md", "markdown"]
12
+ markdown.glfm = true # GitHub-Flavored Markdown (таблиці, todo, alerts)
13
+
14
+ [completion]
15
+ wiki.style = "file-stem" # [[oidc-pkce-flow]] → docs/adr/oidc-pkce-flow.md
16
+
17
+ [code_action]
18
+ toc.enable = true # «Insert/Update TOC» для довгих arc42-сторінок
19
+ ```
20
+
21
+ **Чому `file-stem`?** ADR-slug збігається з іменем файлу — стабільний ідентифікатор у AUTOGEN `sources`, `manifest.json` і валідаторі. Якщо заголовок ADR змінюється, посилання `[[wiki-link]]` не ламається. Без явного конфіга marksman використовує `title-slug-ref` і вимкнений GLFM — частина задокументованої навігації працювала б інакше.
22
+
23
+ ### Поведінка перевірки
24
+
25
+ | Стан | Результат |
26
+ | ----------------------------- | -------------------------------------------------- |
27
+ | baseline-файл пакета відсутній | `fail` — перевстанови `@nitra/cursor` |
28
+ | `.marksman.toml` вже існує | `pass` — файл не чіпається |
29
+ | `.marksman.toml` відсутній | створює файл з baseline, `pass` |
30
+
31
+ Перевірка запускається як `check`-поверхня; `lint`-поверхні правило не має.
@@ -0,0 +1,33 @@
1
+ ## Рекомендовані розширення VSCode (`.vscode/extensions.json`)
2
+
3
+ Правило перевіряє, що `.vscode/extensions.json` містить усі обовʼязкові записи з канонічного шаблону. Перевірка реалізована через Rego (пакет `ci4.vscode_extensions`) і запускається `conftest` у фазі `check`.
4
+
5
+ ### Канонічний шаблон
6
+
7
+ Канон надходить через `--data` як `{ "template": { "snippet": ... } }`. Поточний snippet ([policy/vscode_extensions/template/extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)):
8
+
9
+ ```json
10
+ {
11
+ "recommendations": ["arr.marksman"]
12
+ }
13
+ ```
14
+
15
+ `arr.marksman` — офіційне VSCode-розширення marksman LSP. Дає ту саму навігацію `cmd+click` / `[[wiki-link]]` / find-references / refactor-перейменування, що й Zed built-in marksman, для контрибʼюторів поза Zed.
16
+
17
+ ### Rego-логіка
18
+
19
+ Для кожного запису з `data.template.snippet.recommendations` перевіряє, що він присутній у `input.recommendations`. Якщо запис відсутній — deny з повідомленням:
20
+
21
+ ```
22
+ .vscode/extensions.json: recommendations має містити "arr.marksman" (ci4.mdc)
23
+ ```
24
+
25
+ ### Приклад коректного файлу
26
+
27
+ ```json title=".vscode/extensions.json"
28
+ {
29
+ "recommendations": ["arr.marksman"]
30
+ }
31
+ ```
32
+
33
+ Інші розширення в масиві `recommendations` дозволені — перевірка лише на наявність обовʼязкових, без виключення додаткових.
@@ -4,9 +4,7 @@ alwaysApply: true
4
4
  version: '3.2'
5
5
  ---
6
6
 
7
- Архітектурна документація проєкту живе у Markdown поряд із кодом. Це не довідник «для людей із порталу архітектора» — це **джерело істини**, з якого LLM-агент і людина читають намір системи перед будь-якою зміною коду. Тому правила нижче — не оформлення, а робочий процес: який стек використовуємо, як зберігаємо рішення, як автоматично перегенеровуємо проекції з ADR і як рендеримо для змішаної аудиторії (менеджери + інженери + ops).
8
-
9
- Формат самих ADR-файлів — MADR v4.0.0 minimal — описаний у правилі **`adr`** (`npm/rules/adr/adr.mdc`). Тут описано, як ADR використовуються як вхід для архітектурних проекцій, а не як вони створюються.
7
+ Архітектурна документація проєкту живе у Markdown поряд із кодом — це **джерело істини**, з якого LLM-агент і людина читають намір системи перед будь-якою зміною коду. Правила нижче — не оформлення, а робочий процес: який стек використовуємо, як зберігаємо рішення, як автоматично перегенеровуємо проекції з ADR і як рендеримо для змішаної аудиторії (менеджери + інженери + ops). Формат самих ADR-файлів — MADR v4.0.0 minimal — описаний у правилі **`adr`** (`npm/rules/adr/adr.mdc`).
10
8
 
11
9
  ## Markdown як джерело істини
12
10
 
@@ -208,17 +206,7 @@ User Service відповідає за автентифікацію та про
208
206
  }
209
207
  ```
210
208
 
211
- **`.marksman.toml`** у корені проєкту авто-створюється правилом ci4 при першому `npx @nitra/cursor fix ci4` із canonical baseline ([data/marksman_config/marksman.baseline.toml](./js/data/marksman_config/marksman.baseline.toml)). Ключові опції`markdown.glfm = true` (потрібен для GFM-alerts/таблиць/todo з portable subset), `[completion] wiki.style = "file-stem"` (ADR slug == ім'я файла, стабільний ідентифікатор у AUTOGEN `sources`/manifest/валідаторі — заголовок змінюється, посилання не ламається), `[code_action] toc.enable = true` (TOC code action для довгих arc42-сторінок). Без явного конфіга marksman використовує `title-slug-ref` і вимкнений GLFM — частина задокументованої навігації працювала б інакше. Ручні правки конфіга не перетираються — `ensureBaselineFile` ідемпотентний.
212
-
213
- **VSCode-альтернатива.** Контрибʼютори, що працюють у VSCode/Cursor замість Zed, отримують той самий шар навігації через офіційне розширення marksman LSP. Канонічний запис у `.vscode/extensions.json`:
214
-
215
- ```json title=".vscode/extensions.json"
216
- {
217
- "recommendations": ["arr.marksman"]
218
- }
219
- ```
220
-
221
- Канон `recommendations` (substring requirement): [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json). Інші marksman-сумісні редактори (Neovim, Helix, Emacs) налаштовують `marksman` як LSP-сервер за документацією свого редактора — поведінка ідентична (cmd+click по `[link](file.md)`/`[[wiki-link]]`, find-references, refactor-перейменування).
209
+ Деталі конфігурації `.marksman.toml` та VSCode-альтернативи — у відповідних секціях нижче.
222
210
 
223
211
  **Portable-only синтаксис.** Усе, що пишемо в `docs/`, обмежене **CommonMark + GFM + Mermaid у fenced code (` ```mermaid `) + KaTeX (`$...$`) + нативний HTML5 `<details>`**. Заборонено:
224
212
 
@@ -375,3 +363,17 @@ ADR (`docs/adr/<slug>.md`) — джерело правди для autogen-про
375
363
  ## Query mode як бонус
376
364
 
377
365
  Поверх проекцій — інтерактивний RAG над clean ADR. Інженер питає: «чому ми обрали Percona замість MariaDB?». LLM шукає по semantic index `Context and Problem Statement + Decision Outcome`, повертає `docs/adr/<slug>.md` з прямою цитатою. Корпус малий (десятки-сотні clean ADR після normalize) і структурований (фіксовані MADR-заголовки) — дешево й точно, без галюцинацій.
366
+
367
+ ## Швидкий gate через conftest
368
+
369
+ Rego-перевірки, що запускаються через `conftest` у фазі `check`:
370
+
371
+ | Пакет | Що перевіряє |
372
+ | --------------------------- | -------------------------------------------------------------------- |
373
+ | `ci4.vscode_extensions` | `.vscode/extensions.json` містить `arr.marksman` у `recommendations` |
374
+
375
+ [ci4-marksman_config](./js/marksman_config.mdc)
376
+
377
+ [ci4-vscode_extensions](./js/vscode_extensions.mdc)
378
+
379
+ [ci4-vscode_extensions-policy](./policy/vscode_extensions/vscode_extensions.mdc)
@@ -0,0 +1,9 @@
1
+ ## Rego-gate: обовʼязкові розширення VSCode
2
+
3
+ Rego-пакет: `ci4.vscode_extensions`
4
+
5
+ Цільовий файл: `.vscode/extensions.json`
6
+
7
+ Перевіряє, що кожен запис з `data.template.snippet.recommendations` присутній у `input.recommendations`. Канонічний шаблон надходить через `--data` у conftest: [extensions.json.snippet.json](./template/extensions.json.snippet.json)
8
+
9
+ Додаткові розширення в масиві дозволені — deny лише на відсутність обовʼязкових.