@nitra/cursor 1.13.8 → 1.13.11
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 +43 -0
- package/package.json +1 -1
- package/rules/ga/ga.mdc +10 -15
- package/rules/ga/policy/package_json/package_json.rego +9 -13
- package/rules/ga/policy/package_json/template/package.json.contains.json +1 -0
- package/rules/ga/policy/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/ga/policy/vscode_extensions/vscode_extensions.rego +6 -4
- package/rules/ga/policy/vscode_settings/template/settings.json.snippet.json +1 -0
- package/rules/ga/policy/vscode_settings/vscode_settings.rego +11 -13
- package/rules/ga/policy/zizmor_yml/template/zizmor.yml.snippet.yml +5 -0
- package/rules/ga/policy/zizmor_yml/zizmor_yml.rego +16 -6
- package/rules/rego/lint/lint.mjs +5 -4
- package/rules/rego/policy/package_json/package_json.rego +8 -29
- package/rules/rego/policy/package_json/template/package.json.snippet.json +1 -0
- package/rules/rego/policy/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/rego/policy/vscode_extensions/vscode_extensions.rego +7 -11
- package/rules/rego/policy/vscode_settings/template/settings.json.snippet.json +6 -0
- package/rules/rego/policy/vscode_settings/vscode_settings.rego +19 -27
- package/rules/rego/rego.mdc +10 -8
- package/rules/security/todo.MD +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,49 @@
|
|
|
4
4
|
|
|
5
5
|
Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
|
|
6
6
|
|
|
7
|
+
## [1.13.11] - 2026-05-17
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `rego` rule template/ міграція (Phase 3): 3 концерни — `package_json` (snippet із збереженням `trim_space` tolerance), `vscode_extensions` (snippet-array), `vscode_settings` (snippet-object 2-level + окремий deny на non-object block).
|
|
12
|
+
- Drift-тести у кожному `*_test.rego`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- `rego.package_json.rego` — замість двох inline-deny (missing + wrong-value через `regex/trim_space`) тепер один snippet-walker через `data.template.snippet`.
|
|
17
|
+
- `rego.vscode_extensions.rego` — замість inline `"tsandall.opa"` тепер subset-of через `data.template.snippet.recommendations`.
|
|
18
|
+
- `rego.vscode_settings.rego` — 2-рівневий snippet-walker з гардом `is_object(inner)` для випадку, коли block існує, але не обʼєкт.
|
|
19
|
+
- `rego.mdc` — inline `package.json` snippet замінено на template-link; додано посилання на `.vscode/{extensions,settings}.json` template-файли. Виправлено застаріле `Цілі — npm/policy/` → `npm/rules/`.
|
|
20
|
+
- `docs/adr/template-dir-concern-inventory.md` — позначено 3 `rego.*` концерни як ✓; додано Phase 3 у прогрес-секцію.
|
|
21
|
+
|
|
22
|
+
## [1.13.10] - 2026-05-17
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- `runLintRego` (`npm/rules/rego/lint/lint.mjs`) — `LINT_TARGETS` вказував на застарілий шлях `npm/policy` (не існує після Phase 1 реструктуризації), тож `bun run lint-rego` мовчки exit 0 без реальної перевірки. Тепер `LINT_TARGETS = ['npm/rules']` — `opa check --strict`, `regal lint`, `conftest verify` реально проходять по всіх 111 `.rego`-файлах. TDD-регресія у `lint.test.mjs` (broken-syntax + well-formed fixtures).
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- `.regal/config.yaml` — додано `idiomatic.directory-package-mismatch` і `imports.unresolved-reference` у `ignore` (інтенціональні конвенції проєкту: package = `<rule>.<concern>` у `<rule>/policy/<concern>/`; `data.template.*` ін'єктиться runtime через `--data`). `style.line-length.max-line-length: 220` — узгоджено з `opa fmt` (тримає малі обʼєкти single-line).
|
|
31
|
+
- `*_test.rego` з порушенням `test-outside-test-package` (4 файли: `js-lint.jscpd`, `js-lint.vscode_extensions`, `security.gitleaks`, `vue.package_json`) — перейменовано в `<package>_test` із явним `import data.<package>`.
|
|
32
|
+
- `opa fmt -w npm/rules` — auto-fix форматування.
|
|
33
|
+
- `docs/adr/template-dir-concern-inventory.md` — додано 4 `ga.*` концерни з відміткою `✓` (мігровано); оновлено summary-числа (85 концернів, 39 з template — 46%); додано секцію прогресу міграції.
|
|
34
|
+
|
|
35
|
+
## [1.13.9] - 2026-05-17
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- `ga` rule template/ міграція (Phase 2): 4 концерни — `package_json` (contains-style), `vscode_extensions` (snippet-array), `vscode_settings` (snippet-object), `zizmor_yml` (snippet з канонічним path `rules.unpinned-uses.config.policies."*"`).
|
|
40
|
+
- Drift-тести (`test_data_template_drives_*`) у кожному `*_test.rego` ловлять регресію, якщо rego перестане читати з `data.template`.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- `ga.package_json.rego` — замість двох inline-deny з `is_string` + `regex.match` тепер один generic contains-walker через `data.template.contains`.
|
|
45
|
+
- `ga.vscode_extensions.rego` — замість inline `"github.vscode-github-actions"` тепер subset-of через `data.template.snippet.recommendations`.
|
|
46
|
+
- `ga.vscode_settings.rego` — 2-рівневий snippet-walker через `data.template.snippet` (літеральні keys `[github-actions-workflow]`, `editor.defaultFormatter`).
|
|
47
|
+
- `ga.zizmor_yml.rego` — замість substring `json.marshal` хака тепер структурний чек `rules.unpinned-uses.config.policies."*"` із expected value з `data.template.snippet`.
|
|
48
|
+
- `ga.mdc` — inline `package.json` snippet і `zizmor.yml` snippet блоки замінено на markdown-посилання на template-файли; додано посилання на нові template/ для `.vscode/{extensions,settings}.json`.
|
|
49
|
+
|
|
7
50
|
## [1.13.8] - 2026-05-17
|
|
8
51
|
|
|
9
52
|
### Changed
|
package/package.json
CHANGED
package/rules/ga/ga.mdc
CHANGED
|
@@ -242,11 +242,7 @@ jobs:
|
|
|
242
242
|
|
|
243
243
|
**Лінт:** [actionlint](https://github.com/rhysd/actionlint) через [github-actionlint](https://www.npmjs.com/package/github-actionlint); [zizmor](https://docs.zizmor.sh) — `uvx`, офлайн. Канонічний скрипт у корені делегує виконання CLI `n-cursor lint-ga` (бінарка з `node_modules/.bin/` пакету `@nitra/cursor`), який робить preflight на `shellcheck` і послідовно запускає `actionlint` та `zizmor`:
|
|
244
244
|
|
|
245
|
-
|
|
246
|
-
"scripts": {
|
|
247
|
-
"lint-ga": "n-cursor lint-ga"
|
|
248
|
-
}
|
|
249
|
-
```
|
|
245
|
+
- `package.json` — `scripts.lint-ga` має містити `n-cursor lint-ga`: [package.json.contains.json](./policy/package_json/template/package.json.contains.json)
|
|
250
246
|
|
|
251
247
|
> Не використовуй `npx --no @nitra/cursor lint-ga` — `bun run` автоматично транслює `npx` у `bun x`, а `bun x` для скоупованого пакету з одним bin-ім’ям повертає 0 без виконання. Виклик через bin-ім’я `n-cursor` працює і у `bun run`, і у `npm run`.
|
|
252
248
|
|
|
@@ -254,16 +250,15 @@ CLI робить preflight на `shellcheck` і `uv` (`uvx`) у `PATH`, поті
|
|
|
254
250
|
|
|
255
251
|
**`.github/zizmor.yml`:** для [unpinned-uses](https://docs.zizmor.sh/audits/#unpinned-uses) — політика **`ref-pin`**, якщо в `uses:` семантичні теги. За потреби вимкни [template-injection](https://docs.zizmor.sh/audits/#template-injection):
|
|
256
252
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
```
|
|
253
|
+
- Канон `.github/zizmor.yml`: [zizmor.yml.snippet.yml](./policy/zizmor_yml/template/zizmor.yml.snippet.yml)
|
|
254
|
+
|
|
255
|
+
**`.vscode/extensions.json`** має рекомендувати `github.vscode-github-actions`:
|
|
256
|
+
|
|
257
|
+
- Канон: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
|
|
258
|
+
|
|
259
|
+
**`.vscode/settings.json`** для мови `github-actions-workflow` має `editor.defaultFormatter = "oxc.oxc-vscode"`:
|
|
260
|
+
|
|
261
|
+
- Канон: [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
|
|
267
262
|
|
|
268
263
|
**MegaLinter:** не використовувати; прибрати workflow, конфіги (`.mega-linter.yml`, `.megalinter.yaml`, `.mega-linter.yaml`), залежності та згадки в CI / pre-commit / документації.
|
|
269
264
|
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
# Перевірка кореневого `package.json` для GitHub Actions tooling (ga.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# перевірки `on.*.paths` через `git ls-files`.
|
|
3
|
+
# Канон надходить через --data: { "template": { "contains": ... } }
|
|
4
|
+
# Структура --data сформована з template/package.json.contains.json.
|
|
6
5
|
#
|
|
7
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
8
6
|
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
9
7
|
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
10
8
|
package ga.package_json
|
|
11
9
|
|
|
12
10
|
import rego.v1
|
|
13
11
|
|
|
12
|
+
# Кожне рядкове поле з contains має містити кожен substring.
|
|
13
|
+
# Відсутність ключа → `""` → contains() = false → deny.
|
|
14
14
|
deny contains msg if {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
lint_ga := object.get(object.get(input, "scripts", {}), "lint-ga", "")
|
|
21
|
-
is_string(lint_ga)
|
|
22
|
-
not regex.match(`\bn-cursor\s+lint-ga\b`, lint_ga)
|
|
23
|
-
msg := "lint-ga має делегувати CLI `n-cursor lint-ga` (ga.mdc)"
|
|
15
|
+
some script_name, needles in data.template.contains.scripts
|
|
16
|
+
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
17
|
+
some needle in needles
|
|
18
|
+
not contains(actual, needle)
|
|
19
|
+
msg := sprintf("package.json: scripts.%s має містити %q (ga.mdc)", [script_name, needle])
|
|
24
20
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "scripts": { "lint-ga": ["n-cursor lint-ga"] } }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "recommendations": ["github.vscode-github-actions"] }
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Перевірка `.vscode/extensions.json` для GitHub Actions (ga.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/extensions.json.snippet.json.
|
|
5
|
+
# `recommendations` — subset-of: кожна рекомендація з template має бути у input.
|
|
4
6
|
# Додаткові рекомендації від інших правил дозволені.
|
|
5
7
|
#
|
|
6
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
7
8
|
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
8
9
|
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
9
10
|
package ga.vscode_extensions
|
|
@@ -11,6 +12,7 @@ package ga.vscode_extensions
|
|
|
11
12
|
import rego.v1
|
|
12
13
|
|
|
13
14
|
deny contains msg if {
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
some rec in data.template.snippet.recommendations
|
|
16
|
+
not rec in {r | some r in object.get(input, "recommendations", [])}
|
|
17
|
+
msg := sprintf(".vscode/extensions.json: recommendations має містити %q (ga.mdc)", [rec])
|
|
16
18
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "[github-actions-workflow]": { "editor.defaultFormatter": "oxc.oxc-vscode" } }
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Перевірка `.vscode/settings.json` для GitHub Actions workflow (ga.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/settings.json.snippet.json.
|
|
5
|
+
# Snippet — 2-рівнева мапа: <language-block-key>.<setting-key> = <expected>
|
|
6
|
+
# (VS Code-конвенція: ключі типу `[github-actions-workflow]` і `editor.defaultFormatter`
|
|
7
|
+
# — це літеральні string-keys із дужками/крапкою, не вкладені обʼєкти).
|
|
5
8
|
#
|
|
6
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
7
9
|
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
8
10
|
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
9
11
|
package ga.vscode_settings
|
|
@@ -11,14 +13,10 @@ package ga.vscode_settings
|
|
|
11
13
|
import rego.v1
|
|
12
14
|
|
|
13
15
|
deny contains msg if {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
block := object.get(input, "[github-actions-workflow]", null)
|
|
21
|
-
is_object(block)
|
|
22
|
-
object.get(block, "editor.defaultFormatter", null) != "oxc.oxc-vscode"
|
|
23
|
-
msg := ".vscode/settings.json: [github-actions-workflow].editor.defaultFormatter має бути \"oxc.oxc-vscode\" (ga.mdc)"
|
|
16
|
+
some block_key, expected_inner in data.template.snippet
|
|
17
|
+
inner := object.get(input, block_key, {})
|
|
18
|
+
some leaf_key, expected_value in expected_inner
|
|
19
|
+
actual := object.get(inner, leaf_key, null)
|
|
20
|
+
actual != expected_value
|
|
21
|
+
msg := sprintf(".vscode/settings.json: %s.%s має бути %q (ga.mdc)", [block_key, leaf_key, expected_value])
|
|
24
22
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Перевірка `.github/zizmor.yml` для GitHub Actions (ga.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/zizmor.yml.snippet.yml.
|
|
5
|
+
# Канонічний шлях — `rules.unpinned-uses.config.policies."*"`; expected value
|
|
6
|
+
# (наприклад `"ref-pin"`) приходить із template, path лишається тут.
|
|
6
7
|
#
|
|
7
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
8
8
|
# Конвенція проєкту — `import rego.v1` + multi-value `deny contains msg if { … }`
|
|
9
9
|
# (.cursor/rules/conftest.mdc). Лінт — `bun run lint-rego` (regal).
|
|
10
10
|
package ga.zizmor_yml
|
|
@@ -12,6 +12,16 @@ package ga.zizmor_yml
|
|
|
12
12
|
import rego.v1
|
|
13
13
|
|
|
14
14
|
deny contains msg if {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
expected := data.template.snippet.rules["unpinned-uses"].config.policies["*"]
|
|
16
|
+
policies := object.get(
|
|
17
|
+
object.get(
|
|
18
|
+
object.get(object.get(input, "rules", {}), "unpinned-uses", {}),
|
|
19
|
+
"config",
|
|
20
|
+
{},
|
|
21
|
+
),
|
|
22
|
+
"policies",
|
|
23
|
+
{},
|
|
24
|
+
)
|
|
25
|
+
object.get(policies, "*", null) != expected
|
|
26
|
+
msg := sprintf(".github/zizmor.yml: rules.unpinned-uses.config.policies[%q] має бути %q (ga.mdc)", ["*", expected])
|
|
17
27
|
}
|
package/rules/rego/lint/lint.mjs
CHANGED
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
* потрібен VS Code-розширенню `tsandall.opa` (LSP, format-on-save через `opa fmt`) — деталі в
|
|
19
19
|
* `mdc/rego.mdc`.
|
|
20
20
|
*
|
|
21
|
-
* Цілі лінту: `npm/
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* Цілі лінту: `npm/rules/` (де живуть Rego-полісі пакета `@nitra/cursor` — у
|
|
22
|
+
* `npm/rules/<id>/policy/<concern>/`). Усі три інструменти приймають один шлях
|
|
23
|
+
* і самі рекурсивно знаходять `.rego` (ігноруючи інші розширення на кшталт
|
|
24
|
+
* `target.json` чи template-фіх).
|
|
24
25
|
*/
|
|
25
26
|
import { spawnSync } from 'node:child_process'
|
|
26
27
|
import { existsSync } from 'node:fs'
|
|
@@ -30,7 +31,7 @@ import { isRunAsCli } from '../../../scripts/cli-entry.mjs'
|
|
|
30
31
|
import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
|
|
31
32
|
|
|
32
33
|
/** Шляхи з Rego-полісі (відносно cwd). Існують не всі на ранніх стадіях — фільтруємо нижче. */
|
|
33
|
-
const LINT_TARGETS = ['npm/
|
|
34
|
+
const LINT_TARGETS = ['npm/rules']
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Друкує підказку зі встановлення `opa` (потрібен для `opa check --strict` і VS Code LSP).
|
|
@@ -1,37 +1,16 @@
|
|
|
1
1
|
# Перевірка `package.json` для rego (rego.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# (бінарка з `node_modules/.bin/`) робить preflight `opa`/`regal` і прогонить
|
|
8
|
-
# `opa check --strict` → `regal lint` → опц. `conftest verify` (`@nitra/cursor lint-rego`).
|
|
9
|
-
#
|
|
10
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/package.json.snippet.json.
|
|
5
|
+
# Дозволяємо whitespace навколо значення (trim_space) — допуск, який мав
|
|
6
|
+
# попередній inline-варіант.
|
|
11
7
|
package rego.package_json
|
|
12
8
|
|
|
13
9
|
import rego.v1
|
|
14
10
|
|
|
15
|
-
canonical_lint_rego := "n-cursor lint-rego"
|
|
16
|
-
|
|
17
|
-
lint_rego_template := concat(" ", [
|
|
18
|
-
"package.json: scripts.lint-rego має бути %q",
|
|
19
|
-
"(зараз: %q) (rego.mdc)",
|
|
20
|
-
])
|
|
21
|
-
|
|
22
|
-
deny contains msg if {
|
|
23
|
-
scripts := object.get(input, "scripts", {})
|
|
24
|
-
not "lint-rego" in object.keys(scripts)
|
|
25
|
-
msg := concat(" ", [
|
|
26
|
-
"package.json: відсутній scripts.lint-rego — додай",
|
|
27
|
-
"\"lint-rego\": \"n-cursor lint-rego\" (rego.mdc)",
|
|
28
|
-
])
|
|
29
|
-
}
|
|
30
|
-
|
|
31
11
|
deny contains msg if {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
msg := sprintf(lint_rego_template, [canonical_lint_rego, lint_rego])
|
|
12
|
+
some script_name, expected in data.template.snippet.scripts
|
|
13
|
+
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
14
|
+
trim_space(actual) != expected
|
|
15
|
+
msg := sprintf("package.json: scripts.%s має бути %q (rego.mdc)", [script_name, expected])
|
|
37
16
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "scripts": { "lint-rego": "n-cursor lint-rego" } }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "recommendations": ["tsandall.opa"] }
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
# Перевірка `.vscode/extensions.json` для rego (rego.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# Canonical (rego.mdc): `recommendations` має містити `tsandall.opa`.
|
|
9
|
-
#
|
|
10
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/extensions.json.snippet.json.
|
|
5
|
+
# `recommendations` — subset-of: кожна рекомендація з template має бути у input.
|
|
6
|
+
# Додаткові рекомендації від інших правил дозволені.
|
|
11
7
|
package rego.vscode_extensions
|
|
12
8
|
|
|
13
9
|
import rego.v1
|
|
14
10
|
|
|
15
11
|
deny contains msg if {
|
|
16
|
-
|
|
17
|
-
not
|
|
18
|
-
msg := ".vscode/extensions.json: recommendations має містити
|
|
12
|
+
some rec in data.template.snippet.recommendations
|
|
13
|
+
not rec in {r | some r in object.get(input, "recommendations", [])}
|
|
14
|
+
msg := sprintf(".vscode/extensions.json: recommendations має містити %q (rego.mdc)", [rec])
|
|
19
15
|
}
|
|
@@ -1,38 +1,30 @@
|
|
|
1
1
|
# Перевірка `.vscode/settings.json` для rego (rego.mdc).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# "editor.formatOnSave": true } }
|
|
9
|
-
#
|
|
10
|
-
# Структура каталогу збігається зі шляхом пакету (regal: directory-package-mismatch).
|
|
3
|
+
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
+
# Структура --data сформована з template/settings.json.snippet.json.
|
|
5
|
+
# Snippet — 2-рівнева мапа: <language-block-key>.<setting-key> = <expected>
|
|
6
|
+
# (VS Code-конвенція: ключі `[rego]` і `editor.defaultFormatter`/`editor.formatOnSave`
|
|
7
|
+
# — це літеральні string-keys із дужками/крапкою, не вкладені обʼєкти).
|
|
11
8
|
package rego.vscode_settings
|
|
12
9
|
|
|
13
10
|
import rego.v1
|
|
14
11
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
deny contains msg if {
|
|
18
|
-
not is_object(object.get(input, "[rego]", null))
|
|
19
|
-
msg := concat(" ", [
|
|
20
|
-
".vscode/settings.json: \"[rego]\" має бути обʼєктом з",
|
|
21
|
-
"\"editor.defaultFormatter\": \"tsandall.opa\" і",
|
|
22
|
-
"\"editor.formatOnSave\": true (rego.mdc)",
|
|
23
|
-
])
|
|
24
|
-
}
|
|
25
|
-
|
|
12
|
+
# Leaf-by-leaf: працює коли block присутній і є обʼєктом.
|
|
26
13
|
deny contains msg if {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
some block_key, expected_inner in data.template.snippet
|
|
15
|
+
inner := object.get(input, block_key, {})
|
|
16
|
+
is_object(inner)
|
|
17
|
+
some leaf_key, expected_value in expected_inner
|
|
18
|
+
actual := object.get(inner, leaf_key, null)
|
|
19
|
+
actual != expected_value
|
|
20
|
+
msg := sprintf(".vscode/settings.json: %s.%s має бути %v (rego.mdc)", [block_key, leaf_key, expected_value])
|
|
31
21
|
}
|
|
32
22
|
|
|
23
|
+
# Block існує, але не обʼєкт (напр. рядок) — окрема помилка типу.
|
|
33
24
|
deny contains msg if {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
some block_key in object.keys(data.template.snippet)
|
|
26
|
+
raw := object.get(input, block_key, null)
|
|
27
|
+
raw != null
|
|
28
|
+
not is_object(raw)
|
|
29
|
+
msg := sprintf(".vscode/settings.json: %s має бути обʼєктом (rego.mdc)", [block_key])
|
|
38
30
|
}
|
package/rules/rego/rego.mdc
CHANGED
|
@@ -15,19 +15,21 @@ alwaysApply: false
|
|
|
15
15
|
bun run lint-rego
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
Цілі — `npm/policy
|
|
18
|
+
Цілі — `npm/rules/` (рекурсивно знаходить `.rego` у `<rule>/policy/<concern>/`). Інші *.rego поза деревом додай у `LINT_TARGETS` у `npm/rules/rego/lint/lint.mjs`.
|
|
19
19
|
|
|
20
20
|
`opa` і `regal` — лише у `PATH`, **не** додавай у `dependencies` / `devDependencies`.
|
|
21
21
|
|
|
22
22
|
### `package.json`
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
- Канон `scripts.lint-rego`: [package.json.snippet.json](./policy/package_json/template/package.json.snippet.json)
|
|
25
|
+
|
|
26
|
+
### `.vscode/extensions.json`
|
|
27
|
+
|
|
28
|
+
- Канон `recommendations` має містити `tsandall.opa` (LSP, format-on-save через `opa fmt`): [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
|
|
29
|
+
|
|
30
|
+
### `.vscode/settings.json`
|
|
31
|
+
|
|
32
|
+
- Канон `[rego]`-block (`editor.defaultFormatter` + `editor.formatOnSave`): [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
|
|
31
33
|
|
|
32
34
|
## Конфіг regal
|
|
33
35
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# TODO:
|
|
2
|
+
|
|
3
|
+
## semgrep --config p/kubernetes
|
|
4
|
+
|
|
5
|
+
p/security-audit
|
|
6
|
+
|
|
7
|
+
p/secrets
|
|
8
|
+
|
|
9
|
+
p/nodejs
|
|
10
|
+
|
|
11
|
+
p/javascript
|
|
12
|
+
|
|
13
|
+
p/typescript
|
|
14
|
+
|
|
15
|
+
p/docker
|
|
16
|
+
|
|
17
|
+
p/kubernetes
|
|
18
|
+
|
|
19
|
+
## Trivy
|
|
20
|
+
Найцінніша частина Trivy
|
|
21
|
+
|
|
22
|
+
НЕ image scanning. А:
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
config scanning
|
|
26
|
+
+
|
|
27
|
+
Kubernetes scanning
|