@nitra/cursor 12.8.7 → 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.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/rules/abie/main.mdc +9 -5
- package/rules/abie/policy/base_deployment_preem/base_deployment_preem.mdc +22 -0
- package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
- package/rules/abie/policy/health_check_policy/health_check_policy.mdc +17 -0
- package/rules/abie/policy/http_route_base/http_route_base.mdc +9 -0
- package/rules/abie/policy/package_json_shared/package_json_shared.mdc +17 -0
- package/rules/adr/main.mdc +4 -0
- package/rules/adr/policy/settings_json/settings_json.mdc +7 -0
- package/rules/adr/policy/settings_local_json/settings_local_json.mdc +7 -0
- package/rules/bun/main.mdc +3 -4
- package/rules/bun/policy/bunfig/bunfig.mdc +12 -0
- package/rules/bun/policy/package_json/package_json.mdc +14 -0
- package/rules/capacitor/main.mdc +1 -3
- package/rules/capacitor/policy/package_json/package_json.mdc +9 -0
- package/rules/ci4/main.mdc +2 -0
- package/rules/ci4/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/docker/main.mdc +1 -3
- package/rules/docker/policy/lint_docker_yml/lint_docker_yml.mdc +14 -0
- package/rules/efes/main.mdc +1 -1
- package/rules/efes/policy/package_json_shared/package_json_shared.mdc +30 -0
- package/rules/ga/main.mdc +15 -10
- package/rules/ga/policy/clean_ga_workflows/clean_ga_workflows.mdc +18 -0
- package/rules/ga/policy/clean_merged_branch/clean_merged_branch.mdc +22 -0
- package/rules/ga/policy/git_ai/git_ai.mdc +19 -0
- package/rules/ga/policy/lint_ga/lint_ga.mdc +21 -0
- package/rules/ga/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/ga/policy/vscode_settings/vscode_settings.mdc +9 -0
- package/rules/ga/policy/workflow_common/workflow_common.mdc +18 -0
- package/rules/ga/policy/zizmor_yml/zizmor_yml.mdc +9 -0
- package/rules/graphql/main.mdc +2 -0
- package/rules/graphql/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/hasura/main.mdc +1 -3
- package/rules/hasura/policy/svc_hl/svc_hl.mdc +15 -0
- package/rules/image-avif/main.mdc +1 -3
- package/rules/image-avif/policy/package_json/package_json.mdc +18 -0
- package/rules/image-compress/main.mdc +1 -1
- package/rules/image-compress/policy/package_json/package_json.mdc +13 -0
- package/rules/js/main.mdc +7 -6
- package/rules/js/policy/jscpd/jscpd.mdc +14 -0
- package/rules/js/policy/lint_js_yml/lint_js_yml.mdc +14 -0
- package/rules/js/policy/package_json/package_json.mdc +15 -0
- package/rules/js/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/js-bun-db/main.mdc +1 -6
- package/rules/js-bun-db/policy/package_json/package_json.mdc +17 -0
- package/rules/js-bun-redis/main.mdc +2 -0
- package/rules/js-bun-redis/policy/package_json/package_json.mdc +11 -0
- package/rules/js-mssql/main.mdc +1 -1
- package/rules/js-mssql/policy/package_json/package_json.mdc +9 -0
- package/rules/js-run/main.mdc +5 -3
- package/rules/js-run/policy/configmap/configmap.mdc +31 -0
- package/rules/js-run/policy/jsconfig/jsconfig.mdc +25 -0
- package/rules/js-run/policy/package_json/package_json.mdc +38 -0
- package/rules/k8s/main.mdc +21 -13
- package/rules/k8s/policy/base_kustomization/base_kustomization.mdc +12 -0
- package/rules/k8s/policy/base_manifest/base_manifest.mdc +14 -0
- package/rules/k8s/policy/gateway/gateway.mdc +17 -0
- package/rules/k8s/policy/hasura_configmap/hasura_configmap.mdc +20 -0
- package/rules/k8s/policy/hasura_httproute/hasura_httproute.mdc +16 -0
- package/rules/k8s/policy/hpa_pdb/hpa_pdb.mdc +23 -0
- package/rules/k8s/policy/kustomization/kustomization.mdc +20 -0
- package/rules/k8s/policy/manifest/manifest.mdc +17 -0
- package/rules/k8s/policy/network_policy/network_policy.mdc +22 -0
- package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
- package/rules/k8s/policy/svc_yaml/svc_yaml.mdc +12 -0
- package/rules/nginx-default-tpl/main.mdc +4 -0
- package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings.mdc +15 -0
- package/rules/npm-module/main.mdc +6 -3
- package/rules/npm-module/policy/emit_types_config/emit_types_config.mdc +40 -0
- package/rules/npm-module/policy/npm_package_json/npm_package_json.mdc +50 -0
- package/rules/npm-module/policy/root_package_json/root_package_json.mdc +37 -0
- package/rules/php/main.mdc +1 -3
- package/rules/php/policy/lint_php_yml/lint_php_yml.mdc +21 -0
- package/rules/python/main.mdc +3 -4
- package/rules/python/policy/lint_python_yml/lint_python_yml.mdc +12 -0
- package/rules/python/policy/pyproject_toml/pyproject_toml.mdc +13 -0
- package/rules/rego/main.mdc +4 -0
- package/rules/rego/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/rego/policy/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/rust/main.mdc +2 -2
- package/rules/rust/policy/lint_rust_yml/lint_rust_yml.mdc +12 -0
- package/rules/rust/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/security/main.mdc +3 -2
- package/rules/security/policy/lint_security_yml/lint_security_yml.mdc +7 -0
- package/rules/security/policy/package_json/package_json.mdc +7 -0
- package/rules/style/main.mdc +6 -5
- package/rules/style/policy/lint_style_yml/lint_style_yml.mdc +13 -0
- package/rules/style/policy/package_json/package_json.mdc +18 -0
- package/rules/style/policy/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/style/policy/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/tauri/main.mdc +1 -3
- package/rules/tauri/policy/vscode_extensions/vscode_extensions.mdc +21 -0
- package/rules/test/main.mdc +1 -3
- package/rules/test/policy/package_json/package_json.mdc +16 -0
- package/rules/text/main.mdc +13 -7
- package/rules/text/policy/cspell/cspell.mdc +34 -0
- package/rules/text/policy/lint_text/lint_text.mdc +19 -0
- package/rules/text/policy/markdownlint/markdownlint.mdc +38 -0
- package/rules/text/policy/oxfmtrc/oxfmtrc.mdc +11 -0
- package/rules/text/policy/package_json/package_json.mdc +33 -0
- package/rules/text/policy/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/text/policy/vscode_settings/vscode_settings.mdc +13 -0
- package/rules/vue/main.mdc +1 -3
- package/rules/vue/policy/package_json/package_json.mdc +30 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/rules/abie/main.mdc
CHANGED
|
@@ -48,11 +48,15 @@ bun add -d @nitra/abie-shared
|
|
|
48
48
|
|
|
49
49
|
Пакети (директорія в **`npm/policy/abie/`** → namespace → що перевіряє):
|
|
50
50
|
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
[abie-http-route-base](./policy/http_route_base/http_route_base.mdc)
|
|
52
|
+
|
|
53
|
+
[abie-health-check-policy](./policy/health_check_policy/health_check_policy.mdc)
|
|
54
|
+
|
|
55
|
+
[abie-base-deployment-preem](./policy/base_deployment_preem/base_deployment_preem.mdc)
|
|
56
|
+
|
|
57
|
+
[abie-clean-merged-ignore-branches](./policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc)
|
|
58
|
+
|
|
59
|
+
[abie-package-json-shared](./policy/package_json_shared/package_json_shared.mdc)
|
|
56
60
|
|
|
57
61
|
Cross-file / FS-логіка лишається у JS-частинах (`js/<concern>.mjs`) — Rego не читає файлову систему й не робить cross-document резолюцію:
|
|
58
62
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Rego: `nodeSelector.preem` у base-Deployment
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `abie.base_deployment_preem`
|
|
4
|
+
|
|
5
|
+
Цільові файли: YAML-маніфести Deployment під `…/k8s/.../base/…`.
|
|
6
|
+
|
|
7
|
+
Перевіряє, що кожен `Deployment` має `spec.template.spec.nodeSelector.preem` зі значенням `true` (boolean `true` або рядок `"true"` — без урахування регістру, з обрізаними пробілами). Значення `false` або відсутність ключа — deny.
|
|
8
|
+
|
|
9
|
+
ua-overlay далі підміняє це значення на `preem: false` через JSON6902-патч (`js/ua_node_selector.mjs`). Cross-document перевірка ua-патча — поза Rego.
|
|
10
|
+
|
|
11
|
+
```yaml title="…/k8s/base/deployment.yaml (фрагмент)"
|
|
12
|
+
spec:
|
|
13
|
+
template:
|
|
14
|
+
spec:
|
|
15
|
+
nodeSelector:
|
|
16
|
+
preem: "true" # ✓ або boolean true
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
nodeSelector:
|
|
21
|
+
role: worker # ✗ preem відсутній
|
|
22
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Rego: `ignore_branches` у `clean-merged-branch.yml`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `abie.clean_merged_ignore_branches`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.github/workflows/clean-merged-branch.yml`.
|
|
6
|
+
|
|
7
|
+
Перевіряє, що у workflow-файлі є крок з `uses: phpdocker-io/github-actions-delete-abandoned-branches` і що його `with.ignore_branches` містить обидва токени `dev` та `ua` (case-insensitive, пробіли навколо токенів обрізаються). Токени зчитуються з template-файлу `data.template.snippet` — зміна канону автоматично змінює вимоги.
|
|
8
|
+
|
|
9
|
+
Канонічний snippet: [clean-merged-branch.yml.snippet.yml](./template/clean-merged-branch.yml.snippet.yml)
|
|
10
|
+
|
|
11
|
+
```yaml title=".github/workflows/clean-merged-branch.yml (фрагмент)"
|
|
12
|
+
- uses: phpdocker-io/github-actions-delete-abandoned-branches@v2
|
|
13
|
+
with:
|
|
14
|
+
ignore_branches: "dev,ua,main" # ✓ містить dev та ua
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
ignore_branches: "main" # ✗ не вистачає dev,ua
|
|
19
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Rego: структура `HealthCheckPolicy` у `hc.yaml`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `abie.health_check_policy`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `…/k8s/.../hc.yaml`.
|
|
6
|
+
|
|
7
|
+
Перевіряє для `kind: HealthCheckPolicy` (з `apiVersion` що починається на `networking.gke.io/`):
|
|
8
|
+
|
|
9
|
+
- `apiVersion` — точно `networking.gke.io/v1`;
|
|
10
|
+
- `metadata.name` — непорожній рядок;
|
|
11
|
+
- `spec.default.config.type` — `HTTP`;
|
|
12
|
+
- `spec.default.config.httpHealthCheck.requestPath` — непорожній, починається з `/`;
|
|
13
|
+
- `spec.default.config.httpHealthCheck.port` — `8080`;
|
|
14
|
+
- `spec.targetRef.kind` — `Service`;
|
|
15
|
+
- `spec.targetRef.name` — `<metadata.name>-hl` (якщо `metadata.name` вже закінчується на `-hl` — використовується як є).
|
|
16
|
+
|
|
17
|
+
FS-парність HCP↔Deployment та modeline `$schema` у `hc.yaml` — поза Rego, у `js/hc_pairing.mjs`. JS-опис структури та приклад — у `js/hc_pairing.mdc`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Rego: `HTTPRoute` у base-шарі — домени `aiml.live`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `abie.http_route_base`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `…/k8s/.../base/.../*.yaml` типу HTTPRoute.
|
|
6
|
+
|
|
7
|
+
Перевіряє, що кожен hostname у `spec.hostnames` належить до домену `aiml.live`: точна відповідність `aiml.live`, wildcard `*.aiml.live` або будь-який піддомен `*.aiml.live`. Перевірка case-insensitive. Не є HTTPRoute — пакет не діє.
|
|
8
|
+
|
|
9
|
+
JS-частина (cross-file аналіз ua-overlay, backendRefs, тощо) — у `js/ua_http_route.mjs`. Людинозрозумілий опис + приклади — у `js/http_route_base.mdc`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Rego: `@nitra/abie-shared` у `devDependencies`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `abie.package_json_shared`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `package.json` (кореневий).
|
|
6
|
+
|
|
7
|
+
Перевіряє presence-only: `devDependencies` має містити ключ `@nitra/abie-shared`. Версію не фіксує. Якщо ключ є лише у `dependencies` (не `devDependencies`) — deny.
|
|
8
|
+
|
|
9
|
+
JS-опис та інструкція встановлення — у секції «`@nitra/abie-shared` у `devDependencies`» в `main.mdc`.
|
|
10
|
+
|
|
11
|
+
```json title="package.json (фрагмент)"
|
|
12
|
+
{
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@nitra/abie-shared": "^1.0.0" // ✓
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
package/rules/adr/main.mdc
CHANGED
|
@@ -78,4 +78,8 @@ Cursor Agent читає project-level **`.cursor/hooks.json`**. `npx @nitra/curs
|
|
|
78
78
|
|
|
79
79
|
[adr-settings-policy](./js/settings_policy.mdc)
|
|
80
80
|
|
|
81
|
+
[adr-settings_json-policy](./policy/settings_json/settings_json.mdc)
|
|
82
|
+
|
|
83
|
+
[adr-settings_local_json-policy](./policy/settings_local_json/settings_local_json.mdc)
|
|
84
|
+
|
|
81
85
|
[adr-hooks](./js/hooks.mdc)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## Наявність ADR Stop-хуків у `.claude/settings.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `adr.settings_json`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.claude/settings.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє, що project-shared файл містить **обидва** managed Stop-хуки — `capture-decisions.sh` і `normalize-decisions.sh` — у `hooks.Stop[*].hooks[*].command`. Помилка, якщо маркер будь-якого зі скриптів відсутній.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## Відсутність дублів ADR Stop-хуків у `.claude/settings.local.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `adr.settings_local_json`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.claude/settings.local.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє **зворотне** до `adr.settings_json`: local-файл **не повинен** містити маркерів `capture-decisions.sh` або `normalize-decisions.sh` у `hooks.Stop[*].hooks[*].command` — інакше кожен скрипт виконається двічі на одну Stop-подію.
|
package/rules/bun/main.mdc
CHANGED
|
@@ -17,7 +17,6 @@ version: '2.1'
|
|
|
17
17
|
|
|
18
18
|
## Швидкий gate через conftest
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| `bun.package_json` | Заборонені top-level поля у root `package.json`; `devDependencies` лише `@nitra/*` + root-only test peers |
|
|
20
|
+
[bun-policy-bunfig](./policy/bunfig/bunfig.mdc)
|
|
21
|
+
|
|
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-шарі.
|
package/rules/capacitor/main.mdc
CHANGED
|
@@ -13,8 +13,6 @@ version: '1.1'
|
|
|
13
13
|
|
|
14
14
|
## Швидкий gate через conftest
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|---|---|
|
|
18
|
-
| `capacitor.package_json` | версія `@capacitor/core` у `dependencies` — мінімум major 8 (спрощений JS-порт для одиничного `package.json`) |
|
|
16
|
+
[capacitor-package_json](./policy/package_json/package_json.mdc)
|
|
19
17
|
|
|
20
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).
|
package/rules/ci4/main.mdc
CHANGED
|
@@ -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 лише на відсутність обовʼязкових.
|
package/rules/docker/main.mdc
CHANGED
|
@@ -15,9 +15,7 @@ alwaysApply: false
|
|
|
15
15
|
|
|
16
16
|
## Швидкий gate через conftest
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|---|---|
|
|
20
|
-
| `docker.lint_docker_yml` | `.github/workflows/lint-docker.yml` відповідає канонічному сніпету (paths, uses, run-підрядки) |
|
|
18
|
+
[docker-lint_docker_yml](./policy/lint_docker_yml/lint_docker_yml.mdc)
|
|
21
19
|
|
|
22
20
|
[docker-mirror](./js/mirror.mdc)
|
|
23
21
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Перевірка `.github/workflows/lint-docker.yml`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `docker.lint_docker_yml`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.github/workflows/lint-docker.yml`
|
|
6
|
+
|
|
7
|
+
Перевіряє, що CI-workflow lint-docker відповідає канонічному сніпету:
|
|
8
|
+
|
|
9
|
+
- `on.push.paths` містить усі три glob-маски: `**/Dockerfile`, `**/*.Dockerfile`, `**/*.dockerfile`
|
|
10
|
+
- присутні кроки `uses: actions/checkout@v6` та `uses: ./.github/actions/setup-bun-deps`
|
|
11
|
+
- крок install hadolint містить рядок із версією `v2.12.0` (substring-перевірка)
|
|
12
|
+
- крок lint містить `n-cursor lint docker --read-only`
|
|
13
|
+
|
|
14
|
+
Канонічний шаблон: [lint-docker.yml.snippet.yml](./template/lint-docker.yml.snippet.yml)
|
package/rules/efes/main.mdc
CHANGED
|
@@ -20,4 +20,4 @@ bun add -d @nitra/efes-shared
|
|
|
20
20
|
|
|
21
21
|
Пакети (директорія в **`npm/rules/efes/policy/`** → namespace → що перевіряє):
|
|
22
22
|
|
|
23
|
-
-
|
|
23
|
+
[efes-package_json_shared](./policy/package_json_shared/package_json_shared.mdc)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
## Наявність `@nitra/efes-shared` у `devDependencies`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `efes.package_json_shared`
|
|
4
|
+
|
|
5
|
+
**Цільовий файл:** `package.json` (корінь проєкту, обовʼязковий).
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:** у `devDependencies` кореневого `package.json` має бути ключ `@nitra/efes-shared`. Версію не фіксуємо — лише presence. Наявність лише у `dependencies` (не `devDependencies`) — теж помилка.
|
|
8
|
+
|
|
9
|
+
**Виправлення:**
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add -d @nitra/efes-shared
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Приклади:**
|
|
16
|
+
|
|
17
|
+
✓ правильно — `devDependencies` містить пакет:
|
|
18
|
+
```json
|
|
19
|
+
{ "devDependencies": { "@nitra/efes-shared": "^1.0.0" } }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
✗ неправильно — `devDependencies` відсутній або порожній:
|
|
23
|
+
```json
|
|
24
|
+
{ "name": "my-project" }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
✗ неправильно — пакет лише у `dependencies`:
|
|
28
|
+
```json
|
|
29
|
+
{ "dependencies": { "@nitra/efes-shared": "^1.0.0" } }
|
|
30
|
+
```
|
package/rules/ga/main.mdc
CHANGED
|
@@ -21,13 +21,18 @@ alwaysApply: false
|
|
|
21
21
|
|
|
22
22
|
## Швидкий gate через conftest
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
|
|
24
|
+
[ga-workflow_common](./policy/workflow_common/workflow_common.mdc)
|
|
25
|
+
|
|
26
|
+
[ga-clean_ga_workflows](./policy/clean_ga_workflows/clean_ga_workflows.mdc)
|
|
27
|
+
|
|
28
|
+
[ga-clean_merged_branch](./policy/clean_merged_branch/clean_merged_branch.mdc)
|
|
29
|
+
|
|
30
|
+
[ga-lint_ga](./policy/lint_ga/lint_ga.mdc)
|
|
31
|
+
|
|
32
|
+
[ga-git_ai](./policy/git_ai/git_ai.mdc)
|
|
33
|
+
|
|
34
|
+
[ga-vscode_extensions](./policy/vscode_extensions/vscode_extensions.mdc)
|
|
35
|
+
|
|
36
|
+
[ga-vscode_settings](./policy/vscode_settings/vscode_settings.mdc)
|
|
37
|
+
|
|
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)
|
package/rules/graphql/main.mdc
CHANGED
|
@@ -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\`…\`` у джерелах проєкту.
|
package/rules/hasura/main.mdc
CHANGED
|
@@ -15,6 +15,4 @@ alwaysApply: false
|
|
|
15
15
|
|
|
16
16
|
## Швидкий gate через conftest
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|---|---|---|
|
|
20
|
-
| `hasura.svc_hl` | `policy/svc_hl/svc_hl.rego` | Іменування headless/clusterIP Service: суфікси `-h-hl` та `-h` |
|
|
18
|
+
[hasura-svc_hl](./policy/svc_hl/svc_hl.mdc)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Rego-gate: іменування headless та clusterIP Service
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `hasura.svc_hl`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `hasura/k8s/base/svc.yaml`, `hasura/k8s/base/svc-hl.yaml`
|
|
6
|
+
|
|
7
|
+
Перевіряє два правила іменування Kubernetes Service:
|
|
8
|
+
|
|
9
|
+
- **Headless Service** (`spec.clusterIP: None`) — ім'я має закінчуватись на `-h-hl`
|
|
10
|
+
- **ClusterIP Service** (не headless) — ім'я має закінчуватись на `-h`
|
|
11
|
+
|
|
12
|
+
Ресурси з `kind != "Service"` пропускаються без помилок.
|
|
13
|
+
|
|
14
|
+
✓ `db-h-hl` (headless), `db-h` (clusterIP)
|
|
15
|
+
✗ `contract-h` як headless, `db-h-hl` як clusterIP
|
|
@@ -13,6 +13,4 @@ alwaysApply: false
|
|
|
13
13
|
|
|
14
14
|
## Швидкий gate через conftest
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|---|---|
|
|
18
|
-
| `image_avif.package_json` | typo-ключі, тип поля та тип `disable-avif` в опт-аут конфігу `package.json` |
|
|
16
|
+
[image-avif-package_json](./policy/package_json/package_json.mdc)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Rego-gate: структура опт-аут конфігу у package.json
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `image-avif.package_json`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `package.json` (передається через `--input` у conftest).
|
|
6
|
+
|
|
7
|
+
Перевіряє три умови:
|
|
8
|
+
|
|
9
|
+
- **Тип поля** — `"@nitra/minify-image"` має бути обʼєктом (якщо задано); рядок, масив чи boolean → deny.
|
|
10
|
+
- **Тип прапора** — `"@nitra/minify-image.disable-avif"` має бути `boolean`; рядок або число → deny.
|
|
11
|
+
- **Typo-ключі** — забороняє ключі зі списку deny-template [`package.json.deny.json`](./template/package.json.deny.json) (наприклад, `"disabled-avif"` замість `"disable-avif"`).
|
|
12
|
+
|
|
13
|
+
Deny-template: [package.json.deny.json](./template/package.json.deny.json)
|
|
14
|
+
|
|
15
|
+
✓ `{ "@nitra/minify-image": { "disable-avif": true } }`
|
|
16
|
+
✗ `{ "@nitra/minify-image": { "disabled-avif": true } }` — typo-ключ
|
|
17
|
+
✗ `{ "@nitra/minify-image": "disable-avif" }` — поле не є обʼєктом
|
|
18
|
+
✗ `{ "@nitra/minify-image": { "disable-avif": "yes" } }` — не boolean
|
|
@@ -15,4 +15,4 @@ CLI [`@nitra/minify-image`](https://www.npmjs.com/package/@nitra/minify-image) (
|
|
|
15
15
|
|
|
16
16
|
## Швидкий gate через conftest
|
|
17
17
|
|
|
18
|
-
-
|
|
18
|
+
[image-compress-package_json](./policy/package_json/package_json.mdc)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Заборона `@nitra/minify-image` у залежностях (`package.json`)
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `image_compress.package_json`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `package.json` (єдиний файл проєкту).
|
|
6
|
+
|
|
7
|
+
Перевіряє поля `dependencies` та `devDependencies`: якщо там присутній пакет `@nitra/minify-image` — deny. Список заборонених пакетів надходить через `--data` з канонічного шаблону:
|
|
8
|
+
|
|
9
|
+
[package.json.deny.json](./template/package.json.deny.json)
|
|
10
|
+
|
|
11
|
+
✓ `{}` — порожній `package.json` без залежностей
|
|
12
|
+
✗ `{ "dependencies": { "@nitra/minify-image": "^4.0.1" } }` — заборонено, використовуй `npx`
|
|
13
|
+
✗ `{ "devDependencies": { "@nitra/minify-image": "^4.0.1" } }` — заборонено, використовуй `npx`
|
package/rules/js/main.mdc
CHANGED
|
@@ -35,9 +35,10 @@ version: '1.30'
|
|
|
35
35
|
|
|
36
36
|
Rego-пакети у `policy/` — запускаються `npx @nitra/cursor fix js` або `conftest`:
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
[js-policy-package_json](./policy/package_json/package_json.mdc)
|
|
39
|
+
|
|
40
|
+
[js-policy-jscpd](./policy/jscpd/jscpd.mdc)
|
|
41
|
+
|
|
42
|
+
[js-policy-lint_js_yml](./policy/lint_js_yml/lint_js_yml.mdc)
|
|
43
|
+
|
|
44
|
+
[js-policy-vscode_extensions](./policy/vscode_extensions/vscode_extensions.mdc)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Rego-gate `.jscpd.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_lint.jscpd`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.jscpd.json` у корені проєкту.
|
|
6
|
+
|
|
7
|
+
Що перевіряється:
|
|
8
|
+
|
|
9
|
+
- `gitignore` — точна відповідність (`true`)
|
|
10
|
+
- `exitCode` — точна відповідність (`1`)
|
|
11
|
+
- `reporters` — subset-of: масив має містити всі елементи з канону (`["console"]`)
|
|
12
|
+
- `minLines` — число, значення >= канонічного порогу (`25`); більше дозволено
|
|
13
|
+
|
|
14
|
+
Канон-snippet: [.jscpd.json.snippet.json](./template/.jscpd.json.snippet.json)
|