@7n/rules 1.44.1 → 1.46.0

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 CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.46.0] - 2026-07-23
4
+
5
+ ### Added
6
+
7
+ - концерн coverage правила test: гейт покриття/мутаційки як lint-детектор (--no-fix = CI-гейт), CoverageProvider порт у plugin-api (spec 2026-07-22 absorb-7n-test)
8
+ - coverage: спільні lib manifest-roots/lcov, подовжений full-таймаут для мутаційного тестування (×4), пілот classify (0.7) у цьому репо
9
+
10
+ ### Changed
11
+
12
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
13
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
14
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
15
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
16
+ - doc_comments rollout: header/export JSDoc у конфігах demo
17
+ - doc_comments rollout: header-JSDoc у vitest.config
18
+
19
+ ## [1.45.0] - 2026-07-23
20
+
21
+ ### Added
22
+
23
+ - концерн coverage правила test: гейт покриття/мутаційки як lint-детектор (--no-fix = CI-гейт), CoverageProvider порт у plugin-api (spec 2026-07-22 absorb-7n-test)
24
+
25
+ ### Changed
26
+
27
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
28
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
29
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
30
+ - doc_comments rollout: header-JSDoc у vitest.config (T0 promote)
31
+ - doc_comments rollout: header/export JSDoc у конфігах demo
32
+ - doc_comments rollout: header-JSDoc у vitest.config
33
+
3
34
  ## [1.44.1] - 2026-07-23
4
35
 
5
36
  ### Changed
@@ -3,28 +3,25 @@ type: JS Module
3
3
  title: stryker.config.mjs
4
4
  resource: npm/stryker.config.mjs
5
5
  docgen:
6
- crc: 2f4ed270
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: cb7d2219
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
8
9
  score: 100
10
+ judgeModel: openai-codex/gpt-5.4-mini
9
11
  ---
10
12
 
11
- Цей файл конфігурує процес тестування та мутаційного аналізу, використовуючи Vitest як тестовий раннер. Він визначає, які файли підлягають мутації (у `scripts`, `rules`, `bin`) та які виключаються, спираючись на `mutation.json`. Конфігурація налаштовує Stryker для запуску лише тестів, що покривають мутовані рядки. Також конфігурація використовує `incremental.json` для збереження даних між запусками.
13
+ ## Огляд
14
+
15
+ Файл описує конфігурацію Stryker для `@7n/rules`, щоб запускати `vitest-runner` з `perTest`-покриттям на production-коді в `scripts/`, `rules/` і `bin/`, не зачіпаючи фікстури та baseline-шаблони.
12
16
 
13
17
  ## Поведінка
14
18
 
15
- 1. Визначає тестовий раннер як Vitest.
16
- 2. Вказує конфігураційний файл для Vitest.
17
- 3. Налаштовує аналіз покриття так, що Stryker запускає лише тести, що покривають мутовану лінію.
18
- 4. Встановлює тимчасову директорію для звітів Stryker.
19
- 5. Визначає репортери для виводу результатів у форматі JSON та звичайному тексті.
20
- 6. Вказує ім'я файлу для JSON-звіту.
21
- 7. Вмикає функціонал збереження результатів між запусками, використовуючи файл `incremental.json`.
22
- 8. Визначає список файлів, які підлягають мутації:
23
- - Файли у директорії `scripts`.
24
- - Файли у директорії `rules`.
25
- - Файли у директорії `bin`.
26
- 9. Виключає з мутації файли у директоріях `tests`, `__fixtures__`, `fixtures`, `data`, `template`, `templates`.
27
- 10. Виключає з мутації файли у директорії `data`, крім файлу `stryker-vue-macros-ignorer.mjs` у директорії `rules/test/js/data/stryker_config/`.
19
+ 1. Запускає мутаційне тестування коду `@7n/rules` через `vitest-runner`, щоб оцінити, як добре тести виявляють зміни в production-логіці.
20
+ 2. Перевіряє лише лінії, які реально зачіпаються тестами, щоб зосередити аналіз на корисному сигналі, а не на повному повторному прогоні всього набору.
21
+ 3. Зберігає службові артефакти звіту в `reports/stryker/`, зокрема `mutation.json`, щоб результат можна було переглядати й обробляти далі.
22
+ 4. Підтримує інкрементальний режим через `incremental.json`, щоб повторні запуски відновлювали попередній стан мутаційної оцінки.
23
+ 5. Мутує основний production-код у `scripts/`, `rules/` і `bin/`, а каталоги `**/data/**` і `**/template/**` та `**/templates/**` не включає.
24
+ 6. Окремо включає `rules/test/js/data/stryker_config/stryker-vue-macros-ignorer.mjs`.
28
25
 
29
26
  ## Гарантії поведінки
30
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/rules",
3
- "version": "1.44.1",
3
+ "version": "1.46.0",
4
4
  "description": "CLI еталонних правил і skills (префікс n-): синк у репозиторій, дельта-lint, конформність",
5
5
  "keywords": [
6
6
  "cli",
@@ -3,29 +3,31 @@ type: JS Module
3
3
  title: http-route.mjs
4
4
  resource: npm/rules/abie/lib/http-route.mjs
5
5
  docgen:
6
- crc: c3626280
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
- tier: local-min-retry
6
+ crc: d88f96a3
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
9
9
  score: 100
10
- issues: judge:inaccurate:0.98
11
10
  judgeModel: openai-codex/gpt-5.4-mini
12
11
  ---
13
12
 
14
13
  ## Огляд
15
14
 
16
- Цей файл здійснює крос-документну аналітику HTTPRoute, використовуючи `ABIE_SHARED_CROSS_NS_BACKEND_NAMES` та `analyzeAbieSharedBackendRefsInPackageK8s`. Він підраховує кількість посилань на спільні сервіси (`auth-run-hl`, `file-link-hl`) у base-маніфестах пакета, ігноруючи overlay `ua`. Мета полягає у синхронізації числа `patch`-ів namespace в overlay з кількістю base-reference, що гарантує узгодженість конфігурації (abie.mdc).
15
+ `analyzeAbieSharedBackendRefsInPackageK8s` рахує `backendRefs` у base-маніфестах пакета, що вказують на спільні cross-namespace `-hl` сервіси з набору `ABIE_SHARED_CROSS_NS_BACKEND_NAMES`, і не враховує overlay `ua`. Це дає `ua_http_route` змогу синхронізувати кількість namespace patch-ів в overlay із фактичною кількістю base-reference до shared backend.
17
16
 
18
17
  ## Поведінка
19
18
 
20
- Поведінка:
21
- ABIE_SHARED_CROSS_NS_BACKEND_NAMES: Надає список назв спільних сервісів (`auth-run-hl`, `file-link-hl`), до яких здійснюється аналіз.
22
- analyzeAbieSharedBackendRefsInPackageK8s: Підраховує кількість посилань на спільні сервіси (`auth-run-hl`, `file-link-hl`) у base-маніфестах пакета, що знаходяться поза overlay `ua`, і виявляє порушення вимог конфігурації, використовуючи маркер (abie.mdc).
19
+ ABIE_SHARED_CROSS_NS_BACKEND_NAMES задає спільний перелік cross-namespace `-hl` сервісів, на який орієнтується вся перевірка; цей набір використовується як єдине джерело істини для того, що вважається shared backend.
20
+
21
+ analyzeAbieSharedBackendRefsInPackageK8s проходить по YAML-маніфестах пакета в base-шарі, свідомо оминаючи overlay `ua`, і збирає лише ті HTTPRoute-документи, які реально посилаються на спільні сервіси. Для кожного такого посилання воно підсумовує кількість `backendRefs` і накопичує порушення, якщо shared backend вказано не через `namespace: dev` або без очікуваного `port: 8080` згідно з (abie.mdc).
22
+
23
+ Результат роботи повертається як агрегована статистика для подальшої синхронізації кількості namespace-patch-ів в overlay із фактичною кількістю base-reference; помилки повертаються окремим списком, щоб викликальний концерн міг показати саме ті місця, де базовий HTTPRoute виходить за правилами shared cross-namespace доступу.
23
24
 
24
25
  ## Публічний API
25
26
 
26
- ABIE_SHARED_CROSS_NS_BACKEND_NAMES — Список імен бекендів, які знаходяться в загальному просторі імен (cross-namespace) для спільного використання.
27
- analyzeAbieSharedBackendRefsInPackageK8s — Підраховує у YAML-файлах пакета (за винятком overlay ua) кількість посилань на shared-hl backendRefs та виявляє базові помилки (за винятком namespace: dev).
27
+ - ABIE_SHARED_CROSS_NS_BACKEND_NAMES — Імена спільних headless-сервісів, на які HTTPRoute-и пакетів посилаються крізь namespace.
28
+ - analyzeAbieSharedBackendRefsInPackageK8s — Збирає по yaml-файлах пакета (поза overlay ua) кількість shared-`-hl` `backendRefs`
29
+ і базові помилки (без `namespace: dev`).
28
30
 
29
31
  ## Гарантії поведінки
30
32
 
31
- - Read-only: не виконує операцій запису (ФС/БД).
33
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,31 +3,43 @@ type: JS Module
3
3
  title: yaml.mjs
4
4
  resource: npm/rules/abie/lib/yaml.mjs
5
5
  docgen:
6
- crc: 1b50e492
6
+ crc: b15223d7
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
9
+ score: 100
10
+ issues: judge-refine:kept-original,judge:inaccurate:0.97
11
+ judgeModel: openai-codex/gpt-5.4-mini
7
12
  ---
8
13
 
9
- Спільний набір YAML-хелперів для перевірок правила `abie`. Інкапсулює читання й розбір YAML-файлів Kubernetes-маніфестів так, щоб усі abie-перевірки розбирали вміст однаково: з прибиранням BOM, ігноруванням службового modeline-рядка `# yaml-language-server: $schema=` і fail-safe-поведінкою при пошкоджених файлах.
14
+ ## Огляд
15
+
16
+ Спільні YAML-хелпери для abie-перевірок: `stripBom` прибирає BOM на початку тексту, `MODELINE_RE` розпізнає службовий рядок `# yaml-language-server: $schema=`, а `LINE_SPLIT_RE` ділить вміст на рядки. `readAndParseYamlDocs` читає YAML як набір документів, `isDeploymentDoc` відокремлює документи потрібного типу, а `silentFail` дає fail-safe поведінку: за непридатного вмісту або помилки повертається порожнє значення замість винятку.
10
17
 
11
18
  ## Поведінка
12
19
 
13
- Читання й розбір YAML-документів з файлу:
20
+ MODELINE_RE і LINE_SPLIT_RE задають спільні правила нормалізації вхідного YAML: перший виявляє службовий modeline на початку файлу, другий уніфікує розбиття тексту на рядки незалежно від переносу.
21
+
22
+ stripBom прибирає початковий BOM перед подальшою обробкою, щоб наступні кроки працювали з чистим вмістом без артефактів кодування.
14
23
 
15
- 1. Намагається прочитати файл за абсолютним шляхом. Якщо читання не вдалося викликає переданий обробник помилок із повідомленням, що включає відносний шлях і причину, і повертає `null`.
16
- 2. Прибирає BOM на початку вмісту, якщо він є.
17
- 3. Якщо перший рядок — це YAML-language-server modeline (`# yaml-language-server: $schema=...`), пропускає його перед розбором; решта вмісту парситься без нього. Інакше парситься весь вміст.
18
- 4. Розбирає всі YAML-документи у файлі (мультидокументні файли з `---` підтримуються). При помилці розбору викликає обробник помилок із повідомленням і повертає `null`; інакше повертає масив розібраних документів.
24
+ readAndParseYamlDocs є основним потоком: читає файл, нормалізує вміст через stripBom, відсікає modeline, якщо він є першим рядком, і лише тоді передає результат у YAML-парсинг. Успішний результат повертається далі як набір YAML-документів, а будь-яка проблема читання або парсингу перетворюється на повідомлення через failFn і завершується без винятку назовні.
19
25
 
20
- Окремо надає предикат розпізнавання маніфестів `Deployment`: документ вважається `Deployment`, лише якщо це звичайний об'єкт (не масив, не `null`) із полем `kind` рівним `'Deployment'`.
26
+ silentFail використовується як нейтральний обробник помилок для сценаріїв, де зіпсований або непридатний YAML не має зупиняти перевірку; у такому режимі помилка свідомо приглушується, а контроль залишається у викликача.
21
27
 
22
- Передбачено готовий «тихий» обробник помилок для викликів, які мають мовчки повертати порожній результат при поганому вводі, бо пошкоджені файли діагностує окрема перевірка (`check-k8s`), а не abie.
28
+ isDeploymentDoc відокремлює лише документи потрібного виду для подальших перевірок, щоб решта YAML не проходила через специфічну логіку abie-здач.
23
29
 
24
- ## Де використовується
30
+ ## Публічний API
25
31
 
26
- Хелпери імпортуються іншими модулями abie, що аналізують Kubernetes-маніфести, зокрема `lib/k8s-tree.mjs`, `lib/kustomization-patches.mjs`, `lib/http-route.mjs`, `lib/hc-yaml.mjs` та перевіркою `js/hc_pairing.mjs`.
32
+ - MODELINE_RE Розпізнає modeline `yaml-language-server` з `$schema=` у першому рядку файлу; захоплює URL схеми.
33
+ - LINE_SPLIT_RE — Поділ вмісту на рядки незалежно від стилю переносу (LF чи CRLF).
34
+ - stripBom — Прибирає BOM на початку файлу.
35
+ - isDeploymentDoc — Чи YAML-документ — це `kind: Deployment`.
36
+ - silentFail — No-op fail-handler для функцій, що мовчки повертають null/[] при помилці парсингу.
37
+ - readAndParseYamlDocs — Зчитує і парсить YAML-документи з файлу. BOM і modeline (перший рядок `$schema`)
38
+ автоматично прибираються перед `parseAllDocuments`. При помилці читання/парсингу
39
+ викликає `failFn` і повертає `null`.
27
40
 
28
41
  ## Гарантії поведінки
29
42
 
30
- - Read-only: модуль лише читає й розбирає файли, не змінює їх.
31
- - Fail-safe: помилки читання чи розбору YAML не кидаються назовні — натомість викликається переданий обробник, а результатом стає `null`. Це дозволяє перевіркам пропускати биті файли замість падіння.
32
- - Розбір стійкий до BOM і до службового modeline-рядка `$schema` на першому рядку — вони не ламають парсинг і не потрапляють у результат.
33
- - Предикат розпізнавання `Deployment` безпечний для будь-якого вводу: повертає `false` для `null`, масивів і не-об'єктів, ніколи не кидає винятків.
43
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
44
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
45
+ - За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
@@ -3,28 +3,28 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: npm/rules/ci4/marksman_config/main.mjs
5
5
  docgen:
6
- crc: c34fa8be
6
+ crc: 259b7df5
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
+ tier: local-min-retry
8
9
  score: 100
9
- issues: judge:inaccurate:0.99
10
+ issues: judge:error
10
11
  judgeModel: openai-codex/gpt-5.4-mini
11
12
  ---
12
13
 
13
14
  ## Огляд
14
15
 
15
- Оновлений текст секції «overview» (як вимагається, без попередньої преамбули та згідно з інструкціями):
16
-
17
- Це файловий модуль відповідає за забезпечення певної функціональної області системи. Він виконує аналіз даних у межах визначених логічних кордонів. У своїй поведінці він обов'язково включає маркери повідомлень згідно з `ci4.mdc`.
16
+ Файл виконує перевірку конфігураційних даних у робочому каталозі. Він вимагає наявності канонічного конфігу, визначеного константою MARKSMAN_BASELINE_PATH, для коректної роботи системи, і при його відсутності вказує на необхідність відновлення пакета правил. Крім того, визначається цільовий файл MARKSMAN_TARGET_FILENAME, і ця функція повідомляє про його успішне знаходження або про необхідність ініціалізації. Доступна функція lint виконує перевірку відповідно до визначених конфігурацій.
18
17
 
19
18
  ## Поведінка
20
19
 
21
- 1. Викликається функція main.
22
- 2. Перевіряється наявність канонічного baseline-файлу у шляху, відносно розташування поточного файлу.
23
- 3. Якщо baseline-файл не знайдено, видається повідомлення про помилку (ci4.mdc) та процес завершується з відповідним кодом виходу.
24
- 4. Перевіряється наявність цільового файлу .marksman.toml у корені проєкту.
25
- 5. Якщо цільовий файл існує, видається повідомлення про успіх, і процес завершується з кодом виходу 0.
26
- 6. Якщо цільовий файл не існує, канонічний baseline-файл копіюється у цільовий файл .marksman.toml у корені проєкту, і видається повідомлення про успіх (ci4.mdc).
20
+ При запуску `lint` системи перевіряє наявність файлу `MARKSMAN_BASELINE_PATH`, який є канонічним конфігом, що постачається з пакетом правил; якщо він відсутній, система повідомляє про помилку, що вказує на необхідність перевстановлення пакета `@7n/rules`. Потім система шукає у робочому каталозі файл, визначений у `MARKSMAN_TARGET_FILENAME` (`.marksman.toml`); якщо він знайдений, система повідомляє про успіх. Якщо ж файл відсутній, система повідомляє про необхідність копіювання канонічного baseline-конфігу, посилаючись на правило (ci4.mdc).
21
+
22
+ ## Публічний API
23
+
24
+ - MARKSMAN_BASELINE_PATH Абсолютний шлях до канонічного baseline-конфігу marksman, що постачається разом із пакетом правил.
25
+ - MARKSMAN_TARGET_FILENAME Імʼя конфіг-файлу marksman, який має лежати в корені репозиторію.
26
+ - lint — Перевіряє наявність `.marksman.toml` у корені; сигналить копіювання canonical baseline.
27
27
 
28
28
  ## Гарантії поведінки
29
29
 
30
- - Read-only: не виконує операцій запису (ФС/БД).
30
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,46 +3,75 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: npm/rules/doc-files/docgen-prompts/main.mjs
5
5
  docgen:
6
- crc: 465da2eb
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: 8cb3a892
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
8
9
  score: 100
9
- issues: judge:inaccurate:0.99
10
+ issues: judge-refine:kept-original,judge:inaccurate:0.99
10
11
  judgeModel: openai-codex/gpt-5.4-mini
11
12
  ---
12
13
 
13
14
  ## Огляд
14
15
 
15
- Будь ласка, надайте чорнетку секції «overview» для редагування.
16
+ Файл формує промпти й детерміновані фрагменти для генерації поведінкової документації: `STYLE` задає спільний тон, `sectionMessages`, `overviewMessages`, `criticMessages`, `refineMessages`, `oneShotMessages` і `judgeRefineMessages` готують повідомлення для різних етапів, `isApiGap`, `renderApiLine` та `apiGapMessages` висвітлюють прогалини API, а `guaranteesFromMarkers` і `buildUnitDigest` стискають контекст до контрольованого обсягу `UNIT_DIGEST_TOKENS`. Файл існує як текстовий шар оркестратора документації, щоб підтримувати лаконічний стиль, узгоджувати очікування між етапами генерації та зменшувати ризик вигаданих тверджень. У межах одного прогону використовує кешування для повторного використання вже підготовлених результатів.
16
17
 
17
18
  ## Поведінка
18
19
 
19
- sectionMessages.main.mjs
20
+ STYLE задає спільні правила тону й форми для промптів, щоб усі згенеровані секції лишалися лаконічними, поведінковими та без технічного шуму.
20
21
 
21
- ````
22
- Ти технічний письменник. Пишеш лаконічну ПОВЕДІНКОВУ документацію до коду українською, чистим Markdown.
23
- Пиши ЩО і НАВІЩО, не ЯК. Без вступів і висновків. Не обгортай у ```-блок.
24
- Заборонено: сигнатури, типи, параметри функцій; перелік stdlib-модулів; опис regex чи внутрішніх приватних імен.
22
+ Основний потік генерації розділяє документацію на незалежні кроки. sectionMessages формує запит лише для секції «Поведінка» з мінімальним контекстом: фактами про файл, релевантними анкорами, захищеним «Призначенням» і, за потреби, стислим представленням коду. Після отримання готової «Поведінки» overviewMessages створює «Огляд» уже з неї, а не напряму з коду, щоб підсумок спирався на підтверджений опис поведінки.
25
23
 
26
- Напиши вміст секції «Поведінка»: для кожної публічної функції один короткий пункт «що вона робить». Описуй РІВНО ці публічні імена і жодних інших: STYLE, sectionMessages, overviewMessages, criticMessages, refineMessages, guaranteesFromMarkers, oneShotMessages. Якщо у фактах є свідомі пропуски шляхів згадай їх там, де доречно (не вигадуй інших «не перевіряє»). НЕ пиши аргументи функцій у дужках, без regex. НЕ згадуй за іменами службові функції: anchorsToPrompt. Без заголовка, без додаткових ## чи # підзаголовків усередині секції.
27
- ````
24
+ Публічний API обробляється гібридно без зайвого LLM-переписування. isApiGap визначає, які експорти не мають змістовного опису. Для покритих описом експортів renderApiLine повертає дослівний рядок документації, зберігаючи авторський текст. Для прогалин apiGapMessages формує окремий вузький запит тільки по відсутніх описах, щоб модель не торкалася вже надійних JSDoc-фрагментів.
28
25
 
29
- ## Публічний API
26
+ Якість машинних секцій підсилюється окремим циклом перевірки. criticMessages готує запит до критика, який має знайти конкретні дефекти або підтвердити їх відсутність. refineMessages використовує ці зауваження для переписування чорнетки без зміни призначення секції. judgeRefineMessages виконує точкове доопрацювання документа за причиною від судді, коли потрібно виправити конкретне хибне твердження замість просто позначити результат як погіршений.
27
+
28
+ guaranteesFromMarkers створює «Гарантії поведінки» детерміновано з маркерів факт-листа, без LLM-запиту. Це відокремлює формальні гарантії від вільного тексту й зменшує ризик вигаданих тверджень.
30
29
 
31
- Згідно з інструкцією з `/Users/vitalii/www/nitra/cursor/AGENTS.md`, моя функція генерувати лаконічну поведінкову документацію українською мовою в чистому Markdown для кожного зміненого/нового кодового файлу, у вигляді списку маркерів.
30
+ oneShotMessages лишається базовим одноетапним сценарієм для порівняння з секційним потоком. UNIT_DIGEST_TOKENS задає межу компактного представлення великих файлів, а buildUnitDigest перетворює набір юнітів на стислий дайджест, щоб промпт зберігав фокус на структурі й поведінці замість перевантаження сирим кодом.
32
31
 
33
- Ви надаєте мені список термінів та просите перетворити його на стиль: `«назва що робить»`, використовуючи власні слова, без копіювання дослівно, без типів і сигнатур.
32
+ Файл не виконує власних записів у файлову систему чи базу даних: результати всіх публічних функцій повертаються як текстові секції, рядки або масиви повідомлень для подальшої обробки зовнішнім оркестратором. Кешування використовується лише в межах поточного прогону.
34
33
 
35
- Ось переписаний список у заданому форматі:
34
+ ## Публічний API
36
35
 
37
- STYLE — Визначає загальний стиль та призначення файлу.
38
- sectionMessages Групує повідомлення для секцій, забезпечуючи мінімальний контекст для кожної.
39
- overviewMessages Підготує узагальнений огляд поведінки на основі вже написаної детальної поведінки.
40
- criticMessagesНа етапі первинного аналізу тексту виявляє конкретні недоліки в чорноті для подальшого виправлення.
41
- refineMessages Виправляє чорнетку, усуваючи виявлені критичні недоліки.
42
- guaranteesFromMarkers Створює чіткий, детермінований перелік гарантій роботи, ґрунтуючись на фіксованих маркерних фактах.
43
- oneShotMessages Слугує зразком для порівняння, що містить конкретні приклади, а не загальні описи дій.
36
+ - STYLE — Спільний system-стиль для всіх docgen-промптів: вимагає лаконічну поведінкову
37
+ українську документацію, забороняє сигнатури/типи й мета-фрази перед відповіддю
38
+ (профілактика «озвучування завдання» малими моделями).
39
+ - sectionMessages Секційні набори messages з МІНІМАЛЬНИМ контекстом під кожну секцію.
40
+ Код потрапляє лише в `behavior`; «Огляд» генерується окремо ОСТАННІМ
41
+ (`overviewMessages`) з уже написаної Поведінки тут його немає. «Публічний
42
+ API» сюди більше не входить (Stage 1/3, гібрид doc-files ADR 260719-2155):
43
+ покриті JSDoc-описом експорти рендеряться дослівно без LLM (`renderApiLine`),
44
+ LLM викликається лише на прогалини (`apiGapMessages`) — див. `isApiGap`.
45
+ - isApiGap — Stage 2 (gap-детект, 0 токенів): чи є опис експорту прогалиною — відсутній
46
+ або JSDoc-заглушка без сенсу.
47
+ - renderApiLine — Stage 1 (скриптовий рендер, 0 токенів, 0 галюцинацій): дослівний рядок
48
+ «Публічного API» з покритого JSDoc-описом експорту — без перефразування LLM.
49
+ - apiGapMessages — Stage 3: messages ЛИШЕ для експортів-прогалин (без desc) — вужчий промпт,
50
+ ніж попередній «переписати весь список своїми словами» (жодного контакту з
51
+ уже покритими JSDoc експортами, 0 ризику спотворити авторський текст).
52
+ - overviewMessages — R3 — «Огляд» ОСТАННІМ: узагальнення вже написаної Поведінки, а не здогад із
53
+ голого факт-листа. Лікує generic/хибний Огляд на складних файлах.
54
+ Анкор-блок сюди НЕ підставляється (№8, бенч gemma-4): секції — окремі
55
+ LLM-виклики, і коли анкори бачили обидва, кожен чесно вставляв «рівно один
56
+ раз» → у документі виходило двічі (незграбні «посилаючись на…» в Огляді).
57
+ Анкори живуть лише в Behavior-промпті; скорер R5 перевіряє документ цілком.
58
+ - criticMessages — E2-step 1 — критик. Перевіряє чорнетку секції на конкретні дефекти.
59
+ Повертає messages для LLM-запиту: вихід має бути СПИСКОМ issues або словом NONE.
60
+ - refineMessages — E2-step 2 — refine. Переписує чорнетку, виправляючи перелічені issues.
61
+ - guaranteesFromMarkers — E3 — детермінований шаблон секції «Гарантії поведінки» з facts.markers.
62
+ НЕ використовує LLM: 0 запитів, 0 галюцинацій, 0 generic-фраз.
63
+ - oneShotMessages — One-shot messages (база для порівняння).
64
+ - UNIT_DIGEST_TOKENS — Поріг (у токенах, ~4 байти/токен), після якого сирий src замінюється юніт-дайджестом.
65
+ - buildUnitDigest — №5 (бенч gemma-4): стислий юніт-дайджест великого файлу замість сирого src у
66
+ Behavior-промпті. На ~6k токенів сирцю мала модель втрачає фокус (водянисті
67
+ формулювання); дайджест подає структуру — імʼя, JSDoc, call-graph, тіло лише
68
+ для непокритих JSDoc юнітів (перші рядки) — і тримає промпт компактним.
69
+ - judgeRefineMessages — №6 — judge-refine: один локальний refine-прохід за конкретними зауваженнями
70
+ LLM-судді (замість лише маркування degraded). Суддя вже сформулював, ЩО саме
71
+ хибне (`reason`) — мала модель добре виправляє точкові твердження, коли їй
72
+ сказано, які саме.
44
73
 
45
74
  ## Гарантії поведінки
46
75
 
47
- - Read-only: не виконує операцій запису (ФС/БД).
76
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
48
77
  - Кешує результати в межах одного прогону.
@@ -3,33 +3,45 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: npm/rules/image-avif/avif_generation/main.mjs
5
5
  docgen:
6
- crc: 658146c1
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
- score: 100
9
- issues: judge:inaccurate:0.99
6
+ crc: 7e73761a
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
9
+ score: 85
10
+ issues: internal-name:walkDir,anchor-miss:(image-avif.mdc),judge-refine:kept-original,judge:inaccurate:0.98
10
11
  judgeModel: openai-codex/gpt-5.4-mini
11
12
  ---
12
13
 
13
14
  ## Огляд
14
15
 
15
- Огляд
16
- Цей модуль відповідає за ініціалізацію та виконання процесу конвертації растрових зображень у проєкті на AVIF-двійники, як описано у `package.json`. Публічна функція `main` запускає сканування всіх пакетів монорепозиторію, що призводить до заміни посилань у файлах Vue та HTML на оптимізовані версії. Крім того, він очищає від неіспользуних AVIF-файлів, використовуючи кешування даних протягом одного прогону.
16
+ scanAvif — read-only детектор AVIF для `.vue` і `.html`: він знаходить raster-посилання і класифікує їх як `avif-needs-rewrite`, `avif-missing` або `avif-orphan`. `AVIF_NEEDS_REWRITE`, `AVIF_MISSING`, `AVIF_ORPHAN`, `MINIFY_PACKAGE_NAME`, `CLEANUP_EXTRA_IGNORE_DIR_NAMES` — публічні константи для цих перевірок і спільних правил сканування. `lint --no-fix` лише звітує і не мутує tree, а переписування посилань, AVIF-генерацію та прибирання сиріт виконує окремий T0-fix `fix-avif_generation.mjs`. Cache працює в межах одного прогону.
17
17
 
18
18
  ## Поведінка
19
19
 
20
- 1. main виконує повний цикл перевірки та оптимізації зображень AVIF.
21
- 2. Перед початком роботи перевіряється наявність будь-яких посилань на растрове зображення у файлах Vue або HTML. Якщо таких посилань немає, операція припиняється, оскільки немає чого оптимізувати.
22
- 3. Запускається генерація AVIF-двійників з використанням інструмента `@nitra/minify-image`.
23
- 4. Ініціалізуються лічильники для обліку успішно переписаних посилань, змін у файлах та невдалих спроб заміни.
24
- 5. Проводиться сканування всіх пакетів у монорепозиторії. Для кожного пакета визначається, чи активовано вимкнення перевірки (`disable-avif: true`) у `package.json`.
25
- 6. Якщо перевірка AVIF-імпортів не вимкнена, виконується аналіз файлів Vue та HTML у пакеті. Знайдені растрові посилання замінюються на посилання з суфіксом `.avif`, якщо відповідний AVIF-двійник існує на диску. У разі невдачі заміни фіксується звіт про помилку, а сам файл може бути змінений. Після обробки файлу він записується на диск. Збір до списку шляхів, що використовуються, ведеться для AVIF-двійників.
26
- 7. Паралельно з аналізом пакетів, збирається список усіх абсолютних коренів пакетів, де перевірка була вимкнена.
27
- 8. Після аналізу всіх пакетів, збирається список "сиріт" — AVIF-файлів, які знаходяться у репозиторії, але на які немає жодного активного посилання у `.vue` або `.html` файлах. Ці сироти видаляються, за винятком AVIF-файлів у пакетах, де перевірка була вимкнена, та AVIF-файлів, які мають живі посилання.
28
- 9. Повертається загальний звіт про кількість виконаних операцій (заміна посилань, видалення сиріт, невдачі заміни).
20
+ `scanAvif` запускає спільний read-only потік для detector-а й T0-fix: спершу перевіряє, чи є в репозиторії хоч одне raster-посилання, придатне для AVIF-етапу, далі збирає зв’язки між `.vue`/`.html`, `.avif` і package.json, а потім формує результати для лінту без жодної мутації дерева. Якщо raster-посилань немає, весь етап пропускається; якщо в workspace немає workspaces або `.vue`-файлів, AVIF-правило для проєкту теж не активується.
21
+
22
+ `MINIFY_PACKAGE_NAME` позначає пакет, через який читається opt-out у `package.json`: коли пакет вимикає AVIF-перевірку, його шаблони не беруть участі в перевірці посилань, а його `.avif` не можна автоматично вважати сиротами. Це захищає файли, що можуть використовуватись через alias, runtime-обчислення або зовнішні посилання, які статичний скан тут не бачить.
23
+
24
+ `CLEANUP_EXTRA_IGNORE_DIR_NAMES` додає спільні виключення для обходу, щоб `scanAvif` і `lint` не зачіпали каталоги, які не мають впливати на AVIF-діагностику.
25
+
26
+ `AVIF_NEEDS_REWRITE` використовується для випадків, коли raster-посилання вже має доступний `.avif`-двійник, але посилання ще не переписане на нього; `AVIF_MISSING` — коли потрібного `.avif`-двійника немає; `AVIF_ORPHAN` — коли `.avif` лишився без живих посилань у відсканованих шаблонах.
27
+
28
+ `lint` лише звітує ці три стани як violations і не виконує генерацію AVIF, переписування посилань чи видалення сиріт; ці дії лишаються за окремим T0-fix. Маркери повідомлень прив’язані до `image-avif.mdc`, а сам detector спирається на `package.json` як джерело opt-out-конфігурації.
29
29
 
30
30
  ## Публічний API
31
31
 
32
- mainгенерує зображення у форматі AVIF, автоматично замінює посилання на растрове зображення у файлах `.vue` та `.html`, а також очищує від непідключених файлів AVIF.
32
+ - AVIF_NEEDS_REWRITE Стабільні reasons.
33
+ - AVIF_MISSING — Стабільний reason: для растрового зображення відсутній згенерований AVIF-двійник.
34
+ - AVIF_ORPHAN — Стабільний reason: AVIF-файл лишився без растрового джерела — кандидат на cleanup.
35
+ - MINIFY_PACKAGE_NAME — Імʼя CLI-пакета, який генерує AVIF (використовує T0-fix).
36
+ - CLEANUP_EXTRA_IGNORE_DIR_NAMES — Імена каталогів, які cleanup НЕ зачіпає, бо це артефакти збірки/нативні
37
+ платформи — `.avif` всередині — це продукт попереднього `bun run build`/Capacitor sync,
38
+ а не кандидати на видалення. `walkDir` уже скіпає `node_modules`, `.git`, `dist`,
39
+ `coverage`, `.turbo`, `.next` — додатково для cleanup ігноруємо ще ці.
40
+ - scanAvif — Чистий read-only скан усього AVIF-етапу (без npx, без запису, без unlink). Спільний
41
+ для detector-а (→ violations) і T0-fix (виконує генерацію, потім rescan + write/unlink).
42
+ - lint — Read-only detector AVIF-етапу: ЗВІТУЄ потрібні rewrite-и (`avif-needs-rewrite`),
43
+ відсутні `.avif`-двійники (`avif-missing`) і `.avif`-сироти (`avif-orphan`).
44
+ Не валідує image-compress cache/dependency policy — це окреме правило.
33
45
 
34
46
  ## Гарантії поведінки
35
47
 
@@ -10,6 +10,7 @@ import { basename, dirname, join } from 'node:path'
10
10
  const CONTEXT_LINES = 10
11
11
  const TEST_FILE_MAX_LINES = 2000
12
12
 
13
+ /** Системний промпт класифікатора survived-мутантів (5 verdict-категорій). */
13
14
  export const SYSTEM_PROMPT = `You are a mutation testing classifier.
14
15
 
15
16
  For each survived Stryker mutant, classify it into exactly one verdict:
@@ -16,6 +16,7 @@ import { z } from 'zod'
16
16
  const REASON_SOFT_MAX = 500
17
17
  const SUGGESTED_TEST_SOFT_MAX = 300
18
18
 
19
+ /** Zod-схема verdict-обʼєкта класифікатора (verdict/confidence/reason/suggestedTest). */
19
20
  export const VerdictSchema = z.object({
20
21
  verdict: z.enum(['worth-testing', 'equivalent', 'defensive', 'glue', 'wrapper']),
21
22
  confidence: z.number().min(0).max(1),
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Мовно-агностичний парсинг lcov (спільна lib концерну coverage): агреговані
3
+ * totals (рядки/функції) і per-file розбивка. Живе в core — провайдери всіх
4
+ * мов (vitest lcov, cargo llvm-cov) імпортують звідси, без дублювання парсера
5
+ * у плагінах. SF-шляхи рібейзяться відносно кореня на боці викликача.
6
+ */
7
+
8
+ /**
9
+ * Агрегує LF/LH/FNF/FNH по всіх записах lcov.
10
+ * @param {string} text вміст lcov-файлу
11
+ * @returns {{lines:{covered:number,total:number}, functions:{covered:number,total:number}}} totals
12
+ */
13
+ export function parseLcovTotals(text) {
14
+ const acc = { lines: { covered: 0, total: 0 }, functions: { covered: 0, total: 0 } }
15
+ for (const line of text.split('\n')) {
16
+ if (line.startsWith('LF:')) acc.lines.total += Number(line.slice(3))
17
+ else if (line.startsWith('LH:')) acc.lines.covered += Number(line.slice(3))
18
+ else if (line.startsWith('FNF:')) acc.functions.total += Number(line.slice(4))
19
+ else if (line.startsWith('FNH:')) acc.functions.covered += Number(line.slice(4))
20
+ }
21
+ return acc
22
+ }
23
+
24
+ /**
25
+ * Per-file рядкове покриття з lcov (`SF:`/`LF:`/`LH:`; шляхи — як у файлі).
26
+ * @param {string} text вміст lcov-файлу
27
+ * @returns {Array<{file: string, pct: number, linesFound: number, linesCovered: number}>} рядки по файлах
28
+ */
29
+ export function parseLcovPerFile(text) {
30
+ const files = []
31
+ let currentFile = null
32
+ let lf = 0
33
+ let lh = 0
34
+ for (const line of text.split('\n')) {
35
+ if (line.startsWith('SF:')) {
36
+ currentFile = line.slice(3).trim()
37
+ lf = 0
38
+ lh = 0
39
+ } else if (line.startsWith('LF:')) {
40
+ lf = Number(line.slice(3))
41
+ } else if (line.startsWith('LH:')) {
42
+ lh = Number(line.slice(3))
43
+ } else if (line === 'end_of_record' && currentFile) {
44
+ files.push({
45
+ file: currentFile,
46
+ pct: lf === 0 ? 100 : Math.round((lh / lf) * 10000) / 100,
47
+ linesFound: lf,
48
+ linesCovered: lh
49
+ })
50
+ currentFile = null
51
+ }
52
+ }
53
+ return files
54
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Мовно-агностичний пошук коренів екосистеми за маніфестом (спільна lib
3
+ * концерну coverage): каталоги з одним із маніфест-файлів у корені проєкту та
4
+ * на першому рівні вкладеності (типові розкладки: крейт/пакет у корені,
5
+ * `src-tauri/`, side-пакет у монорепо). Глибші члени workspace не повертаються
6
+ * — тулзи (`cargo llvm-cov`, `pytest`) покривають їх із кореня самі.
7
+ */
8
+ import { existsSync } from 'node:fs'
9
+ import { readdir } from 'node:fs/promises'
10
+ import { join } from 'node:path'
11
+
12
+ /** Службові теки, де маніфести першого рівня не шукаються. */
13
+ const IGNORE_DIRS = new Set([
14
+ 'node_modules',
15
+ 'dist',
16
+ 'build',
17
+ 'target',
18
+ 'coverage',
19
+ 'docs',
20
+ '.git',
21
+ '.claude',
22
+ '.worktrees',
23
+ '.cursor',
24
+ '.github'
25
+ ])
26
+
27
+ /**
28
+ * Корені під `cwd`, що мають хоча б один із `manifestNames`.
29
+ * @param {string} cwd корінь проєкту
30
+ * @param {string[]} manifestNames імена маніфестів (напр. `['Cargo.toml']`, `['pyproject.toml', 'setup.py']`)
31
+ * @returns {Promise<string[]>} абсолютні шляхи каталогів-коренів
32
+ */
33
+ export async function findManifestRoots(cwd, manifestNames) {
34
+ const hasManifest = dir => manifestNames.some(name => existsSync(join(dir, name)))
35
+ const roots = []
36
+ if (hasManifest(cwd)) roots.push(cwd)
37
+ let entries
38
+ try {
39
+ entries = await readdir(cwd, { withFileTypes: true })
40
+ } catch {
41
+ return roots
42
+ }
43
+ for (const entry of entries) {
44
+ if (!entry.isDirectory() || entry.name.startsWith('.') || IGNORE_DIRS.has(entry.name)) continue
45
+ const dir = join(cwd, entry.name)
46
+ if (hasManifest(dir)) roots.push(dir)
47
+ }
48
+ return roots
49
+ }
@@ -3,24 +3,27 @@ type: JS Module
3
3
  title: fix-oxfmtrc.mjs
4
4
  resource: npm/rules/text/oxfmtrc/fix-oxfmtrc.mjs
5
5
  docgen:
6
- crc: 2902bd52
7
- model: openai-codex/gpt-5.4-mini
8
- tier: cloud-min
6
+ crc: d2983472
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
9
  score: 100
10
- issues: judge:inaccurate:0.98
11
10
  judgeModel: openai-codex/gpt-5.4-mini
12
11
  ---
13
12
 
14
13
  ## Огляд
15
14
 
16
- Публічна точка входу `patterns` повертає набір правил вирівнювання для `.oxfmtrc.json` і слугує read-only джерелом очікуваного стану цього конфіга. Код спирається на конфіг `.oxfmtrc.json` як на залежність контексту, щоб узгоджувати його формат із прийнятими правилами.
15
+ Файл визначає T0-fix-сценарій концерну text/oxfmtrc для `.oxfmtrc.json`, який приводить конфіг до канону правила через глибоке об’єднання з шаблоном. `patterns` існує, щоб додавати налаштування з канонічного шаблону й не втрачати наявні локальні ключі конфігу.
17
16
 
18
17
  ## Поведінка
19
18
 
20
- 1. `patterns` формує набір виправлень для узгодження шаблонного конфіга з цільовим файлом `.oxfmtrc.json`.
21
- 2. Кожен елемент у `patterns` описує окреме правило вирівнювання цього конфіга, щоб тримати його в очікуваному стані.
22
- 3. `patterns` не виконує записів у файлову систему чи базу даних і не змінює інші файли поза `.oxfmtrc.json`.
19
+ 1. `patterns` оголошує один fix-сценарій для приведення `.oxfmtrc.json` до канонічного стану правила.
20
+ 2. Сценарій додає або оновлює значення з шаблону правила через глибоке об’єднання, щоб обов’язкові налаштування були присутні.
21
+ 3. Наявні локальні ключі конфігу зберігаються, щоб проєктові відмінності не втрачалися під час автоматичного виправлення.
22
+
23
+ ## Публічний API
24
+
25
+ - patterns — Fix-патерни концерну: один шаблонний deep-merge у `.oxfmtrc.json`.
23
26
 
24
27
  ## Гарантії поведінки
25
28
 
26
- - Read-only: не виконує операцій запису (ФС/БД).
29
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,25 +3,29 @@ type: JS Module
3
3
  title: fix-vscode_settings.mjs
4
4
  resource: npm/rules/text/vscode_settings/fix-vscode_settings.mjs
5
5
  docgen:
6
- crc: aa3c10a6
7
- model: openai-codex/gpt-5.4-mini
8
- tier: cloud-min
6
+ crc: 7208a85f
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
9
  score: 100
10
- issues: judge:inaccurate:0.93
11
10
  judgeModel: openai-codex/gpt-5.4-mini
12
11
  ---
13
12
 
14
13
  ## Огляд
15
14
 
16
- Файл визначає, за якими правилами `patterns` перевіряє відповідність `.vscode/settings.json` конфігурації з `settings.json`. Це потрібно, щоб підтримувати узгоджений стан редакторських налаштувань у проєкті.
15
+ Файл задає автоматичне виправлення для `.vscode/settings.json` у межах концерну `text/vscode_settings`. Він існує, щоб доводити workspace-налаштування до канону через `deep-merge` шаблону правила, зберігаючи локальні користувацькі значення.
17
16
 
18
17
  ## Поведінка
19
18
 
20
- 1. `patterns` формує набір правил для приведення `.vscode/settings.json` до узгодженого стану з шаблоном.
21
- 2. `patterns` орієнтується на конфігурацію `settings.json` як на джерело очікуваного вигляду налаштувань.
22
- 3. `patterns` потрібен, щоб автоматично підтримувати єдину структуру редакторських налаштувань у проєкті.
23
- 4. `patterns` працює лише як опис правил і не виконує запис у файлову систему чи базу даних.
19
+ 1. `patterns` оголошує єдиний fix-патерн для приведення `settings.json` до проєктного канону.
20
+
21
+ 2. Патерн застосовує шаблон правила як deep-merge, щоб додати або оновити обов’язкові налаштування без перетирання локальних користувацьких значень.
22
+
23
+ 3. Результат призначений для автоматичного виправлення відхилень у VS Code workspace-конфігурації в межах концерну `text/vscode_settings`.
24
+
25
+ ## Публічний API
26
+
27
+ - patterns — Fix-патерни концерну: один шаблонний deep-merge у `.vscode/settings.json`.
24
28
 
25
29
  ## Гарантії поведінки
26
30
 
27
- - Read-only: не виконує операцій запису (ФС/БД).
31
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,26 +3,31 @@ type: JS Module
3
3
  title: fix-zed_settings.mjs
4
4
  resource: npm/rules/worktree/zed_settings/fix-zed_settings.mjs
5
5
  docgen:
6
- crc: 452faa10
6
+ crc: 3cff4486
7
7
  model: openai-codex/gpt-5.5
8
8
  tier: cloud-avg
9
9
  score: 100
10
- issues: judge:inaccurate:0.98
11
10
  judgeModel: openai-codex/gpt-5.4-mini
12
11
  ---
13
12
 
14
13
  ## Огляд
15
14
 
16
- Надає правило `patterns` для перевірки очікуваних налаштувань проєкту. Код спирається на конфіг `settings.json` і працює read-only, щоб описати вимоги до конфігурації без самостійного внесення змін.
15
+ Файл задає fix для `.zed/settings.json`, який приводить робочий конфіг Zed до командного канону через `deep-merge` шаблону правила. Він існує, щоб додавати або виправляти очікувані значення `settings.json`, не перезаписуючи локальні налаштування користувача поза конфліктами з канонічними вимогами.
16
+
17
+ `patterns` є єдиною публічною точкою для оголошення цього правила.
17
18
 
18
19
  ## Поведінка
19
20
 
20
- 1. `patterns` визначає правило автоматичного приведення робочого дерева до очікуваного шаблону налаштувань Zed.
21
+ 1. `patterns` оголошує fix-поведінку для приведення робочого конфіга Zed до командного канону.
22
+
23
+ 2. Під час застосування fix оновлює `.zed/settings.json` на основі шаблону правила через злиття налаштувань, щоб додати або виправити очікувані значення з `settings.json`.
24
+
25
+ 3. Наявні локальні налаштування користувача зберігаються, якщо вони не конфліктують із канонічними вимогами правила.
21
26
 
22
- 2. `patterns` орієнтується на конфіг `settings.json`, щоб забезпечити наявність і узгодженість `.zed/settings.json` у проєкті.
27
+ ## Публічний API
23
28
 
24
- 3. `patterns` не змінює файлову систему самостійно; воно лише описує поведінку виправлення для зовнішнього механізму застосування правил.
29
+ - patterns Fix-патерни концерну: один шаблонний deep-merge у `.zed/settings.json`.
25
30
 
26
31
  ## Гарантії поведінки
27
32
 
28
- - Read-only: не виконує операцій запису (ФС/БД).
33
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -82,6 +82,11 @@
82
82
  "type": "number",
83
83
  "description": "Мінімальний mutation score у відсотках (лише повний вимір: lint --full / lint test).",
84
84
  "default": 80
85
+ },
86
+ "classifyConfidenceThreshold": {
87
+ "type": "number",
88
+ "description": "Confidence-поріг LLM-класифікації survived-мутантів (allowed gaps). ≤1 — увімкнено; дефолт 1.1 = вимкнено (rollout-mode).",
89
+ "default": 1.1
85
90
  }
86
91
  }
87
92
  },
@@ -3,45 +3,54 @@ type: JS Module
3
3
  title: lint-lock.mjs
4
4
  resource: npm/scripts/lib/lint-surface/lint-lock.mjs
5
5
  docgen:
6
- crc: 23bf1b2c
7
- model: openai-codex/gpt-5.5
8
- tier: cloud-avg
9
- score: 100
10
- issues: judge:inaccurate:0.98
6
+ crc: c1100ba8
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
9
+ score: 90
10
+ issues: internal-name:withLock,judge-refine:kept-original,judge:inaccurate:0.99
11
11
  judgeModel: openai-codex/gpt-5.4-mini
12
12
  ---
13
13
 
14
14
  ## Огляд
15
15
 
16
- Файл серіалізує лише довгі machine-wide запуски `n-rules lint --full`, щоб на машині одночасно виконувався щонайбільше один full-прогін. Delta, scoped і `--no-fix` запуски не беруть глобальний лок і не стають у цю чергу.
16
+ Спільний машинний стан для `n-rules lint --full`: через `withLock` блокується лише `--full`, а scoped, delta та `--no-fix` запуски йдуть без черги. Це серіалізує довгі whole-tree прогони на одній машині, дає видимість позиції в черзі й показує живий прогрес активного запуску.
17
17
 
18
- Активний full-прогін записує власника лока в `owner.json` і публікує живий стан у `progress.json`, щоб процеси в очікуванні бачили поточного виконавця та прогрес. Процеси в черзі реєструються у `queue/<enqueuedAt>-<pid>.json`, що дає видимий список очікування й позицію кожного запуску.
18
+ `GLOBAL_CACHE_DIR` лежить в `os.tmpdir` і працює machine-wide. У ньому зберігаються `lock/owner.json` для власника лока, `queue/<enqueuedAt>-<pid>.json` для черги процесів і `progress.json` для знімка активного прогресу.
19
19
 
20
- Дедуплікація спирається на fingerprint і TTL у механіці лока, а не на файли стану. За неможливості безпечно дочекатися черги запуск завершується fail-closed, щоб не допустити мовчазного паралельного full-прогону.
20
+ `lintLockFingerprint` домішує варіант виклику до знімка дерева, щоб scoped-успіх не хибно перекривав ширший прогін. `staleThreshold` піднято до 6 год, `waitTimeout` — 45 хв; після цього очікування завершується fail-closed, а не мовчазним паралельним запуском.
21
+
22
+ `createProgressPublisher` оновлює `progress.json`, `renderWaitLine` відображає чергу й прогрес, а `withGlobalLintLock` є спільною точкою доступу до цього режиму.
21
23
 
22
24
  ## Поведінка
23
25
 
24
- - `GLOBAL_CACHE_DIR` задає спільне machine-wide місце стану для черги full-лінту, включно з `owner.json` і `progress.json`.
26
+ `GLOBAL_CACHE_DIR` спільний машинний кеш для всіх full-запусків lint: тут зберігаються власник лока, черга очікування і живий прогрес активного прогону. Саме цей стан робить чергу видимою між процесами та дозволяє не запускати кілька повних прогонів паралельно.
25
27
 
26
- - `lintLockFingerprint` формує ключ дедуплікації для full-лінту з урахуванням стану дерева й варіанта запуску; повертає порожнє значення, коли безпечно дедуплікувати неможливо.
28
+ `lintLockFingerprint` визначає, чи можна безпечно застосувати TTL-дедуплікацію для конкретного варіанта lint. Якщо знімок дерева недоступний або виклик не відповідає поточному робочому дереву, дедуплікація вимикається і запуск іде далі по черзі. Інакше fingerprint враховує і стан дерева, і варіант виклику, щоб короткий scoped-успіх не підміняв ширший full-прогін.
27
29
 
28
- - `createProgressPublisher` публікує throttled-знімки прогресу активного full-прогону в `progress.json`, щоб процеси в черзі бачили живий стан без зайвого навантаження на диск.
30
+ `withGlobalLintLock` точка входу для повного запуску: non-full варіанти проходять одразу, а full-прогони стають у глобальну чергу, чекають звільнення лока й виконуються по одному. Після входу в лок активний запуск публікує свій прогрес у `progress.json`, а процеси в черзі читають його та показують актуальний стан очікування. Якщо запуск уже був успішно дедуплікований, результат повертається без повторного виконання.
29
31
 
30
- - `renderWaitLine` створює однорядковий статус очікування з позицією в черзі, поточним власником лока з `owner.json`, прогресом із `progress.json` і рештою очікувачів.
32
+ `createProgressPublisher` пов’язує репортер прогресу активного прогону зі спільним станом: нові знімки потрапляють у файл прогресу з обмеженням частоти оновлення, щоб черга бачила живий, але стабільний стан. Це джерело правди для всіх очікувальних процесів.
31
33
 
32
- - `withGlobalLintLock` серіалізує лише `--full` запуски лінту через глобальну чергу, а короткі дельта/scoped/`--no-fix` запуски пропускає одразу; при timeout завершується fail-closed, щоб не допустити паралельний full-прогін.
34
+ `renderWaitLine` збирає однорядковий статус очікування з трьох джерел: поточного власника лока, живої черги і знімка прогресу активного прогону. У результаті процес у черзі бачить, хто зараз працює, яка в нього стадія, і яке місце займає сам у загальному порядку.
33
35
 
34
36
  ## Публічний API
35
37
 
36
- - GLOBAL_CACHE_DIR — зберігає спільний machine-wide стан лока й черги для всіх repo та worktree; спирається на owner.json і progress.json.
37
- - lintLockFingerprint — формує ключ для TTL-дедуплікації за станом робочого дерева та режимом запуску lint; повертає null поза git-repo або коли --cwd відрізняється від process cwd, щоб не прив’язати прогін до чужого дерева.
38
- - createProgressPublisher публікує прогрес активного lint-прогону в progress.json, щоб процеси в черзі бачили актуальний progress bar власника лока.
39
- - renderWaitLine — показує стан очікування в черзі: позицію процесу, поточного власника з pid і текою, його прогрес та інші queued процеси.
40
- - withGlobalLintLock запускає full lint під глобальним локом і чергою; delta, scoped та --no-fix прогони стартують одразу без очікування.
38
+ - GLOBAL_CACHE_DIR — Machine-wide директорія стану лока/черги спільна для всіх репо й worktree.
39
+ - lintLockFingerprint — Fingerprint для TTL-дедуплікації: стан робочого дерева + варіант виклику lint.
40
+ null (→ дедуплікація вимкнена, черга працює) коли:
41
+ - не в git-репо (worktreeFingerprint дасть null);
42
+ - `--cwd` вказує не на процесний cwd git-команди fingerprint-а виконуються
43
+ у `process.cwd()`, тож знімок відповідав би не тому дереву, що лінтиться.
44
+ - createProgressPublisher — Publisher прогресу активного прогону: приймає знімки від
45
+ `createProgressReporter({ onUpdate })` і (throttled) пише їх у стан-файл,
46
+ звідки процеси в черзі читають прогрес-бар активного прогону.
47
+ - renderWaitLine — Рядок стану черги для процесу, що стоїть у черзі: позиція, хто працює (pid + тека),
48
+ прогрес-бар власника і перелік решти черги.
49
+ - withGlobalLintLock — Виконує `runFn` під глобальним локом full-прогонів. Не-full варіанти
50
+ (дельта/scoped/`--no-fix`) виконуються одразу, без лока й черги.
41
51
 
42
52
  ## Гарантії поведінки
43
53
 
44
- - У кожен момент на машині виконується щонайбільше один `lint --full`; запуски в черзі стартують у порядку постановки.
45
- - Файлові операції стану (реєстрація в черзі, публікація прогресу, читання чужих записів) best-effort: їх збій не валить прогін, лише зменшує видимість; записи мертвих PID прибираються при читанні списку.
46
- - Таймаут очікування черги виняток (fail-closed), а не мовчазний паралельний запуск.
47
- - Ідентичний повторний `--full` на незміненому дереві дедуплікується за fingerprint у межах TTL (exit 0 без повторної роботи); поза git-репо чи при `--cwd` не на процесний cwd дедуплікація вимикається, черга лишається.
54
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
55
+ - За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
56
+ - Кешує результати в межах одного прогону.
@@ -46,6 +46,14 @@ const PROGRESS_FILE = join(GLOBAL_CACHE_DIR, 'progress.json')
46
46
  /** Дедлайн очікування в черзі: full-прогони довгі, 20 хв дефолту withLock замало. */
47
47
  const WAIT_TIMEOUT_MS = 45 * 60_000
48
48
 
49
+ /**
50
+ * Дедлайн, коли активний/очікуваний прогін включає концерн coverage правила
51
+ * `test` (spec absorb-7n-test, ризик 3.4): повне мутаційне тестування
52
+ * (Stryker/cargo-mutants) на великому проєкті не вкладається у 45 хв —
53
+ * інженерний запас ×4 замість вгадування точної тривалості.
54
+ */
55
+ const WAIT_TIMEOUT_WITH_COVERAGE_MS = 4 * WAIT_TIMEOUT_MS
56
+
49
57
  /** Поріг time-based staleness (див. модульний коментар). */
50
58
  const STALE_THRESHOLD_MS = 6 * 3_600_000
51
59
 
@@ -235,10 +243,13 @@ export function withGlobalLintLock(variant, runFn, opts = {}) {
235
243
  if (!variant.full) return Promise.resolve(runFn())
236
244
  const { isTTY, log, queueDir, progressFile, ...lockOpts } = opts
237
245
  const ui = createWaitUi({ isTTY, log, queueDir, progressFile })
246
+ // Full-прогін завжди включає концерн coverage (мутаційне тестування) —
247
+ // черга чекає з покриттєвим запасом; scoped `lint test` під лок не йде
248
+ // (variant.full=false), тож окремої осі для нього не треба.
238
249
  return withLock('lint-full', runFn, {
239
250
  cacheDir: GLOBAL_CACHE_DIR,
240
251
  staleThreshold: STALE_THRESHOLD_MS,
241
- waitTimeout: WAIT_TIMEOUT_MS,
252
+ waitTimeout: WAIT_TIMEOUT_WITH_COVERAGE_MS,
242
253
  onWaitTimeout: 'fail',
243
254
  getFingerprint: () => lintLockFingerprint(variant),
244
255
  ...ui,
@@ -3,35 +3,51 @@ type: JS Module
3
3
  title: migration-cache.mjs
4
4
  resource: npm/skills/taze/js/migration-cache.mjs
5
5
  docgen:
6
- crc: 5f264929
7
- model: openai-codex/gpt-5.4-mini
8
- tier: cloud-min
6
+ crc: c9ebf692
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
9
  score: 100
10
- issues: judge:inaccurate:0.98
11
10
  judgeModel: openai-codex/gpt-5.4-mini
12
11
  ---
13
12
 
14
13
  ## Огляд
15
14
 
16
- Модуль керує кешем уже відомих міграцій на диску (`~/.cache/n-rules/taze-migrations` за замовчуванням) кеш персистентний і спільний для всіх repo/worktree на машині, не обмежений одним прогоном. `migrationCacheKey` формує ключ для запису, `readMigrationCache` і `writeMigrationCache` працюють із кешованими даними, а `withKnownMigrationNotes` підставляє вже відомі відомості там, де це доречно. Читання fail-safe (`readMigrationCache` перехоплює помилки й повертає `null` замість винятку); запис (`writeMigrationCache`) винятків не перехоплює.
15
+ Файл підтримує дисковий кеш нотаток про міграції пакетів між версіями для повторного використання між прогонами й репозиторіями, щоб повторне звернення до тих самих даних не виконувало зайву роботу. `DEFAULT_CACHE_DIR`, `migrationCacheKey`, `readMigrationCache`, `writeMigrationCache` і `withKnownMigrationNotes` задають спільні точки доступу до цього кешу.
16
+
17
+ Якщо кеш недоступний, запис непридатний або операція читання кешу не може бути виконана, обробка продовжується без винятків назовні й за потреби повертає порожнє значення замість збою.
17
18
 
18
19
  ## Поведінка
19
20
 
20
- - `DEFAULT_CACHE_DIR` задає спільний каталог кешу міграцій для всіх репозиторіїв на цій машині.
21
- - `migrationCacheKey` — перетворює пару версій пакета на безпечний крос-репо ключ кешу.
22
- - `readMigrationCache` читає кешований запис міграції для конкретної пари версій; якщо запису немає або він пошкоджений, повертає `null` без помилки.
23
- - `writeMigrationCache` — зберігає запис про вже проаналізовану міграцію в кеш, щоб не повторювати той самий аналіз у наступних прогонових середовищах.
24
- - `withKnownMigrationNotes` додає до промпта підсумок відомої міграції з кешу й підказує пропустити повторне дослідження та перейти до перевірки в поточному проєкті.
21
+ DEFAULT_CACHE_DIR задає спільне місце зберігання результатів аналізу міграцій для всіх репозиторіїв на машині. Кеш не прив’язаний до поточного проєкту, тому повторне оновлення того самого пакета між тими самими версіями може повторно використати вже підготовлені нотатки.
22
+
23
+ migrationCacheKey формує стабільний безпечний ключ для пари пакет-версії. Цей ключ використовують readMigrationCache і writeMigrationCache, щоб звертатися до одного й того самого запису незалежно від репозиторію чи worktree.
24
+
25
+ writeMigrationCache зберігає підсумок ізольованого LLM-аналізу міграції. Дані потрапляють у спільний кеш і стають доступними для наступних прогонів із тим самим ключем.
26
+
27
+ readMigrationCache на початку наступного прогону шукає готовий запис у спільному кеші. Якщо запис відсутній або непридатний для читання, кеш вважається недоступною оптимізацією й повертається порожній результат замість помилки; основний процес міграції має продовжитися без кешованих нотаток.
28
+
29
+ Коли readMigrationCache знаходить запис, withKnownMigrationNotes додає його підсумок до базового промпта. Результат спрямовує runner не повторювати вже виконане CHANGELOG/diff-дослідження, а одразу перевіряти використання API в поточному проєкті та застосовувати релевантні зміни.
25
30
 
26
31
  ## Публічний API
27
32
 
28
- - DEFAULT_CACHE_DIR — Спільний каталог для кешу міграцій на цій машині, незалежний від конкретного repo чи worktree.
29
- - migrationCacheKey Перетворює `pkg`, `from` і `to` на безпечну назву файла для спільного кешу.
30
- - readMigrationCache — Повертає збережені дані про вже відому міграцію для тієї самої пари версій, або `null`, якщо запису немає чи він пошкоджений.
31
- - writeMigrationCacheЗаписує результат вже розібраної міграції в кеш, щоб наступний repo з тим самим оновленням не починав дослідження заново.
32
- - withKnownMigrationNotes Додає до prompt короткий підсумок знайденої міграції і пропускає початковий етап з пошуком у CHANGELOG та diff.
33
+ - DEFAULT_CACHE_DIR — Каталог за замовчуванням для кешу міграцій спільний для всіх репо на цій
34
+ машині (не прив'язаний до конкретного worktree/репо), бо ключ кешу сам
35
+ пакет+діапазон версій, а не проєкт.
36
+ - migrationCacheKeyСанітизує `(pkg, from, to)` у безпечне імʼя файлу крос-репо ключ кешу.
37
+ Той самий `(pkg, from, to)` у різних репо/воркспейсах дає той самий ключ.
38
+ - readMigrationCache — Читає кешований запис міграції для `(pkg, from, to)`, якщо інший
39
+ repo/worktree на цій машині вже проганяв через LLM ту саму пару версій.
40
+ Відсутній/побитий файл — `null` (мовчки, не провал прогону: кеш —
41
+ оптимізація, а не залежність, від якої залежить коректність).
42
+ - writeMigrationCache — Зберігає результат ізольованого LLM-виклику для `(pkg, from, to)` — щоб
43
+ наступний репо з тим самим bump-ом на цій машині не повторював
44
+ CHANGELOG-дослідження з нуля (див. `readMigrationCache`).
45
+ - withKnownMigrationNotes — Дописує до промпта `provider.promptFor(entry)` підсумок відомої міграції,
46
+ якщо кеш її знайшов — каже runner-у пропустити крок 1 (CHANGELOG/diff-
47
+ дослідження) і одразу шукати використання в поточному проєкті.
33
48
 
34
49
  ## Гарантії поведінки
35
50
 
36
- - `readMigrationCache` перехоплює помилки читання/парсингу й повертає `null` замість винятку (fail-safe); `writeMigrationCache` винятків не перехоплює.
37
- - Кеш персистентний на диску і спільний для всіх repo/worktree на машині — не обмежений одним прогоном.
51
+ - Перехоплює помилки операцій кешу, для яких кеш є необовʼязковою оптимізацією, і не пропускає їх назовні.
52
+ - За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
53
+ - Кешує результати на диску для повторного використання між прогонами й репозиторіями.