@nitra/cursor 12.8.6 → 12.8.7
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/adr/js/hooks.mdc +32 -0
- package/rules/adr/js/madr_format.mdc +96 -0
- package/rules/adr/js/settings_policy.mdc +34 -0
- package/rules/adr/main.mdc +13 -95
- package/rules/bun/js/bunfig.mdc +12 -0
- package/rules/bun/js/layout.mdc +60 -0
- package/rules/bun/js/lint.mdc +9 -0
- package/rules/bun/js/package_json.mdc +19 -0
- package/rules/bun/main.mdc +9 -61
- package/rules/capacitor/js/ios_spm.mdc +69 -0
- package/rules/capacitor/js/version.mdc +29 -0
- package/rules/capacitor/main.mdc +8 -22
- package/rules/changelog/js/agent-workflow.mdc +15 -0
- package/rules/changelog/js/changelog-format.mdc +33 -0
- package/rules/changelog/js/comparison-models.mdc +40 -0
- package/rules/changelog/main.mdc +4 -98
- package/rules/ci4/js/marksman_config.mdc +31 -0
- package/rules/ci4/js/vscode_extensions.mdc +33 -0
- package/rules/ci4/main.mdc +14 -14
- package/rules/docker/js/compile.mdc +44 -0
- package/rules/docker/js/hadolint.mdc +50 -0
- package/rules/docker/js/mirror.mdc +13 -0
- package/rules/docker/js/multistage.mdc +13 -0
- package/rules/docker/js/native-addon.mdc +43 -0
- package/rules/docker/js/nginx-tag.mdc +7 -0
- package/rules/docker/js/nginx-user.mdc +37 -0
- package/rules/docker/js/non-root.mdc +39 -0
- package/rules/docker/main.mdc +15 -196
- package/rules/ga/js/lint_toolchain.mdc +15 -0
- package/rules/ga/js/required_workflows.mdc +35 -0
- package/rules/ga/js/vscode.mdc +17 -0
- package/rules/ga/js/workflow_common.mdc +108 -0
- package/rules/ga/js/workflows.mdc +32 -0
- package/rules/ga/js/zizmor.mdc +7 -0
- package/rules/ga/main.mdc +17 -125
- package/rules/graphql/js/tooling.mdc +13 -0
- package/rules/graphql/js/vscode_extensions.mdc +13 -0
- package/rules/graphql/main.mdc +3 -22
- package/rules/hasura/js/internal_urls.mdc +27 -0
- package/rules/hasura/js/migrations.mdc +13 -0
- package/rules/hasura/js/svc_hl.mdc +17 -0
- package/rules/hasura/main.mdc +8 -30
- package/rules/image-avif/js/avif_generation.mdc +26 -0
- package/rules/image-avif/js/package_json_optout.mdc +21 -0
- package/rules/image-avif/main.mdc +7 -34
- package/rules/image-compress/js/package_json.mdc +7 -0
- package/rules/image-compress/js/package_setup.mdc +13 -0
- package/rules/image-compress/main.mdc +4 -12
- package/rules/js/docs/index.md +3 -3
- package/rules/js/js/dep-policy.mdc +17 -0
- package/rules/js/js/eslint-config.mdc +28 -0
- package/rules/js/js/extensions.mdc +8 -0
- package/rules/js/js/file-extensions.mdc +12 -0
- package/rules/js/js/for-in.mdc +26 -0
- package/rules/js/js/jscpd.mdc +42 -0
- package/rules/js/js/knip.mdc +15 -0
- package/rules/js/js/lint-js-workflow.mdc +58 -0
- package/rules/js/js/oxlintrc.mdc +20 -0
- package/rules/js/js/package-json.mdc +31 -0
- package/rules/js/js/tests.mdc +9 -0
- package/rules/js/js/utils-lib-structure.mdc +15 -0
- package/rules/js/main.mdc +21 -214
- package/rules/js-bun-db/js/bun-sql-migration.mdc +15 -0
- package/rules/js-bun-db/js/connection.mdc +42 -0
- package/rules/js-bun-db/js/pg-format-identifiers.mdc +102 -0
- package/rules/js-bun-db/js/pg-format-shim.mdc +99 -0
- package/rules/js-bun-db/js/pg-leftover.mdc +27 -0
- package/rules/js-bun-db/js/pg-listen-notify.mdc +51 -0
- package/rules/js-bun-db/js/query-safety.mdc +117 -0
- package/rules/js-bun-db/js/sql-array.mdc +88 -0
- package/rules/js-bun-db/js/unsafe.mdc +65 -0
- package/rules/js-bun-db/main.mdc +15 -605
- package/rules/js-bun-redis/js/imports.mdc +47 -0
- package/rules/js-bun-redis/js/package_json.mdc +44 -0
- package/rules/js-bun-redis/main.mdc +3 -11
- package/rules/js-mssql/js/mssql-in-list.mdc +38 -0
- package/rules/js-mssql/js/mssql-pool.mdc +56 -0
- package/rules/js-mssql/js/mssql-query-template.mdc +33 -0
- package/rules/js-mssql/js/mssql-tvp.mdc +75 -0
- package/rules/js-mssql/js/mssql-version.mdc +7 -0
- package/rules/js-mssql/main.mdc +10 -198
- package/rules/js-run/js/check-env.mdc +35 -0
- package/rules/js-run/js/conn-aliases.mdc +109 -0
- package/rules/js-run/js/jsconfig.mdc +20 -0
- package/rules/js-run/js/otel-configmap.mdc +6 -0
- package/rules/js-run/js/pino.mdc +6 -0
- package/rules/js-run/js/project-structure.mdc +11 -0
- package/rules/js-run/js/runtime.mdc +14 -0
- package/rules/js-run/js/scope.mdc +11 -0
- package/rules/js-run/js/settimeout.mdc +11 -0
- package/rules/js-run/js/temporal.mdc +5 -0
- package/rules/js-run/main.mdc +16 -218
- package/rules/k8s/js/configmap.mdc +41 -0
- package/rules/k8s/js/deployment_resources.mdc +49 -0
- package/rules/k8s/js/hasura_httproute.mdc +91 -0
- package/rules/k8s/js/hpa_apiversion.mdc +27 -0
- package/rules/k8s/js/ingress_gateway.mdc +16 -0
- package/rules/k8s/js/kustomize_structure.mdc +144 -0
- package/rules/k8s/js/lint_k8s.mdc +72 -0
- package/rules/k8s/js/multidoc_yaml.mdc +5 -0
- package/rules/k8s/js/network_policy.mdc +136 -0
- package/rules/k8s/js/schema_modeline.mdc +57 -0
- package/rules/k8s/js/service.mdc +44 -0
- package/rules/k8s/js/topology_hpa_pdb.mdc +181 -0
- package/rules/k8s/main.mdc +30 -843
- package/rules/nginx-default-tpl/js/dockerfile.mdc +36 -0
- package/rules/nginx-default-tpl/js/http-route.mdc +41 -0
- package/rules/nginx-default-tpl/js/ini-keys.mdc +21 -0
- package/rules/nginx-default-tpl/js/template-structure.mdc +86 -0
- package/rules/nginx-default-tpl/js/vscode.mdc +37 -0
- package/rules/nginx-default-tpl/main.mdc +6 -112
- package/rules/npm-module/js/docs/index.md +5 -5
- package/rules/npm-module/js/docs/rule_meta.md +6 -6
- package/rules/npm-module/js/docs/skill_meta.md +8 -8
- package/rules/npm-module/js/header_doc_pointer.mdc +18 -0
- package/rules/npm-module/js/package_structure.mdc +62 -0
- package/rules/npm-module/js/rule_meta.mdc +11 -0
- package/rules/npm-module/js/skill_meta.mdc +11 -0
- package/rules/npm-module/main.mdc +10 -55
- package/rules/php/js/lint_php_yml.mdc +12 -0
- package/rules/php/js/tooling.mdc +66 -0
- package/rules/php/main.mdc +7 -66
- package/rules/python/js/lint_python_yml.mdc +23 -0
- package/rules/python/js/pyproject_toml.mdc +32 -0
- package/rules/python/js/tooling.mdc +23 -0
- package/rules/python/main.mdc +9 -33
- package/rules/rego/js/rego-lint.mdc +31 -0
- package/rules/rego/js/vscode_extensions.mdc +11 -0
- package/rules/rego/js/vscode_settings.mdc +13 -0
- package/rules/rego/main.mdc +8 -24
- package/rules/rust/js/coverage.mdc +28 -0
- package/rules/rust/js/lint.mdc +22 -0
- package/rules/rust/js/tauri_composition.mdc +8 -0
- package/rules/rust/js/vscode_extensions.mdc +12 -0
- package/rules/rust/main.mdc +8 -38
- package/rules/security/js/rego_policies.mdc +15 -0
- package/rules/security/js/sample_secret.mdc +19 -0
- package/rules/security/js/trufflehog.mdc +21 -0
- package/rules/security/main.mdc +7 -35
- package/rules/style/js/admin-table.mdc +88 -0
- package/rules/style/js/colors.mdc +21 -0
- package/rules/style/js/gap.mdc +22 -0
- package/rules/style/js/quasar-fixes.mdc +32 -0
- package/rules/style/js/quasar.mdc +7 -0
- package/rules/style/js/tooling.mdc +85 -0
- package/rules/style/main.mdc +13 -253
- package/rules/tauri/js/cargo_mutants_config.mdc +39 -0
- package/rules/tauri/js/tool_surface.mdc +21 -0
- package/rules/tauri/js/tooling.mdc +25 -0
- package/rules/tauri/main.mdc +8 -78
- package/rules/test/js/cargo_mutants_config.mdc +18 -0
- package/rules/test/js/docs/index.md +7 -7
- package/rules/test/js/location.mdc +52 -0
- package/rules/test/js/no-console-store-restore.mdc +11 -0
- package/rules/test/js/no-process-chdir.mdc +15 -0
- package/rules/test/js/no-relative-fs-path.mdc +22 -0
- package/rules/test/js/sandbox-aware-test.mdc +28 -0
- package/rules/test/js/stryker_config.mdc +26 -0
- package/rules/test/js/vitest-config-pool-forks.mdc +33 -0
- package/rules/test/main.mdc +18 -184
- package/rules/text/js/ci-lint-text.mdc +15 -0
- package/rules/text/js/cspell.mdc +81 -0
- package/rules/text/js/dotenv-linter.mdc +16 -0
- package/rules/text/js/forbidden-prettier.mdc +13 -0
- package/rules/text/js/markdownlint.mdc +25 -0
- package/rules/text/js/oxfmt.mdc +35 -0
- package/rules/text/js/package-json.mdc +26 -0
- package/rules/text/js/shellcheck.mdc +18 -0
- package/rules/text/js/v8r.mdc +23 -0
- package/rules/text/js/vscode.mdc +86 -0
- package/rules/text/main.mdc +20 -237
- package/rules/vue/js/composition-api.mdc +82 -0
- package/rules/vue/js/nheader-layout.mdc +171 -0
- package/rules/vue/js/node-imports.mdc +25 -0
- package/rules/vue/js/quasar-ui.mdc +32 -0
- package/rules/vue/js/structure.mdc +101 -0
- package/rules/vue/js/testing.mdc +32 -0
- package/rules/vue/js/tfm-translations.mdc +26 -0
- package/rules/vue/js/vite-config.mdc +126 -0
- package/rules/vue/js/vite-env.mdc +55 -0
- package/rules/vue/js/vue-imports.mdc +25 -0
- package/rules/vue/main.mdc +16 -640
- package/scripts/docs/index.md +16 -16
- package/scripts/lib/docs/index.md +36 -36
- package/scripts/utils/docs/index.md +14 -14
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## CI: `.github/workflows/lint-php.yml`
|
|
2
|
+
|
|
3
|
+
Канон workflow — [lint-php.yml.snippet.yml](./policy/lint_php_yml/template/lint-php.yml.snippet.yml).
|
|
4
|
+
|
|
5
|
+
Файл запускається при push/PR до `dev`/`main` за змінами в `**/*.php`, `composer.json`, `composer.lock`, `phpstan.neon`, `phpstan.neon.dist`, `psalm.xml` або самого workflow.
|
|
6
|
+
|
|
7
|
+
Кроки job `php`:
|
|
8
|
+
1. `actions/checkout@v6` (без persist-credentials)
|
|
9
|
+
2. `./.github/actions/setup-bun-deps`
|
|
10
|
+
3. `shivammathur/setup-php@v2` — PHP 8.5
|
|
11
|
+
4. `composer install --no-interaction --no-progress --prefer-dist`
|
|
12
|
+
5. `n-cursor lint php --read-only`
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
## PHP-інструменти лінту
|
|
2
|
+
|
|
3
|
+
Весь код повинен відповідати PHP 8.5, перевірятися через PHPCompatibility і конвертуватися через Rector.
|
|
4
|
+
|
|
5
|
+
Код має бути добре задокументований через phpDoc:
|
|
6
|
+
|
|
7
|
+
```php
|
|
8
|
+
/** @param array<int, string> $items */
|
|
9
|
+
function process($items) {
|
|
10
|
+
foreach ($items as $id => $name) {
|
|
11
|
+
// PHPStan знає, що $id — int, $name — string
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### PHP_CodeSniffer (phpcs) і пакет `squizlabs/php_codesniffer`
|
|
17
|
+
|
|
18
|
+
Стиль, базові ризики, за потреби окремі стандарти. Для **SQL injection**, **XSS**, **небезпечні функції** — PHPCS + **php-security-audit** (стандарт `Security`).
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
phpcs --standard=Security app/
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### PHPStan
|
|
25
|
+
|
|
26
|
+
Статичний аналіз типів і смертельних слабких місць; **PHPStan Taint Analysis** (`phpstan/phpstan-taint-analysis`) — для потоку даних (taint) у стилі security-аналізу.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
vendor/bin/phpstan analyse
|
|
30
|
+
# після підключення розширення taint — у phpstan.neon/ neon.dist
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### PHP-CS-Fixer
|
|
34
|
+
|
|
35
|
+
Форматтер/фіксер коду; у **lint** зазвичай перевірка без змін (`--dry-run`).
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
vendor/bin/php-cs-fixer fix --dry-run --diff
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Psalm
|
|
42
|
+
|
|
43
|
+
Альтернативний/додатковий аналізатор; **Psalm Security Plugin** (`vimeo/psalm` + пакет на кшталт `psalm/plugin-security` залежно від вибраної збірки) — для security-орієнтованих правил.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
vendor/bin/psalm
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `composer audit`
|
|
50
|
+
|
|
51
|
+
Перевірка відомих вразливостей залежностей за даними **Packagist/security-advisories**.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
composer audit
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Запуск lint-php
|
|
58
|
+
|
|
59
|
+
`composer`-інструменти не мають єдиного CLI, який сам обходить репозиторій, тому php-лінт делегується у JS-скрипт-обгортку. Запуск — через **`n-cursor lint php`** (CI — `--read-only`); окремого `package.json`-скрипта немає.
|
|
60
|
+
|
|
61
|
+
Скрипт `run-php.mjs`:
|
|
62
|
+
|
|
63
|
+
- якщо `composer.json` у корені відсутній — вихід 0 (перевірка пропущена);
|
|
64
|
+
- якщо `composer.json` є, але `composer` не знайдено в PATH — це помилка;
|
|
65
|
+
- `composer audit` — обовʼязковий;
|
|
66
|
+
- `vendor/bin/php-cs-fixer`, `vendor/bin/phpcs`, `vendor/bin/phpstan`, `vendor/bin/psalm` — запускаються лише якщо встановлені (інакше крок пропускається з повідомленням).
|
package/rules/php/main.mdc
CHANGED
|
@@ -5,73 +5,14 @@ globs: "**/*.php"
|
|
|
5
5
|
alwaysApply: false
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Весь код повинен відповідати PHP 8.5
|
|
8
|
+
Весь код повинен відповідати PHP 8.5 (PHPCompatibility + Rector). Лінт запускається через `n-cursor lint php`.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
[php-tooling](./js/tooling.mdc)
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
/** @param array<int, string> $items */
|
|
14
|
-
function process($items) {
|
|
15
|
-
foreach ($items as $id => $name) {
|
|
16
|
-
// PHPStan знає, що $id — int, $name — string
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
```
|
|
12
|
+
[php-lint_php_yml](./js/lint_php_yml.mdc)
|
|
20
13
|
|
|
21
|
-
##
|
|
14
|
+
## Швидкий gate через conftest
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
phpcs --standard=Security app/
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### PHPStan
|
|
32
|
-
|
|
33
|
-
Статичний аналіз типів і смертельних слабких місць; **PHPStan Taint Analysis** (`phpstan/phpstan-taint-analysis`) — для потоку даних (taint) у стилі security-аналізу.
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
vendor/bin/phpstan analyse
|
|
37
|
-
# після підключення розширення taint — у phpstan.neon/ neon.dist
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### PHP-CS-Fixer
|
|
41
|
-
|
|
42
|
-
Форматтер/фіксер коду; у **lint** зазвичай перевірка без змін (`--dry-run`).
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
vendor/bin/php-cs-fixer fix --dry-run --diff
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Psalm
|
|
49
|
-
|
|
50
|
-
Альтернативний/додатковий аналізатор; **Psalm Security Plugin** (`vimeo/psalm` + пакет на кшталт `psalm/plugin-security` залежно від вибраної збірки) — для security-орієнтованих правил.
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
vendor/bin/psalm
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### `composer audit`
|
|
57
|
-
|
|
58
|
-
Перевірка відомих вразливостей залежностей за даними **Packagist/security-advisories**.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
composer audit
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## lint-php
|
|
65
|
-
|
|
66
|
-
`composer`-інструмененти не мають єдиного CLI, який сам обходить репозиторій, тому php-лінт делегується у JS-скрипт-обгортку. Запуск — через **`n-cursor lint php`** (CI — `--read-only`); окремого `package.json`-скрипта немає.
|
|
67
|
-
|
|
68
|
-
Скрипт `run-php.mjs`:
|
|
69
|
-
|
|
70
|
-
- якщо `composer.json` у корені відсутній — вихід 0 (перевірка пропущена);
|
|
71
|
-
- якщо `composer.json` є, але `composer` не знайдено в PATH — це помилка;
|
|
72
|
-
- `composer audit` — обовʼязковий;
|
|
73
|
-
- `vendor/bin/php-cs-fixer`, `vendor/bin/phpcs`, `vendor/bin/phpstan`, `vendor/bin/psalm` — запускаються лише якщо встановлені (інакше крок пропускається з повідомленням).
|
|
74
|
-
|
|
75
|
-
## CI: `.github/workflows/lint-php.yml`
|
|
76
|
-
|
|
77
|
-
- Канон: [lint-php.yml.snippet.yml](./policy/lint_php_yml/template/lint-php.yml.snippet.yml)
|
|
16
|
+
| Пакет | Що перевіряє |
|
|
17
|
+
|---|---|
|
|
18
|
+
| `php.lint_php_yml` | Структуру `.github/workflows/lint-php.yml` — наявність канонічних `run:`-кроків |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## CI: `.github/workflows/lint-python.yml`
|
|
2
|
+
|
|
3
|
+
Канонічний workflow: [lint-python.yml.snippet.yml](./policy/lint_python_yml/template/lint-python.yml.snippet.yml)
|
|
4
|
+
|
|
5
|
+
Без кроків `poetry install` / `snok/install-poetry` — лише `astral-sh/setup-uv@v8.0.0` + `uv sync --frozen`.
|
|
6
|
+
|
|
7
|
+
Обовʼязкові кроки:
|
|
8
|
+
- `actions/checkout@v6` з `persist-credentials: false`;
|
|
9
|
+
- `./.github/actions/setup-bun-deps` — встановлення JS-залежностей (для `n-cursor lint`);
|
|
10
|
+
- `astral-sh/setup-uv@v8.0.0` — встановлення uv;
|
|
11
|
+
- `uv sync --frozen` — встановлення Python-залежностей строго з lock-файлу;
|
|
12
|
+
- `n-cursor lint python --read-only` — запуск lint (без auto-fix у CI).
|
|
13
|
+
|
|
14
|
+
`uv` / `ruff` / `mypy` **не** додаються в кореневі `devDependencies` споживача — це окремий toolchain, що ставиться через `astral-sh/setup-uv` у CI або локально.
|
|
15
|
+
|
|
16
|
+
## Rego: python.lint_python_yml
|
|
17
|
+
|
|
18
|
+
Polісі `policy/lint_python_yml/lint_python_yml.rego` — drift-safe перевірка через `--data template`:
|
|
19
|
+
|
|
20
|
+
- кожен `uses` з template має бути присутнім у workflow input;
|
|
21
|
+
- кожен `run` з template має бути substring серед run-кроків input.
|
|
22
|
+
|
|
23
|
+
Заборона Poetry-кроків (`snok/install-poetry`, `poetry install`) забезпечується відсутністю у каноні: правило вимагає uv-кроки, і жодних poetry-кроків у template немає.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## pyproject.toml: PEP 621 і заборона Poetry
|
|
2
|
+
|
|
3
|
+
Метадані проєкту — у секції **`[project]`** (PEP 621), а **не** в `[tool.poetry]`.
|
|
4
|
+
|
|
5
|
+
Обовʼязкові поля:
|
|
6
|
+
- `[project].name` — назва пакета;
|
|
7
|
+
- `[project].version` — статична версія;
|
|
8
|
+
- `[project].requires-python` — мінімальна версія Python;
|
|
9
|
+
- `[project].dependencies` — залежності (навіть порожній список).
|
|
10
|
+
|
|
11
|
+
Lock-файл — **`uv.lock`** (коммітиться). `poetry.lock` / `poetry.toml` мають бути відсутні.
|
|
12
|
+
|
|
13
|
+
Залежності: `uv add <pkg>`; dev-залежності: `uv add --dev <pkg>`.
|
|
14
|
+
|
|
15
|
+
Канонічний цільовий вигляд `pyproject.toml`: [pyproject.toml.snippet.toml](./policy/pyproject_toml/template/pyproject.toml.snippet.toml)
|
|
16
|
+
|
|
17
|
+
Заборонені під-таблиці `[tool.*]` (Poetry): [pyproject.toml.deny.toml](./policy/pyproject_toml/template/pyproject.toml.deny.toml)
|
|
18
|
+
|
|
19
|
+
## Міграція з Poetry на uv
|
|
20
|
+
|
|
21
|
+
1. Прибери `[tool.poetry]` і `poetry.lock` / `poetry.toml`.
|
|
22
|
+
2. Перенеси метадані в `[project]` (name, version, requires-python, dependencies) за PEP 621.
|
|
23
|
+
3. Згенеруй lock: `uv lock` → `uv.lock`.
|
|
24
|
+
4. Dev-залежності: `uv add --dev ruff mypy …`.
|
|
25
|
+
|
|
26
|
+
## Rego: python.pyproject_toml
|
|
27
|
+
|
|
28
|
+
Polисі `policy/pyproject_toml/pyproject_toml.rego` — дві групи правил:
|
|
29
|
+
|
|
30
|
+
**1. Заборона Poetry** — перевіряє, чи є заборонені під-таблиці `[tool.*]` з `pyproject.toml.deny.toml` (drift-safe через `--data template`).
|
|
31
|
+
|
|
32
|
+
**2. PEP 621** — `[project].name` і `[project].version` мають бути непорожніми рядками.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Перевірка наявності uv-toolchain і відсутності Poetry
|
|
2
|
+
|
|
3
|
+
JS-перевірка (`js/tooling.mjs`) запускається, якщо в корені репо є `pyproject.toml`. Перевіряє:
|
|
4
|
+
|
|
5
|
+
- `uv.lock` — має існувати (зафіксувати командою `uv lock`);
|
|
6
|
+
- `poetry.lock` / `poetry.toml` — мають **бути відсутніми** (Poetry заборонено);
|
|
7
|
+
- `package.json` — має бути у корені (js-обгортка lint є частиною монорепо);
|
|
8
|
+
- `.github/workflows/lint-python.yml` — має існувати (структуру перевіряє Rego-полісі `python.lint_python_yml`).
|
|
9
|
+
|
|
10
|
+
Якщо `pyproject.toml` відсутній — перевірка пропускається з кодом 0 (проєкт не Python).
|
|
11
|
+
|
|
12
|
+
## lint-python: JS-скрипт-обгортка
|
|
13
|
+
|
|
14
|
+
Інструменти uv-екосистеми не мають єдиного CLI-обходу репо, тому python-лінт делегується у JS-скрипт-обгортку. Запуск — через **`n-cursor lint python`** (CI — `--read-only`); окремого `package.json`-скрипта немає.
|
|
15
|
+
|
|
16
|
+
Скрипт `rules/python/lint/lint.mjs`:
|
|
17
|
+
|
|
18
|
+
- якщо `pyproject.toml` у корені відсутній — вихід 0 (перевірка пропущена);
|
|
19
|
+
- якщо `pyproject.toml` є, але `uv` не знайдено в PATH — це помилка;
|
|
20
|
+
- `uv lock --check` і `uv sync --frozen` — обовʼязкові;
|
|
21
|
+
- `uv run ruff check --fix .` + `uv run ruff format .` — auto-fix (мутують робоче дерево, як `markdownlint-cli2 --fix` у lint-text);
|
|
22
|
+
- `uv run mypy .` — статична перевірка типів;
|
|
23
|
+
- усі `ruff`/`mypy`-кроки запускаються лише якщо інструмент доступний у середовищі (інакше крок пропускається з повідомленням).
|
package/rules/python/main.mdc
CHANGED
|
@@ -5,41 +5,17 @@ alwaysApply: false
|
|
|
5
5
|
version: '1.0'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Python-проєкти ведуться **виключно** на [uv](https://docs.astral.sh/uv/) — єдиний пакет-менеджер і резолвер. **Poetry заборонено.**
|
|
8
|
+
Python-проєкти ведуться **виключно** на [uv](https://docs.astral.sh/uv/) — єдиний пакет-менеджер і резолвер. **Poetry заборонено.** Середовище: `uv sync --frozen` (строго з `uv.lock`).
|
|
9
9
|
|
|
10
|
-
-
|
|
11
|
-
- Lock-файл — **`uv.lock`** (коммітиться). `poetry.lock` / `poetry.toml` мають бути відсутні.
|
|
12
|
-
- Залежності: `uv add <pkg>`; dev-залежності: `uv add --dev <pkg>`.
|
|
13
|
-
- Середовище: `uv sync --frozen` (строго з `uv.lock`).
|
|
10
|
+
[python-pyproject_toml](./js/pyproject_toml.mdc)
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
[python-lint_python_yml](./js/lint_python_yml.mdc)
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
[python-tooling](./js/tooling.mdc)
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
2. Перенеси метадані в `[project]` (name, version, requires-python, dependencies) за PEP 621.
|
|
21
|
-
3. Згенеруй lock: `uv lock` → `uv.lock`.
|
|
22
|
-
4. Dev-залежності: `uv add --dev ruff mypy …`.
|
|
16
|
+
## Швидкий gate через conftest (Rego)
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## lint-python
|
|
29
|
-
|
|
30
|
-
Інструменти uv-екосистеми не мають єдиного CLI, що сам обходить репозиторій, тому python-лінт делегується у JS-скрипт-обгортку. Запуск — через **`n-cursor lint python`** (CI — `--read-only`); окремого `package.json`-скрипта немає.
|
|
31
|
-
|
|
32
|
-
Скрипт `rules/python/lint/lint.mjs`:
|
|
33
|
-
|
|
34
|
-
- якщо `pyproject.toml` у корені відсутній — вихід 0 (перевірка пропущена);
|
|
35
|
-
- якщо `pyproject.toml` є, але `uv` не знайдено в PATH — це помилка;
|
|
36
|
-
- `uv lock --check` і `uv sync --frozen` — обовʼязкові;
|
|
37
|
-
- `uv run ruff check --fix .` + `uv run ruff format .` — auto-fix (мутують робоче дерево, як `markdownlint-cli2 --fix` у lint-text);
|
|
38
|
-
- `uv run mypy .` — статична перевірка типів;
|
|
39
|
-
- усі `ruff`/`mypy`-кроки запускаються лише якщо інструмент доступний у середовищі (інакше крок пропускається з повідомленням).
|
|
40
|
-
|
|
41
|
-
## CI: `.github/workflows/lint-python.yml`
|
|
42
|
-
|
|
43
|
-
- Канон: [lint-python.yml.snippet.yml](./policy/lint_python_yml/template/lint-python.yml.snippet.yml)
|
|
44
|
-
|
|
45
|
-
Без кроків `poetry install` / `snok/install-poetry` — лише `astral-sh/setup-uv@v8.0.0` + `uv sync --frozen`.
|
|
18
|
+
| Namespace | Що перевіряє |
|
|
19
|
+
|-----------|-------------|
|
|
20
|
+
| `python.pyproject_toml` | Заборона `[tool.poetry]`; наявність `[project].name` і `[project].version` (PEP 621) |
|
|
21
|
+
| `python.lint_python_yml` | Обовʼязкові `uses` і `run`-кроки у `.github/workflows/lint-python.yml` |
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
## Лінт Rego-файлів (opa / regal / conftest)
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
n-cursor lint rego
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Цілі — `npm/rules/` (рекурсивно знаходить `.rego` у `<rule>/policy/<concern>/`).
|
|
8
|
+
Інші `*.rego` поза деревом — додай у `LINT_TARGETS` у `npm/rules/rego/lint/lint.mjs`.
|
|
9
|
+
|
|
10
|
+
`opa` і `regal` — лише у `PATH`, **не** додавай у `dependencies` / `devDependencies`.
|
|
11
|
+
|
|
12
|
+
### Кроки лінту
|
|
13
|
+
|
|
14
|
+
1. **`opa check --strict`** — компіляція з типами і строгим режимом: ловить мертвий код,
|
|
15
|
+
неоднозначні правила, незадекларовані змінні. Зупиняє пайплайн при помилці.
|
|
16
|
+
2. **`regal lint`** — статичний лінтер: v0-синтаксис, неявні set-rules, відхилення від `rego.v1`,
|
|
17
|
+
bugs/idiomatic/performance-правила.
|
|
18
|
+
3. **`conftest verify`** (опційно) — виконує `test_*` правила у `*_test.rego`.
|
|
19
|
+
Якщо `conftest` відсутній у `PATH` — пропускається без помилки (у CI потрібно встановити).
|
|
20
|
+
|
|
21
|
+
### Конфіг regal
|
|
22
|
+
|
|
23
|
+
У корені проєкту — `.regal/config.yaml`. Дозволено вимикати окремі правила під специфіку репо
|
|
24
|
+
(наприклад, conftest-полісі — `deny`-правила як де-факто entrypoint-и):
|
|
25
|
+
|
|
26
|
+
```yaml title=".regal/config.yaml"
|
|
27
|
+
rules:
|
|
28
|
+
idiomatic:
|
|
29
|
+
no-defined-entrypoint:
|
|
30
|
+
level: ignore
|
|
31
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Розширення VS Code для Rego
|
|
2
|
+
|
|
3
|
+
`.vscode/extensions.json` має містити `tsandall.opa` у масиві `recommendations` —
|
|
4
|
+
це забезпечує LSP-підтримку та форматування через `opa fmt` при збереженні.
|
|
5
|
+
|
|
6
|
+
Канонічний сніпет: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
|
|
7
|
+
|
|
8
|
+
Перевірка — subset-of: кожне розширення зі сніпету має бути присутнє у `recommendations`.
|
|
9
|
+
Додаткові розширення (від інших правил) — дозволені.
|
|
10
|
+
|
|
11
|
+
Ціль (`target.json`): `.vscode/extensions.json` — обовʼязковий файл.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Налаштування VS Code для Rego
|
|
2
|
+
|
|
3
|
+
`.vscode/settings.json` має містити `[rego]`-блок з двома ключами:
|
|
4
|
+
|
|
5
|
+
- `editor.defaultFormatter` = `"tsandall.opa"`
|
|
6
|
+
- `editor.formatOnSave` = `true`
|
|
7
|
+
|
|
8
|
+
Канонічний сніпет: [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
|
|
9
|
+
|
|
10
|
+
Перевірка — leaf-by-leaf: кожен ключ/значення зі сніпету звіряється з файлом.
|
|
11
|
+
Якщо `[rego]`-блок присутній, але не є обʼєктом — окрема помилка типу.
|
|
12
|
+
|
|
13
|
+
Ціль (`target.json`): `.vscode/settings.json` — обовʼязковий файл.
|
package/rules/rego/main.mdc
CHANGED
|
@@ -9,31 +9,15 @@ alwaysApply: false
|
|
|
9
9
|
|
|
10
10
|
Синтаксичні правила (`rego.v1`, `import rego.v1`, заборона legacy v0) — у `conftest.mdc` (alwaysApply). Цей файл — про **інструментарій**: VS Code, лінтери, форматування.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
[rego-rego-lint](./js/rego-lint.mdc)
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
n-cursor lint rego
|
|
16
|
-
```
|
|
14
|
+
## Швидкий gate через conftest
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
| Пакет | Ціль | Що перевіряє |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `rego.vscode_extensions` | `.vscode/extensions.json` | `recommendations` містить `tsandall.opa` |
|
|
19
|
+
| `rego.vscode_settings` | `.vscode/settings.json` | `[rego]`-блок з `defaultFormatter` + `formatOnSave` |
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
[rego-vscode_extensions](./js/vscode_extensions.mdc)
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- Канон `recommendations` має містити `tsandall.opa` (LSP, format-on-save через `opa fmt`): [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
|
|
25
|
-
|
|
26
|
-
### `.vscode/settings.json`
|
|
27
|
-
|
|
28
|
-
- Канон `[rego]`-block (`editor.defaultFormatter` + `editor.formatOnSave`): [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
|
|
29
|
-
|
|
30
|
-
## Конфіг regal
|
|
31
|
-
|
|
32
|
-
У корені — `.regal/config.yaml`. Дозволено вимикати окремі правила під специфіку репо (наприклад, conftest-полісі — `deny`-правила як де-факто entrypoint-и):
|
|
33
|
-
|
|
34
|
-
```yaml title=".regal/config.yaml"
|
|
35
|
-
rules:
|
|
36
|
-
idiomatic:
|
|
37
|
-
no-defined-entrypoint:
|
|
38
|
-
level: ignore
|
|
39
|
-
```
|
|
23
|
+
[rego-vscode_settings](./js/vscode_settings.mdc)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Покриття + мутаційне тестування Rust
|
|
2
|
+
|
|
3
|
+
Покриття + мутаційне тестування Rust постачаються через `n-cursor coverage` (правило `test.mdc`). Реалізація провайдера — у `npm/rules/rust/coverage/coverage.mjs`: `cargo llvm-cov --json --summary-only` + `cargo mutants --jobs N`.
|
|
4
|
+
|
|
5
|
+
Бінарники: `cargo install cargo-llvm-cov && cargo install cargo-mutants`.
|
|
6
|
+
|
|
7
|
+
### Паралелізм cargo-mutants
|
|
8
|
+
|
|
9
|
+
Паралельні воркери: дефолт `min(4, cpus/2)`; override через env **`CARGO_MUTANTS_JOBS`**. Прапорець `--in-place` відсутній — cargo-mutants створює власну sandbox-копію в `target/mutants.<i>/`, що сумісне з `--jobs > 1`.
|
|
10
|
+
|
|
11
|
+
### Incremental mutation через `--in-diff`
|
|
12
|
+
|
|
13
|
+
cargo-mutants **не** має persistent-кешу вердиктів між прогонами (на відміну від Stryker `incremental.json`). Штатний аналог «не передивляйся незмінений код» — scoping за git-diff. Вмикається env-змінною **`CARGO_MUTANTS_BASE_REF`**:
|
|
14
|
+
|
|
15
|
+
- **не задано** (дефолт, типово для `main`) — повний прогін усіх мутантів;
|
|
16
|
+
- задано (напр. `origin/main`, типово для feature-гілки в CI) — мутуються лише рядки, змінені у `<baseRef>...HEAD`. Провайдер бере `git diff --relative <baseRef>...HEAD` з каталогу crate, пише diff у sandbox і передає cargo-mutants `--in-diff`.
|
|
17
|
+
|
|
18
|
+
Краєві випадки: порожній diff (немає змін під crate) → mutation `0/0` без запуску cargo-mutants; невідомий ref / не git-репо → попередження у stderr і fallback до повного прогону.
|
|
19
|
+
|
|
20
|
+
### Пропуск baseline через `CARGO_MUTANTS_BASELINE=skip`
|
|
21
|
+
|
|
22
|
+
cargo-mutants спершу ганяє немутований baseline (повний build+test), щоб переконатися, що suite зелений. **`CARGO_MUTANTS_BASELINE=skip`** прибирає цей крок (`--baseline skip`), економлячи один повний `cargo test`.
|
|
23
|
+
|
|
24
|
+
Безпечно **лише** коли тести вже зелені у попередньому CI-степі (типовий порядок: `cargo test` → потім `n-cursor coverage` зі `skip`). Без цієї гарантії всі вердикти стають сміттєвими — дефолт: baseline-прогін. Найкорисніше в парі з `--in-diff`.
|
|
25
|
+
|
|
26
|
+
### CI-кеш `target/` — множник
|
|
27
|
+
|
|
28
|
+
`--in-diff` ріже **кількість** мутантів, кеш `target/` — **вартість кожної** компіляції; вони множаться. Без кешу холодний CI щоразу перебудовує всі залежності, і baseline-build (для Tauri — хвилини) затьмарює економію від меншої кількості мутантів. У workflow, що викликає `n-cursor coverage` для Rust, став `Swatinem/rust-cache@v2` після `dtolnay/rust-toolchain@stable`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Лінт Rust: rustfmt + clippy
|
|
2
|
+
|
|
3
|
+
**rustfmt** ([rust-lang/rustfmt](https://github.com/rust-lang/rustfmt)) — форматер; **clippy** ([rust-lang/rust-clippy](https://github.com/rust-lang/rust-clippy)) — лінтер. Запуск — через **`n-cursor lint rust`** (адаптер `main.mjs`):
|
|
4
|
+
|
|
5
|
+
- **локально (fix):** `cargo fmt --all` → `cargo clippy --fix --allow-staged --allow-dirty --all-targets --all-features` → фінальний `cargo clippy --all-targets --all-features -- -D warnings`
|
|
6
|
+
- **`--read-only` (детект, CI):** `cargo fmt --all -- --check` + `cargo clippy --all-targets --all-features -- -D warnings`
|
|
7
|
+
|
|
8
|
+
Без `Cargo.toml` у cwd — no-op (exit 0). Окремого `package.json`-скрипта немає.
|
|
9
|
+
|
|
10
|
+
`cargo`, `rustfmt`, `clippy` **не додавай** у `devDependencies` — це Rust toolchain, ставиться через `rustup` локально або через `dtolnay/rust-toolchain@stable` у CI.
|
|
11
|
+
|
|
12
|
+
### Канон CI workflow `.github/workflows/lint-rust.yml`
|
|
13
|
+
|
|
14
|
+
[lint-rust.yml.snippet.yml](./policy/lint_rust_yml/template/lint-rust.yml.snippet.yml)
|
|
15
|
+
|
|
16
|
+
Після `actions/checkout@v6` — `dtolnay/rust-toolchain@stable` (з `components: rustfmt, clippy`) + `Swatinem/rust-cache@v2` для кешу `~/.cargo` і `target/`. Bun composite дії тут не потрібен — toolchain ставиться напряму.
|
|
17
|
+
|
|
18
|
+
**Перед** `actions/checkout@v6` у інших workflows йде стандартна послідовність (див. **ga.mdc**). У `lint-rust.yml` bun-composite не потрібен.
|
|
19
|
+
|
|
20
|
+
Rego-перевірка `rust.lint_rust_yml` верифікує:
|
|
21
|
+
- наявність кожного `uses` з канону (`actions/checkout@v6`, `dtolnay/rust-toolchain@stable`, `Swatinem/rust-cache@v2`);
|
|
22
|
+
- наявність кожного `run`-кроку з канону як підрядка серед run-кроків input-файлу.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
## Композиція з Tauri
|
|
2
|
+
|
|
3
|
+
Tauri-проєкт завжди має `src-tauri/Cargo.toml`, тому правило `rust` активується автоматично разом з `tauri`. Поділ обов'язків:
|
|
4
|
+
|
|
5
|
+
- `rust` — лінт через `n-cursor lint rust`, `rust-analyzer`, `even-better-toml`, CI workflow.
|
|
6
|
+
- `tauri` — `tauri-apps.tauri-vscode` (див. **tauri.mdc**).
|
|
7
|
+
|
|
8
|
+
Обидва правила перевіряють `.vscode/extensions.json` за `contains`-семантикою; конкурентного запису немає.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Розширення VS Code для Rust
|
|
2
|
+
|
|
3
|
+
У `.vscode/extensions.json` поле `recommendations` **має містити**:
|
|
4
|
+
|
|
5
|
+
- `rust-lang.rust-analyzer`
|
|
6
|
+
- `tamasfe.even-better-toml`
|
|
7
|
+
|
|
8
|
+
Перевірка `contains`-семантики: інші розширення дозволені, усі з канону мають бути присутні.
|
|
9
|
+
|
|
10
|
+
Канон: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
|
|
11
|
+
|
|
12
|
+
Rego-перевірка `rust.vscode_extensions` для кожного запису з канону перевіряє його наявність у `recommendations` вхідного файлу.
|
package/rules/rust/main.mdc
CHANGED
|
@@ -5,44 +5,14 @@ alwaysApply: false
|
|
|
5
5
|
version: '1.4'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Правило забезпечує форматування (rustfmt), лінт (clippy), CI workflow та покриття для Rust-проєктів.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
[rust-lint](./js/lint.mdc)
|
|
11
|
+
[rust-vscode_extensions](./js/vscode_extensions.mdc)
|
|
12
|
+
[rust-tauri_composition](./js/tauri_composition.mdc)
|
|
13
|
+
[rust-coverage](./js/coverage.mdc)
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
## Швидкий gate через conftest
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Перед **`./.github/actions/setup-bun-deps`** в інших workflows йде **`actions/checkout@v6`** (див. **ga.mdc**). У **lint-rust.yml** після checkout — `dtolnay/rust-toolchain@stable` (з `components: rustfmt, clippy`) + `Swatinem/rust-cache@v2` для кешу `~/.cargo` і `target/`. Bun composite дії тут не потрібен — toolchain ставиться напряму.
|
|
17
|
-
|
|
18
|
-
## Композиція з Tauri
|
|
19
|
-
|
|
20
|
-
Tauri-проєкт завжди має `src-tauri/Cargo.toml`, тому правило `rust` активується автоматично разом з `tauri`. Поділ обов'язків:
|
|
21
|
-
|
|
22
|
-
- `rust` — лінт через `n-cursor lint rust`, `rust-analyzer`, `even-better-toml`, CI workflow.
|
|
23
|
-
- `tauri` — `tauri-apps.tauri-vscode` (див. **tauri.mdc**).
|
|
24
|
-
|
|
25
|
-
Обидва правила перевіряють `.vscode/extensions.json` за `contains`-семантикою; конкурентного запису немає.
|
|
26
|
-
|
|
27
|
-
## Покриття + мутаційне тестування Rust
|
|
28
|
-
|
|
29
|
-
Покриття + мутаційне тестування Rust постачаються через `n-cursor coverage` (правило `test.mdc`). Реалізація провайдера — у `npm/rules/rust/coverage/coverage.mjs`: `cargo llvm-cov --json --summary-only` + `cargo mutants --jobs N` (паралельні воркери, дефолт `min(4, cpus/2)`; override через env `CARGO_MUTANTS_JOBS`). Прапорець `--in-place` прибраний — cargo-mutants створює власну sandbox-копію в `target/mutants.<i>/`, що сумісне з `--jobs > 1`. Бінарники: `cargo install cargo-llvm-cov && cargo install cargo-mutants`.
|
|
30
|
-
|
|
31
|
-
### Incremental mutation через `--in-diff`
|
|
32
|
-
|
|
33
|
-
cargo-mutants **не** має persistent-кешу вердиктів між прогонами (на відміну від Stryker `incremental.json`). Штатний аналог «не передивляйся незмінений код» — scoping за git-diff. Вмикається env-змінною **`CARGO_MUTANTS_BASE_REF`**:
|
|
34
|
-
|
|
35
|
-
- **не задано** (дефолт, типово для `main`) — повний прогін усіх мутантів;
|
|
36
|
-
- задано (напр. `origin/main`, типово для feature-гілки в CI) — мутуються лише рядки, змінені у `<baseRef>...HEAD`. Провайдер бере `git diff --relative <baseRef>...HEAD` з каталогу crate (шляхи в diff збігаються з тим, що мутує cargo-mutants навіть у monorepo з `src-tauri/`), пише його у sandbox і передає cargo-mutants `--in-diff`.
|
|
37
|
-
|
|
38
|
-
Краєві випадки: порожній diff (немає змін під crate) → mutation `0/0` без запуску cargo-mutants; невідомий ref / не git-репо → попередження у stderr і fallback до повного прогону.
|
|
39
|
-
|
|
40
|
-
### Пропуск baseline через `CARGO_MUTANTS_BASELINE=skip`
|
|
41
|
-
|
|
42
|
-
cargo-mutants спершу ганяє немутований baseline (повний build+test), щоб переконатися, що suite зелений. Це **фіксована** вартість, незалежна від кількості мутантів — а отже більша частка дрібного `--in-diff`-прогону. **`CARGO_MUTANTS_BASELINE=skip`** прибирає цей крок (cargo-mutants `--baseline skip`), економлячи один повний `cargo test`.
|
|
43
|
-
|
|
44
|
-
Безпечно **лише** коли тести вже зелені у попередньому CI-степі (типовий порядок: `cargo test` → потім `n-cursor coverage` зі `skip`). Без цієї гарантії всі вердикти стають сміттєвими, тому дефолт — baseline-прогін. Найкорисніше в парі з `--in-diff`.
|
|
45
|
-
|
|
46
|
-
### CI-кеш `target/` — множник, без якого scoping невидимий
|
|
47
|
-
|
|
48
|
-
`--in-diff` ріже **кількість** мутантів, кеш `target/` — **вартість кожної** компіляції; вони множаться. Без кешу холодний CI щоразу перебудовує всі залежності, і baseline-build (для Tauri — хвилини) затьмарює економію від меншої кількості мутантів. У workflow, що викликає `n-cursor coverage` для Rust, став `Swatinem/rust-cache@v2` (кеш `~/.cargo` + `target/`) після `dtolnay/rust-toolchain@stable` — так само, як у `lint-rust.yml`. Sandbox-копії `target/mutants.<i>/` самі не кешуються, але деривуються з кешованих залежностей.
|
|
17
|
+
- `rust.lint_rust_yml` — перевіряє `.github/workflows/lint-rust.yml`: наявність обов'язкових `uses` (`actions/checkout@v6`, `dtolnay/rust-toolchain@stable`, `Swatinem/rust-cache@v2`) та `run`-кроків з канону.
|
|
18
|
+
- `rust.vscode_extensions` — перевіряє `.vscode/extensions.json`: `recommendations` містить `rust-lang.rust-analyzer` і `tamasfe.even-better-toml`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Rego-полісі: `package.json` і CI workflow
|
|
2
|
+
|
|
3
|
+
### `security.package_json` — заборона `trufflehog` у залежностях
|
|
4
|
+
|
|
5
|
+
Перевіряє, що `trufflehog` не потрапив у `dependencies` або `devDependencies` — він є глобальним CLI і не повинен бути npm-залежністю.
|
|
6
|
+
|
|
7
|
+
- Канон deny-списку: [package.json.deny.json](../policy/package_json/template/package.json.deny.json)
|
|
8
|
+
|
|
9
|
+
### `security.lint_security_yml` — CI workflow з TruffleHog
|
|
10
|
+
|
|
11
|
+
Workflow `.github/workflows/lint-security.yml` обовʼязковий — забезпечує незалежний скан секретів на push/PR (агрегований `lint` локально + окремий fail-fast job на CI).
|
|
12
|
+
|
|
13
|
+
Перевіряється, що серед `uses:` є крок з `trufflesecurity/trufflehog@main`. Універсальні workflow-перевірки (checkout, permissions, persist-credentials) — у `ga.workflow_common`. Для повного скану історії потрібен `fetch-depth: 0`.
|
|
14
|
+
|
|
15
|
+
- Канон workflow: [lint-security.yml.snippet.yml](../policy/lint_security_yml/template/lint-security.yml.snippet.yml)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Placeholder для секретів — `sample-secret`
|
|
2
|
+
|
|
3
|
+
Фейкові credential-значення у **прикладних файлах** (`.env.example`, `.env.dist`, `*.example`, `*.sample`, `*.template`, вміст каталогів `fixtures/`) пиши як `sample-secret`, а не як bare `secret`.
|
|
4
|
+
|
|
5
|
+
`sample-secret` містить підрядок `sample` із вшитого списку `DefaultFalsePositives` TruffleHog — таке значення сканер відсіює **гарантовано** й незалежно від версії. Bare `secret` наразі не фіксується сканером лише тому, що випадково присутнє у словнику `fp_words.txt`; це крихка поведінка, що залежить від версії інструмента.
|
|
6
|
+
|
|
7
|
+
### Приклади
|
|
8
|
+
|
|
9
|
+
- Правильно: `DB_PASSWORD=sample-secret`, `password: "sample-secret"`
|
|
10
|
+
- Неправильно: `DB_PASSWORD=secret`, `password: "secret"`
|
|
11
|
+
|
|
12
|
+
### Що перевіряється
|
|
13
|
+
|
|
14
|
+
Перевіряється лише `secret` у позиції значення (після `=`, `:`, `=>`); імена ключів на кшталт `client_secret` не чіпаються.
|
|
15
|
+
|
|
16
|
+
Concern `security.sample_secret` (`js/sample_secret.mjs`) сканує всі прикладні файли:
|
|
17
|
+
- суфікс basename'а: `.example`, `.sample`, `.template`, `.dist`
|
|
18
|
+
- інфікс у basename'і: `.example.`, `.sample.`, `.template.`
|
|
19
|
+
- сегмент шляху: `fixtures/`, `fixture/`, `__fixtures__/`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## TruffleHog — налаштування та `.trufflehog-exclude`
|
|
2
|
+
|
|
3
|
+
[TruffleHog](https://github.com/trufflesecurity/trufflehog) — глобальний CLI (як `shellcheck`, `conftest`); **не** додавай до `dependencies`/`devDependencies`.
|
|
4
|
+
|
|
5
|
+
Скан запускається через `n-cursor lint security` (CI — `n-cursor lint security --read-only`); окремого `lint-*` скрипта в `package.json` немає.
|
|
6
|
+
|
|
7
|
+
### Ключові прапори запуску
|
|
8
|
+
|
|
9
|
+
- `trufflehog filesystem .` — сканує робоче дерево як директорію (включно з untracked/gitignored файлами); підкоманда `git file://.` лишається на CI для аудиту історії.
|
|
10
|
+
- `--no-update` — вимикає self-update check (CI-friendly).
|
|
11
|
+
- `--exclude-paths .trufflehog-exclude` — файл з regex-patterns, які треба пропускати (аналог `[allowlist].paths` із gitleaks).
|
|
12
|
+
- `--results=verified,unknown` — показує лише верифіковані секрети + ті, що TruffleHog не зміг перевірити (`unverified` дублікат відсіюється).
|
|
13
|
+
- `--fail` — exit-code `183` за наявності знахідок (щоб лінт падав).
|
|
14
|
+
|
|
15
|
+
### `.trufflehog-exclude` (рекомендована основа)
|
|
16
|
+
|
|
17
|
+
Канон (допускає розширення): [.trufflehog-exclude.snippet.txt](./templates/trufflehog/.trufflehog-exclude.snippet.txt)
|
|
18
|
+
|
|
19
|
+
**Важливо:** один regex-pattern на рядок, без TOML-обгортки; коментарі починаються з `#`.
|
|
20
|
+
|
|
21
|
+
Перевірка (JS): `js/trufflehog.mjs` — впевнюється, що файл `.trufflehog-exclude` існує в корені й містить канонічні шаблони.
|