@7n/rules 1.43.1 → 1.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/docs/vitest.config.md +14 -19
  3. package/package.json +1 -1
  4. package/rules/abie/lib/docs/index.md +0 -2
  5. package/rules/abie/lib/http-route.mjs +1 -0
  6. package/rules/abie/lib/yaml.mjs +2 -0
  7. package/rules/ci4/marksman_config/docs/index.md +10 -0
  8. package/rules/ci4/marksman_config/main.mjs +2 -0
  9. package/rules/doc-files/docgen-prompts/docs/index.md +9 -0
  10. package/rules/doc-files/docgen-prompts/main.mjs +5 -0
  11. package/rules/hasura/internal_urls/docs/index.md +0 -2
  12. package/rules/hasura/internal_urls/docs/main.md +27 -15
  13. package/rules/hasura/internal_urls/main.mjs +1 -0
  14. package/rules/image-avif/avif_generation/docs/index.md +10 -0
  15. package/rules/image-avif/avif_generation/main.mjs +2 -0
  16. package/rules/rego/vscode_settings/docs/fix-vscode_settings.md +12 -10
  17. package/rules/rego/vscode_settings/fix-vscode_settings.mjs +5 -0
  18. package/rules/tauri/cargo_mutants_config/docs/index.md +0 -2
  19. package/rules/tauri/cargo_mutants_config/docs/main.md +38 -12
  20. package/rules/tauri/cargo_mutants_config/main.mjs +5 -1
  21. package/rules/tauri/core_test_isolation/docs/main.md +19 -16
  22. package/rules/tauri/core_test_isolation/main.mjs +3 -1
  23. package/rules/tauri/linux_deps/docs/main.md +25 -18
  24. package/rules/tauri/linux_deps/main.mjs +2 -1
  25. package/rules/tauri/release/docs/main.md +20 -12
  26. package/rules/tauri/release/main.mjs +2 -0
  27. package/rules/tauri/updater/docs/main.md +31 -14
  28. package/rules/tauri/updater/main.mjs +4 -0
  29. package/rules/test/coverage/concern.json +9 -0
  30. package/rules/test/coverage/fix-worker.mjs +111 -0
  31. package/rules/test/coverage/lib/classify/apply.mjs +67 -0
  32. package/rules/test/coverage/lib/classify/cache.mjs +77 -0
  33. package/rules/test/coverage/lib/classify/docs/apply.md +28 -0
  34. package/rules/test/coverage/lib/classify/docs/cache.md +34 -0
  35. package/rules/test/coverage/lib/classify/docs/index.md +37 -0
  36. package/rules/test/coverage/lib/classify/docs/prompt.md +30 -0
  37. package/rules/test/coverage/lib/classify/docs/verdict-schema.md +30 -0
  38. package/rules/test/coverage/lib/classify/index.mjs +140 -0
  39. package/rules/test/coverage/lib/classify/prompt.mjs +136 -0
  40. package/rules/test/coverage/lib/classify/verdict-schema.mjs +163 -0
  41. package/rules/test/coverage/lib/llm.mjs +100 -0
  42. package/rules/test/coverage/main.mjs +161 -0
  43. package/rules/test/main.json +1 -0
  44. package/rules/test/main.mdc +140 -0
  45. package/rules/test/package_json/concern.json +11 -0
  46. package/rules/test/package_json/package_json.mdc +18 -0
  47. package/rules/test/package_json/package_json.rego +25 -0
  48. package/rules/test/package_json/template/package.json.contains.json +6 -0
  49. package/rules/text/oxfmtrc/fix-oxfmtrc.mjs +5 -0
  50. package/rules/text/vscode_settings/fix-vscode_settings.mjs +5 -0
  51. package/rules/worktree/vscode_settings/docs/fix-vscode_settings.md +10 -7
  52. package/rules/worktree/vscode_settings/fix-vscode_settings.mjs +5 -0
  53. package/rules/worktree/zed_settings/fix-zed_settings.mjs +5 -0
  54. package/schemas/n-rules.json +18 -1
  55. package/scripts/lib/adr/docs/index.md +0 -2
  56. package/scripts/lib/adr/docs/normalize-pipeline.md +44 -28
  57. package/scripts/lib/adr/normalize-pipeline.mjs +11 -0
  58. package/scripts/lib/auto-worktree.mjs +9 -3
  59. package/scripts/lib/docs/auto-worktree.md +50 -12
  60. package/scripts/lib/docs/inline-template-links.md +17 -8
  61. package/scripts/lib/docs/plugin-api.md +1 -1
  62. package/scripts/lib/docs/worktree-notice.md +65 -10
  63. package/scripts/lib/inline-template-links.mjs +5 -0
  64. package/scripts/lib/lint-surface/docs/run-detectors.md +25 -22
  65. package/scripts/lib/lint-surface/docs/tier-sampling-experiment.md +30 -14
  66. package/scripts/lib/lint-surface/run-detectors.mjs +1 -1
  67. package/scripts/lib/lint-surface/tier-sampling-experiment.mjs +1 -0
  68. package/scripts/lib/plugin-api.mjs +46 -0
  69. package/scripts/lib/worktree-notice.mjs +5 -3
  70. package/scripts/utils/docs/walkDir.md +26 -15
  71. package/scripts/utils/docs/worktree-fingerprint.md +16 -15
  72. package/scripts/utils/walkDir.mjs +9 -5
  73. package/scripts/utils/worktree-fingerprint.mjs +5 -0
  74. package/skills/storybook/SKILL.md +4 -4
  75. package/skills/taze/js/migration-cache.mjs +1 -1
@@ -3,42 +3,58 @@ type: JS Module
3
3
  title: normalize-pipeline.mjs
4
4
  resource: npm/scripts/lib/adr/normalize-pipeline.mjs
5
5
  docgen:
6
- crc: f8bd18e2
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: 7840afd7
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
9
+ score: 100
10
+ issues: judge-refine:kept-original,judge:inaccurate:0.99
11
+ judgeModel: openai-codex/gpt-5.4-mini
8
12
  ---
9
13
 
10
- Реалізує локально-орієнтований конвеєр для нормалізації ADR. У цій системі JavaScript виконує оркестрацію, тоді як LLM відповідає виключно на вузькі, верифіковані питання. Процес включає відбір кандидатів на основі лексичної схожості (Stage 0: retrieval), бінарне судження між записами (Stage 1: edge-judge) та класифікацію драфтів (Stage 1b: kind-judge). Система об'єднує підтверджені ребра через алгоритм Union-Find (Stage 1c: cluster) для вибору опорного елемента (anchor) та призначення операцій. Далі, LLM вилучає секції в JSON (Stage 2: gen-MADR), після чого JS збирає канон. На фінальній стадії, LLM створює прозу про змін (Stage 3: gen-merge), яку JS додає до документа з відповідним заголовком.
14
+ ## Огляд
15
+
16
+ Файл готує ADR-чернетки до застосування як `operations[]` у тому самому контракті, що й single-shot-пайплайн, сумісному з `apply-ops`: створення нового MADR, доповнення наявного ADR або пропуск. Він існує як локально-орієнтована альтернатива для малої LLM `omlx/gemma-4b`, де JS керує retrieval, кластерами, датами, MADR-каркасом і після кластеризації призначає `op`, а модель дає лише вузькі перевірювані судження та фрагменти змісту.
11
17
 
12
18
  ## Поведінка
13
19
 
14
- Поведінка
15
- tokenize токенізує назву чи слаг, повертаючи множину значущих токенів, фільтруючи стоп-слова та занадто короткі елементи.
16
- jaccard обчислює коефіцієнт Jaccard між двома множинами токенів.
17
- draftTitle витягує заголовок з тіла чернетки, використовуючи специфічні шаблони або шукаючи перший заголовок H1, не класифікований як секція MADR.
18
- isNoDecision перевіряє тіло чернетки на наявність маркерів, що свідчать про те, що рішення не було прийняте, без використання LLM.
19
- buildEdges будує пари (ребра) між чернетками та між чернетками і список чистих ADR, виходячи з лексичної схожості.
20
- validateMadr перевіряє згенерований текст MADR на відповідність формату OKF (наприклад, наявність YAML frontmatter, заголовок, статуси та секції).
21
- madrDate визначає стандартну ISO-дату для ADR, використовуючи або поле `captured` з чернетки, або префікс імені файлу.
22
- normalizeSections перетворює сирий JSON-вивід моделі на структурований об'єкт, нормалізуючи типи даних (наприклад, рядок у масив).
23
- assembleMadr збирає канонічний текст MADR, комбінуючи наданий заголовок, ISO-дату та нормалізовані секції, створюючи кінцевий markdown.
24
- genMadr викликає LLM для вилучення змісту ADR із чернетки, а потім конструює та валідує повний MADR за допомогою `assembleMadr` та `validateMadr`.
25
- normalizePipeline виконує повний конвеєр: ідентифікує кластери чернеток, визначає операції (delete, rewrite, merge-anchor тощо) та ініціює виклики LLM для генерації контенту та додатків.
20
+ `normalizePipeline` приймає батч ADR-чернеток і список уже чистих ADR, після чого веде їх через послідовність дрібних перевірюваних рішень. Глобальні рішення про зв’язки, кластери, цільові документи й фінальні operations залишаються в JS; LLM використовується лише для вузьких локальних суджень і генерації контрольованих фрагментів.
21
+
22
+ На початку потоку `draftTitle` дістає робочу назву кожної чернетки, а `isNoDecision` відсікає записи, де рішення явно не прийняте. Для решти `buildEdges` створює кандидатні зв’язки між чернетками та між чернетками і clean ADR: назви й слаги проходять через `tokenize`, а близькість кандидатів оцінює `jaccard`. Це retrieval-етап: він лише звужує простір порівнянь, а не приймає остаточне рішення про злиття.
23
+
24
+ Далі `normalizePipeline` перевіряє кандидатні зв’язки через LLM-судження «те саме рішення чи ні», консервативно об’єднує підтверджені зв’язки в кластери й призначає для кожної чернетки дію: створити новий ADR, доповнити наявний або пропустити як тривіальну/непридатну. Ізольовані чернетки додатково класифікуються як standalone або trivial, щоб не створювати ADR без достатньої змістовної ваги.
25
+
26
+ Коли потрібен новий ADR, `genMadr` перетворює одну чернетку на MADR-документ. Дату для канонічного каркаса визначає `madrDate`; модель повертає лише зміст секцій, який приводить до стабільної форми `normalizeSections`. Після цього `assembleMadr` збирає повний MADR із контрольованим заголовком, датою, статусом, назвами секцій, fallback-текстами й bullet-структурою. `validateMadr` є фінальним quality gate: невалідний документ не потрапляє в operations як готовий вміст.
27
+
28
+ Коли чернетка має доповнити наявний ADR, `normalizePipeline` генерує лише новий зміст оновлення, а службовий заголовок оновлення та дата лишаються під контролем JS через ту саму політику дат. Це зберігає однаковий формат для створення нових ADR і для merge-доповнень.
29
+
30
+ Результатом `normalizePipeline` є operations у тому самому контракті, що й single-shot-пайплайн, разом зі статистикою та діагностичним trace. Подальше застосування змін виконується спільною apply-логікою поза цим файлом; цей конвеєр лише готує перевірені наміри змін і не покладається на кешування.
26
31
 
27
32
  ## Публічний API
28
33
 
29
- Here is the rewritten list as concise bullet points:
30
-
31
- * tokenizeПеретворює назву чи слаг у набір значущих слів, розділених пробілами та дефісами.
32
- * jaccard Обчислює ступінь схожості між двома наборами слів.
33
- * draftTitle Знаходить основний заголовок чернетки, починаючи з ADR-рядка; якщо його немає, шукає перший H1, інакше бере назву файлу.
34
- * isNoDecision — Автоматично виявляє чернетки, де рішення відсутнє (наприклад, через переривання транскрипту), щоб їх не обробляти LLM.
35
- * buildEdges Створює потенційні зв'язки між елементами на основі схожості слів.
36
- * validateMadr Перевіряє якість згенерованого документа MADR автоматично.
37
- * madrDateВизначає дату документа у форматі ISO, використовуючи дані з метаданих чернетки або дату створення файлу.
38
- * normalizeSectionsСтандартизує вивід генеративної моделі в чітку структуру секцій, виправляючи невеликі помилки формату.
39
- * assembleMadrЗбирає повний документ MADR у версії 4.0.0, використовуючи фіксовану структуру та контент від інших частин.
40
- * genMadr Генерує чернетку документа MADR на основі заданих даних.
41
- * normalizePipeline Виконує послідовність усіх кроків обробки даних, повертаючи список виконаних операцій та статистику.
34
+ - tokenize Токенізує назву/слаг у множину значущих токенів (kebab + пробіли, без стоп-слів).
35
+ - jaccard — Jaccard-схожість двох множин токенів.
36
+ - draftTitleВитягує заголовок драфта. Капчер пише `## ADR <title>` він у пріоритеті
37
+ (чернетка може мати контент-заголовки раніше або взагалі не мати ADR-рядка).
38
+ Fallback-и: перший h1, що не є MADR-секцією, інакше '' (caller бере імʼя файлу).
39
+ - isNoDecision — Детермінований no-decision гейт (харднінг #1). Чернетка, де у `Decision Outcome`
40
+ рішення явно НЕ прийняте (transcript обірвався) не варта окремого ADR: gold
41
+ (sonnet) такі видаляє. Ловимо без LLM, щоб не покладатися на kind-judge малої моделі.
42
+ - buildEdgesБудує кандидати-ребра за лексичною схожістю.
43
+ - validateMadrДетермінований гейт якості згенерованого MADR.
44
+ - madrDateДетермінована ISO-дата для поля **Date:**. Пріоритет `captured` frontmatter
45
+ (перші 10 символів ISO-стемпа); fallback timestamp-префікс імені файлу
46
+ (`YYMMDD-…` `20YY-MM-DD`). Каркас MADR не повинен залежати від LLM навіть тут.
47
+ - normalizeSections — Нормалізує сирий JSON-вивід gen-моделі у строгу форму секцій. Толерантна до
48
+ дрібних відхилень малої моделі: рядок замість масиву → масив із одного елемента,
49
+ число/null → рядок/порожньо, обрізає пробіли й порожні елементи.
50
+ - assembleMadr — Детермінована збірка канонічного MADR 4.0.0 з заголовка, дати й секцій-контенту.
51
+ Увесь каркас (Status, назви секцій, шаблон "Chosen option…", fallback-фрази,
52
+ bullets) — тут, не в моделі. Заголовок і дата — JS-власність (draftTitle/captured),
53
+ модель їх не торкається.
54
+ - genMadr — Stage 2: перетворює одну чернетку на валідний MADR-документ. Модель лише
55
+ витягує зміст секцій як JSON; каркас збирає JS, результат проганяється через
56
+ валідатор із ретраями каскаду. При невдачі повертає `valid: false` без вмісту.
57
+ - normalizePipeline — Головний конвеєр. Повертає operations[] (контракт single-shot) + stats.
42
58
 
43
59
  ## Гарантії поведінки
44
60
 
@@ -459,6 +459,17 @@ export function assembleMadr({ title, date, sections: s }) {
459
459
  ].join('\n')
460
460
  }
461
461
 
462
+ /**
463
+ * Stage 2: перетворює одну чернетку на валідний MADR-документ. Модель лише
464
+ * витягує зміст секцій як JSON; каркас збирає JS, результат проганяється через
465
+ * валідатор із ретраями каскаду. При невдачі повертає `valid: false` без вмісту.
466
+ * @param {string} title заголовок рішення
467
+ * @param {string} body тіло чернетки (обрізається до безпечного розміру)
468
+ * @param {string} captured момент фіксації чернетки (для дати MADR)
469
+ * @param {{allowCloud: boolean, stats: object}} cfg конфіг каскаду й лічильники
470
+ * @param {string} [file] шлях чернетки — fallback-джерело дати
471
+ * @returns {Promise<{content: string | null, slug: string, valid: boolean, error?: string}>} зібраний документ або позначка невдачі
472
+ */
462
473
  export async function genMadr(title, body, captured, cfg, file = '') {
463
474
  const date = madrDate(captured, file)
464
475
  const slug = slugify(title)
@@ -28,7 +28,9 @@ async function defaultConfirm(message) {
28
28
  * Гарантує, що подальші кроки виконуються в ізольованому worktree
29
29
  * (`main.json.worktree: true`-контракт), навіть коли викликач — детермінований
30
30
  * JS-код, що не годує SKILL.md жодному LLM-агенту (тож агентський preflight-блок
31
- * з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
31
+ * з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
32
+ * (репо-конвенція) або `.claude/worktrees/` (worktree харнесу Claude Code,
33
+ * куди `npx \@7n/mt worktree create` класти заборонено — `n-worktree.mdc`) —
32
34
  * повертає його без змін. Інакше сам створює `.worktrees/<branch>-<suffix>`
33
35
  * (`npx \@7n/mt worktree create`) і ставить залежності (`bun install`).
34
36
  *
@@ -62,8 +64,12 @@ export async function ensureRunningInWorktree(
62
64
  ) {
63
65
  const toplevelResult = spawnFn('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8' })
64
66
  const toplevel = toplevelResult.status === 0 ? toplevelResult.stdout.trim() : ''
65
- const segments = new Set(toplevel.replaceAll('\\', '/').split('/'))
66
- if (segments.has('.worktrees')) return { cwd, autoCreated: false, branchArg: null }
67
+ const pathSegments = toplevel.replaceAll('\\', '/').split('/')
68
+ const segments = new Set(pathSegments)
69
+ const isClaudeHarnessWorktree = pathSegments.some(
70
+ (seg, i) => seg === '.claude' && pathSegments[i + 1] === 'worktrees'
71
+ )
72
+ if (segments.has('.worktrees') || isClaudeHarnessWorktree) return { cwd, autoCreated: false, branchArg: null }
67
73
 
68
74
  const branchResult = spawnFn('git', ['branch', '--show-current'], { cwd, encoding: 'utf8' })
69
75
  const currentBranch = branchResult.status === 0 ? branchResult.stdout.trim() : ''
@@ -3,28 +3,66 @@ type: JS Module
3
3
  title: auto-worktree.mjs
4
4
  resource: npm/scripts/lib/auto-worktree.mjs
5
5
  docgen:
6
- crc: bae09068
7
- model: openai-codex/gpt-5.4-mini
8
- score: 100
9
- issues: judge:inaccurate:0.98
10
- judgeModel: openai-codex/gpt-5.4-mini
6
+ crc: 2a9e7bfd
7
+ model: omlx/gemma-4-e2b-it-4bit
8
+ tier: local-min-retry
9
+ score: 90
11
10
  ---
12
11
 
13
12
  ## Огляд
14
13
 
15
- Файл керує запуском у ізольованому worktree, щоб підготувати зміни в окремому середовищі, потім викликати bringChangesBackToOriginal для повернення результату до вихідного дерева і removeAutoCreatedWorktree для очищення тимчасового worktree. Поведінка спирається на конфіг main.json.
14
+ Функції забезпечують ізоляцію роботи з кодом у worktree, перенесення змін між робочими середовищами та керування життєвим циклом створеного worktree. ensureRunningInWorktree гарантує роботу в ізольованому середовищі, bringChangesBackToOriginal переносить модифікації з worktree назад до основного репозиторію, використовуючи механізм копіювання, а не git merge, removeAutoCreatedWorktree забезпечує прибирання, видаляючи сам worktree після завершення операції.
16
15
 
17
16
  ## Поведінка
18
17
 
19
- - `ensureRunningInWorktree` перевіряє, чи виконання вже йде в ізольованому worktree; якщо ні, за потреби створює його для поточної гілки, ставить залежності й повертає новий `cwd`.
20
- - `bringChangesBackToOriginal` — переносить зміни з автоствореного worktree назад у вихідне дерево як untracked/незакомічені правки, включно з додаванням, оновленням і видаленням файлів; перейменування переносить лише в нову назву.
21
- - `removeAutoCreatedWorktree` — прибирає автостворений worktree разом із його ефемерною гілкою після перенесення змін назад, а у разі збою лише повідомляє про ручне прибирання.
18
+ Поведінка: Функції взаємодіють для ізоляції роботи з кодом у worktree, перенесенні змін між робочими середовищами та керування життєвим циклом створюваного worktree. `ensureRunningInWorktree` гарантує роботу в ізольованому середовищі, тоді як `bringChangesBackToOriginal` переносить модифікації з worktree назад до основного репозиторію, використовуючи механізм копіювання, а не git merge. `removeAutoCreatedWorktree` забезпечує прибирання, видаляючи сам worktree, що виконується лише після завершення операції з `bringChangesBackToOriginal`.
22
19
 
23
20
  ## Публічний API
24
21
 
25
- - ensureRunningInWorktree — Гарантує ізольований worktree для наступних кроків; якщо вже працюєш у `.worktrees/`, лишає поточний каталог без змін, інакше створює окремий worktree та ставить залежності. За замовчуванням на брудному дереві питає в терміналі (y/N) дозвіл закомить і запушити зараз через `npx @7n/n push`, і лише на "ні" (або поза TTY) кидає; це можна послабити (`requireCleanTree: false`) лише там, де чистоту вже забезпечили іншим способом.
26
- - bringChangesBackToOriginal — Повертає зміни з автоствореного worktree у початкове дерево простим копіюванням файлів: нові й змінені файли переносять, видалені прибирають у вихідному дереві. Працює як перенесення фактичного стану, а не як merge.
27
- - removeAutoCreatedWorktree Прибирає тимчасовий worktree та пов’язану з ним ephemeral branch після того, як зміни вже перенесено назад; якщо прибирання не вдалось, залишає worktree для ручного розбору.
22
+ - ensureRunningInWorktree — Гарантує, що подальші кроки виконуються в ізольованому worktree
23
+ (`main.json.worktree: true`-контракт), навіть коли викликачдетермінований
24
+ JS-код, що не годує SKILL.md жодному LLM-агенту (тож агентський preflight-блок
25
+ з `worktree-notice.mjs` нікому виконувати). Якщо `cwd` вже під `.worktrees/`
26
+ (репо-конвенція) або `.claude/worktrees/` (worktree харнесу Claude Code,
27
+ куди `npx \@7n/mt worktree create` класти заборонено — `n-worktree.mdc`) —
28
+ повертає його без змін. Інакше сам створює `.worktrees/<branch>-<suffix>`
29
+ (`npx \@7n/mt worktree create`) і ставить залежності (`bun install`).
30
+
31
+ **Гейт на чисте дерево.** Auto-create читає стан і потім переносить зміни
32
+ назад копіюванням файлів (`bringChangesBackToOriginal`) — а не git merge.
33
+ Якщо у вихідному `cwd` вже є незакомічені зміни, вони НЕ потраплять у щойно
34
+ створений worktree (той — checkout HEAD), і перенесення назад мовчки
35
+ затерло б їх версією з worktree. Тому за замовчуванням (`requireCleanTree:
36
+ true`) на брудному дереві auto-create питає в терміналі (`deps.confirm`,
37
+ дефолт — y/N через stdin; поза TTY одразу "ні") дозвіл закомить і
38
+ запушити зараз через `npx \@7n/n push` (сквош усього робочого дерева в один
39
+ коміт + push у origin — сама команда підтвердження не питає, тому питаємо
40
+ ми, ДО виклику). На "ні"/поза TTY — кидає, як і раніше. Викликач, що
41
+ гарантує чистоту дерева сам (наприклад taze — SKILL.md вимагає цього як
42
+ передумову ще ДО виклику), може передати `requireCleanTree: false`, щоб не
43
+ платити за зайву git-команду і не питати підтвердження.
44
+ - bringChangesBackToOriginal — Переносить зміни з автоствореного worktree назад у вихідне дерево як
45
+ **untracked/незакомічені** правки (просте копіювання файлів, без git
46
+ merge/cherry-pick). Джерело істини — `git status --porcelain` у worktree:
47
+ для кожного шляху копіює файл, якщо він існує (модифікація/додавання), або
48
+ видаляє його у вихідному дереві, якщо existsSync каже, що в worktree його
49
+ вже нема (видалення). Перейменування (`old -> new` у porcelain) переносять
50
+ лише нову назву — стара лишається як була, прийнятний компроміс для
51
+ інструментів, що самі файли не перейменовують (ефект можливий лише як
52
+ побічний результат LLM-рефакторингу чи форматера).
53
+
54
+ **Untracked-директорія цілком.** Git схлопує щойно створену untracked
55
+ директорію в один porcelain-рядок із `/` на кінці (якщо в ній нема жодного
56
+ файлу, вже відомого git) — `copyFile` на такий шлях впав би (`EISDIR`/`ENOENT`)
57
+ і обривав би цикл, гублячи все, що йшло по порядку ітерації ДАЛІ. Такий
58
+ рядок (суфікс `/` або реальний каталог на диску) копіюється рекурсивно
59
+ (`copyDirectoryRecursive`) — весь вміст, а не один `copyFile`.
60
+ - removeAutoCreatedWorktree — Прибирає автостворений worktree разом з його ефемерною git-гілкою
61
+ (`npx \@7n/mt worktree remove <branch>`) — викликати лише ПІСЛЯ
62
+ `bringChangesBackToOriginal`, інакше зміни згорять разом з деревом.
63
+ Не кидає при провалі — це прибирання, а не крок, від якого залежить
64
+ результат прогону; провал лише логується, worktree лишається для
65
+ ручного розбору.
28
66
 
29
67
  ## Гарантії поведінки
30
68
 
@@ -3,23 +3,32 @@ type: JS Module
3
3
  title: inline-template-links.mjs
4
4
  resource: npm/scripts/lib/inline-template-links.mjs
5
5
  docgen:
6
- crc: 35230d2d
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: dde8124c
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
8
9
  score: 100
10
+ issues: judge-refine:kept-original,judge:inaccurate:0.96
11
+ judgeModel: openai-codex/gpt-5.4-mini
9
12
  ---
10
13
 
11
- Модуль збагачує текстовий контент, використовуючи конфігурації з package.json.snippet.json та package.json. Функція inlineTemplateLinks замінює текстові посилання на шаблони вбудованими блоками, якщо відповідні файли знаходяться у директорії правил. Функція appendDiscoveredMdcFiles доповнює текст вмістом усіх знайдених файлів `.mdc` з піддиректорій `js/` та `policy/` у директорії правил.
14
+ ## Огляд
15
+
16
+ Перетворює markdown-лінки на файли з `template/` у fenced-блоки з фактичним вмістом цих файлів і додає знайдені `.mdc`-правила, щоб зібраний `.mdc` лишався самодостатнім для подальшого використання без відносних шляхів. Поведінку реалізують `inlineTemplateLinks` і `appendDiscoveredMdcFiles`.
12
17
 
13
18
  ## Поведінка
14
19
 
15
- inlineTemplateLinks замінює посилання на шаблони в тексті на вбудовані блоки з вмістом файлу, якщо ці файли існують у вказаній директорії правил.
16
- appendDiscoveredMdcFiles додає до кінця тексту вміст усіх знайдених файлів `.mdc` з піддиректорій `js/` та `policy/` у директорії правил.
20
+ inlineTemplateLinks спочатку підбирає лише ті markdown-лінки, що ведуть у template-піддерево, і замінює їх самодостатнім вбудованим фрагментом із фактичним вмістом файлу; так правило перестає залежати від відносних посилань. Для вкладених прикладів і слот-файлів відновлюється читабельна назва цілі, зокрема для `package.json.snippet.json` і `package.json`, а формат fenced-блока обирається за розширенням вмісту. Якщо ціль не знайдено, обробка зупиняється з помилкою, щоб згенерований `.mdc` не містив битих посилань.
21
+
22
+ appendDiscoveredMdcFiles далі доповнює вже оброблений текст усіма знайденими `.mdc`-файлами з піддиректорій, які позначені через `concern.json`; це дає змогу зібрати повний пакет правил без ручного перелічення допоміжних файлів. Порядок стабільний: спочатку директори сортуються, потім файли всередині кожного каталогу, а результати додаються в кінець як один суцільний блок. Якщо таких директорій немає, початковий текст лишається без змін.
17
23
 
18
24
  ## Публічний API
19
25
 
20
- inlineTemplateLinks — Замінює посилання на шаблони в Markdown на вбудовані блоки, якщо шлях містить `/template/`. Помилка виникає, якщо цільовий файл посилання відсутній.
21
- appendDiscoveredMdcFiles Додає всі знайдені файли `.mdc` з папок `js/` та `policy/<concern>/`. Файли з `js/` йдуть першими, а потім файли з підпапок `policy/<concern>/` (у алфавітному порядку за `concern`, а потім за назвою файлу).
26
+ - inlineTemplateLinks — Finds markdown links whose path contains /template/ and replaces them with
27
+ inline fenced blocks. Reads file from join(ruleDir, rel-path).
28
+ Throws Error if a matched link target doesn't exist (fail loud — user must know).
29
+ - appendDiscoveredMdcFiles — Appends all *.mdc files from concern subdirectories (those with concern.json).
30
+ Concerns ordered alphabetically; files within each concern ordered alphabetically.
22
31
 
23
32
  ## Гарантії поведінки
24
33
 
25
- - Read-only: не виконує операцій запису (ФС/БД).
34
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: plugin-api.mjs
4
4
  resource: npm/scripts/lib/plugin-api.mjs
5
5
  docgen:
6
- crc: c614a880
6
+ crc: 72b55c0e
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  issues: judge:inaccurate:0.98
@@ -3,25 +3,80 @@ type: JS Module
3
3
  title: worktree-notice.mjs
4
4
  resource: npm/scripts/lib/worktree-notice.mjs
5
5
  docgen:
6
- crc: 174d1f15
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: 4feb8b6c
7
+ model: omlx/gemma-4-e2b-it-4bit
8
+ tier: local-min-retry
8
9
  score: 100
9
10
  ---
10
11
 
11
- Управляє вставкою інструкцій для виконання команд у ізольованому git-worktree у синкнутий `SKILL.md` (рішення D2 зі spec). Коли `main.json.worktree === true`, інструкції вставляються між маркерами `WORKTREE_START` та `WORKTREE_END`. Це забезпечує ре-синк ідемпотентність: наявний блок замінюється, а при `main.json.worktree === false` — видаляється. Механізм адаптований для агента, який читає `SKILL.md`.
12
+ ## Огляд
13
+
14
+ Цей файл містить інструкції для вбудовування вказівки про використання worktree-гілки в синкнутий текст `SKILL.md`. Він забезпечує ідемпотентне заміщення або видалення цього блоку залежно від значення `main.json.worktree`, забезпечуючи зв'язок з інструкціями щодо роботи з окремими Git-репозиторіями та інструментами для управління залежностями та бінарними викликами.
15
+
16
+ ## Behavior
17
+ Транслітерує кирилицю в ASCII для короткого suffix
18
+ @param {string} value вхідний текст
19
+ @returns {string} транслітерований текст
20
+
21
+ ### deriveSuffix
22
+ Робить короткий безпечний suffix для worktree-гілки з назви скіла
23
+ @param {string} content вміст `SKILL.md`
24
+ @returns {string} suffix до 10 символів
25
+ викликає: transliterate
26
+
27
+ ### buildNoticeBody
28
+ Тіло worktree-інструкції з конкретним суфіксом, щоб агент не питав назву гілки
29
+ @param {string} suffix короткий suffix задачі
30
+ @returns {string} markdown-блок без маркерів
31
+
32
+ ### buildBlock
33
+ Канонічний блок worktree-інструкції
34
+ @param {string} content вміст `SKILL.md`
35
+ @returns {string} текст блоку від START до END
36
+ викликає: buildNoticeBody
37
+
38
+ ### injectWorktreeNotice
39
+ Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`
40
+ @param {string} content вміст `SKILL.md`
41
+ @param {boolean} enabled чи має бути блок значення `main.json.worktree`
42
+ @returns {string} оновлений вміст ідемпотентно
12
43
 
13
44
  ## Поведінка
14
45
 
15
- WORKTREE_START: Позначає початок блоку інструкцій для роботи в окремому git-worktree.
16
- WORKTREE_END: Позначає кінець блоку інструкцій для роботи в окремому git-worktree.
17
- injectWorktreeNotice: Вставляє, оновлює або видаляє блок інструкцій для роботи в worktree у вмісті SKILL.md залежно від булевого значення.
46
+ Транслітерує кирилицю в ASCII для короткого suffix
47
+ @param {string} value вхідний текст
48
+ @returns {string} транслітерований текст
49
+
50
+ ### deriveSuffix
51
+ Робить короткий безпечний suffix для worktree-гілки з назви скіла
52
+ @param {string} content вміст `SKILL.md`
53
+ @returns {string} suffix до 10 символів
54
+ викликає: transliterate
55
+
56
+ ### buildNoticeBody
57
+ Тіло worktree-інструкції з конкретним суфіксом, щоб агент не питав назву гілки
58
+ @param {string} suffix короткий suffix задачі
59
+ @returns {string} markdown-блок без маркерів
60
+
61
+ ### buildBlock
62
+ Канонічний блок worktree-інструкції
63
+ @param {string} content вміст `SKILL.md`
64
+ @returns {string} текст блоку від START до END
65
+ викликає: buildNoticeBody, deriveSuffix
66
+
67
+ ### injectWorktreeNotice
68
+ Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`
69
+ @param {string} content вміст `SKILL.md`
70
+ @param {boolean} enabled чи має бути блок значення `main.json.worktree`
71
+ @returns {string} оновлений вміст ідемпотентно
72
+ викликає: buildBlock
18
73
 
19
74
  ## Публічний API
20
75
 
21
- WORKTREE_START — Позначає початок блоку, що описує робоче дерево.
22
- WORKTREE_END — Позначає кінець блоку, що описує робоче дерево.
23
- injectWorktreeNotice — Додає, змінює або видаляє блок робочого дерева у файлі `SKILL.md`.
76
+ - WORKTREE_START — Маркер початку worktree-блоку (стабільний, не залежить від тексту всередині).
77
+ - WORKTREE_END — Маркер кінця worktree-блоку.
78
+ - injectWorktreeNotice — Вставляє / оновлює / видаляє worktree-блок у вмісті `SKILL.md`.
24
79
 
25
80
  ## Гарантії поведінки
26
81
 
27
- - Read-only: не виконує операцій запису (ФС/БД).
82
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Інлайн template-посилань у .mdc-правилах: markdown-лінки на файли з тек
3
+ * template/ замінюються fenced-блоками з фактичним вмістом файлу, щоб
4
+ * згенероване правило було самодостатнім без відносних шляхів.
5
+ */
1
6
  import { existsSync } from 'node:fs'
2
7
  import { readFile } from 'node:fs/promises'
3
8
  import { basename, extname, join } from 'node:path'
@@ -3,42 +3,45 @@ type: JS Module
3
3
  title: run-detectors.mjs
4
4
  resource: npm/scripts/lib/lint-surface/run-detectors.mjs
5
5
  docgen:
6
- crc: a0f45fc3
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: e9224e37
7
+ model: openai-codex/gpt-5.4-mini
8
+ tier: cloud-min
8
9
  score: 100
9
- issues: judge:inaccurate:0.98
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
- Цей файл є детектором для уніфікованої поверхні лінту, який сканує код без внесення змін. Він виконує процес вибору області перевірки (`scope-selection`), збирає всі виявлені порушення (`normalized violations`) для кожного аспекту (`concern`) відповідно до конфігурації `.n-rules.json`. Цей компонент працює у режимі `Detect-only`, тобто він не вносить жодних мутацій і не використовує LLM. Порушення передаються до пайплайну виправлення (Fix-pipeline) для подальшої обробки.
16
+ Файл формує єдину поверхню для `n-rules lint --no-fix`: від discovery правил і вибору меж запуску до виконання `lint` для кожного concern та збору нормалізованих violations. Його результатом є список порушень, який використовує fix-pipeline для подальшої обробки, тоді як сам detect не змінює дерево файлів.
16
17
 
17
18
  ## Поведінка
18
19
 
19
- Поведінка
20
- DEFAULT_RULES_DIR визначає шлях до стандартної директорії з правилами.
21
- buildDetectPlan створює впорядкований план прогону лінтера, збираючи всі відповідні концерни та визначаючи область їх сканування.
22
- detectAll виконує прохід лінтера у режим детекції, збираючи всі виявлені порушення та повертаючи код виходу.
20
+ DEFAULT_RULES_DIR задає базовий корінь правил, від якого стартує discovery, коли споживач не передав власні каталоги.
23
21
 
24
- **Внутрішній паралелізм (ADR 260716-1354-внутрішній-паралелізм-lint-оркестратора).** `detectAll` читає `N_RULES_LINT_CONCURRENCY` (дефолт `1` production-паралелізм ще не пройшов benchmark-gates ADR): за замовчуванням план виконується повністю послідовно (`detectPlanSequentially`), спостережувано ідентично до-ADR поведінці. При `concurrency > 1` план ділиться на два лейни через `blocking-inventory.mjs` (`isSerialLane`) і виконується через `scheduler.mjs` (`runPlanConcurrently`, `detectPlanConcurrently`): parallel lane — доведені non-blocking concern-и, bounded pool до `concurrency`; serial lane — решта, строго послідовно. Перший `DetectorError` (будь-який лейн) зупиняє нові старти, `AbortController` сигналізує вже запущеним async-детекторам (`ctx.signal`), а вже завершені concern-и лишаються в результаті `exitCode 2` пріоритетний над частковими violations. Фінальний масив violations завжди стабільно сортується за `(ruleId, concernId, file, data.line, reason)` — незалежно від порядку завершення (`sortViolations`), навіть при `concurrency=1`.
22
+ buildDetectPlan спочатку визначає набір rules-каталогів, потім відбирає лише доступні concern-и з урахуванням capability, далі будує план виконання за режимом прогону: scoped, delta, full або repo-wide. Сам план фіксує, які concern-и запускаються whole-repo, а які лише по перетину з файлами, щоб detect і fix-pipeline працювали з однаковою картиною.
25
23
 
26
- ## Публічний API
27
-
28
- * DEFAULT_RULES_DIR — Містить набір стандартних правил для перевірок.
29
- * buildDetectPlan — Створює план виконання перевірок, охоплюючи визначені області.
30
- * detectAll — Виконує повний прохід пошуку проблем і повертає всі виявлені порушення та код виходу.
31
- * loadEnabledLintRules — Discovery-фасад для споживачів поза detect/fix-конвеєром (`ci plan`): concerns за rule-id + set активних правил.
32
- * computeActiveDomains — Активність доменів для файлового набору (лише per-file concerns) — єдине джерело правди для `ci plan`: «plan сказав true» ⇔ «lint щось запустить».
24
+ loadEnabledLintRules використовує той самий discovery-ланцюжок, але повертає не план, а повну мапу concern-и за rule-id разом із множиною активних правил. Це потрібно зовнішнім споживачам, які мають знати, що реально доступно для прогону, не запускаючи сам detector-цикл.
33
25
 
34
- **Осі плану (сервіс-канон):** scoped + explicit files (`lint js --path <dir>`) лише per-file concerns названих правил × перетин; `pathMode` (дефолтний `--path`) → full-scope concerns виключені з delta-плану; `repoWide` (`--repo-wide`) ЛИШЕ full-scope concerns enabled-правил, whole-repo (окремий CI-workflow, не гейтить деплой).
26
+ computeActiveDomains дає скорочений зріз цієї ж моделі: для заданого набору файлів показує, які rule-id справді активуються хоча б одним per-file concern-ом. Full-scope перевірки тут навмисно не враховуються, бо їхня зона відповідає repo-wide прогону.
35
27
 
36
- ## Гарантії поведінки
28
+ detectAll бере готовий план, виконує його, збирає normalized violations і повертає ще й derived exitCode. Увесь шлях read-only: нічого не записує в дерево, не змінює конфіг і не покладається на мутації поза межами збирання результатів. Фільтрація та видимість правил спираються на .n-rules.json, тож саме він визначає, які rules каталоги й concern-и вважаються активними.
37
29
 
38
- - Read-only: не виконує операцій запису (ФС/БД).
30
+ ## Публічний API
39
31
 
40
- **Multi-dir (плагіни):** `effectiveRulesDirs` додає rules-каталоги плагінів з `.n-rules.json` (hot-path: без install, quiet); `readLintConcernsByRuleMulti` зливає концерни за іменем (перший власник виграє) — плагін може додавати концерни до правила ядра (mixin).
32
+ - DEFAULT_RULES_DIR Цей файл: npm/scripts/lib/lint-surface/run-detectors.mjs PACKAGE_ROOT = npm (4 dirname угору).
33
+ - buildDetectPlan — Будує план прогону для заданих опцій (discovery + scope-table).
34
+ Спільне джерело для detect-only і fix-pipeline.
35
+ - loadEnabledLintRules — Discovery-фасад для споживачів поза detect/fix-конвеєром (`ci plan`):
36
+ concerns за rule-id (ядро + плагіни, capability-фільтр) і set активних правил.
37
+ - computeActiveDomains — Активність доменів (rule-id) для заданого файлового набору — єдине джерело
38
+ правди для `ci plan`: домен «активний», якщо хоч один його **per-file**
39
+ concern тригериться на цих файлах (та сама таблиця planConcernForDelta, що
40
+ й `lint <domain> --path` → «plan сказав true» ⇔ «lint щось запустить»).
41
+ Правила без жодного per-file concern не потрапляють у результат (їхні
42
+ full-scope перевірки — справа `--repo-wide`).
43
+ - detectAll — Запускає detect-only прохід. Повертає всі violations і похідний exitCode.
41
44
 
42
- **Capability-гейт:** `filterByCapabilities` відкидає концерни з незадоволеним `requires.capability` (capabilities надають встановлені плагіни через маніфест `n-rules.capabilities`; явний `opts.capabilities` у тестах перекриває резолв).
45
+ ## Гарантії поведінки
43
46
 
44
- **Warning про rule-id без concern-ів:** якщо rule-id з `.n-rules.json#rules` не має жодного concern-а серед усіх `rulesDirs` (ядро + плагіни) — `console.error` попереджає про можливий дрейф конфігу (типово: правило переїхало в плагін, якого консюмер не підключив у `plugins[]`). Rule-id з існуючим каталогом, але без `concern.json` (документаційні правила на кшталт `feedback`), warning не тригерить.
47
+ - Власних операцій запису (ФС/БД) у файлі немає; виклики імпортованих модулів можуть писати.
@@ -3,32 +3,48 @@ type: JS Module
3
3
  title: tier-sampling-experiment.mjs
4
4
  resource: npm/scripts/lib/lint-surface/tier-sampling-experiment.mjs
5
5
  docgen:
6
- crc: f6a46f92
7
- model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ crc: 959712b3
7
+ model: openai-codex/gpt-5.5
8
+ tier: cloud-avg
8
9
  score: 100
9
- issues: judge:inaccurate:0.98
10
+ issues: judge:error
10
11
  judgeModel: openai-codex/gpt-5.4-mini
11
12
  ---
12
13
 
13
14
  ## Огляд
14
15
 
15
- Файл слугує експериментальною обгорткою для перевірки процесу виправлення (lint fix ladder). Він моделює ізольовані потенційні рішення для певного рівня, відкочуючи робоче дерево до початкового стану S1 перед кожною спробою. Мета модуля ізольовано протестувати кандидати, які пройшли автоматичне виявлення чистоти, щоб оцінити їхню цінність через механізм зворотного зв'язку.
16
+ Експериментальний harness моделює isolated sampling для окремого tier-а lint fix ladder: будує experiment-only rung-и, проганяє sampling-кандидатів із відкотом до S1 і лишає лише candidate, що пройшов canonical detect. Файл існує, щоб перевіряти sampling/consensus поза production `runFixPipeline`, залишаючи judge/consensus тільки джерелом feedback, а не рішенням про patch.
17
+
18
+ Публічні точки входу: `EXPERIMENT_TIER_ORDER`, `buildExperimentLadder`, `samplingProfilesForTier`, `chooseCleanCandidate`, `runTierSamplingExperiment`.
19
+
20
+ Модуль працює fail-safe: перехоплює помилки й не кидає винятків назовні.
16
21
 
17
22
  ## Поведінка
18
23
 
19
- EXPERIMENT_TIER_ORDER визначає фіксований порядок експериментальних рівнів.
20
- buildExperimentLadder конструює список експериментальних етапів на основі наданих моделей для кожного tier.
21
- samplingProfilesForTier генерує список можливих профілів відбору для певного tier.
22
- chooseCleanCandidate вибирає найкращий кандидат серед усіх спроб, які пройшли перевірку на чистоту.
23
- runTierSamplingExperiment виконує послідовність випробувань (sampling) для заданого tier, тестуючи кандидатів, обираючи найкращого та застосовуючи його патч для фінальної перевірки.
24
+ `EXPERIMENT_TIER_ORDER` задає порядок експериментальних tier-ів, за яким формується ladder для isolated sampling поверх lint fix pipeline.
25
+
26
+ `buildExperimentLadder` створює окремий experiment-only ladder із підтримкою `cloud-max`, не змінюючи production-послідовність `runFixPipeline`. Дані про моделі й timeouts перетворюються на набір rung-ів, які далі використовуються як сценарії окремих випробувань.
27
+
28
+ `samplingProfilesForTier` визначає набір sampling-кандидатів для конкретного tier-а. Якщо для tier-а передані перевизначення, вони стають джерелом профілів; інакше використовується стандартний набір для цього рівня.
29
+
30
+ `runTierSamplingExperiment` бере violations, базовий контекст, rung і sampling-кандидатів, після чого послідовно тестує кожного кандидата в ізольованому стані S1. Для кожної спроби робоче дерево відкочується до початкового snapshot, запускається worker, фіксуються змінені файли, виконується canonical detect і записується результат спроби разом із telemetry та latency.
31
+
32
+ Після всіх спроб `chooseCleanCandidate` обирає лише чистий candidate: пріоритет має менша кількість змінених файлів, менший patch і коротша latency. Якщо чистого кандидата немає, експеримент завершується без застосування patch до робочого дерева.
33
+
34
+ Якщо чистий candidate знайдено, `runTierSamplingExperiment` застосовує саме його зміни як фінальний результат tier sampling. Judge/consensus не приймає рішення про застосування patch: його відповідь повертається тільки як feedback поруч із attempts, selected candidate, фінальними violations і clean-статусом.
35
+
36
+ Модуль працює fail-safe: помилки окремих кандидатів або допоміжних етапів перетворюються на результати спроб і не викидаються назовні. Кешування між запусками або кандидатами не використовується.
24
37
 
25
38
  ## Публічний API
26
39
 
27
- * EXPERIMENT_TIER_ORDER — Визначає пріоритетність випробувань (tiers).
28
- * buildExperimentLadder — Створює ієрархію для експериментів, не впливаючи на конфігурацію продакшену.
29
- * samplingProfilesForTier — Повідомляє про доступні варіанти збору зразків для конкретного рівня випробувань.
30
- * chooseCleanCandidate — Вибирає оптимальний варіант з усіх тестових спроб, базуючись на мінімальній кількості змін у файлах, розмірі патчу та латентності.
31
- * runTierSamplingExperiment Проводить комплекс випробувань для одного рівня: для кожного варіанту повертається до початкового стану, запускається робочий процес, оцінюється якість, а при виборі — застосовується відповідний виправлення.
40
+ - EXPERIMENT_TIER_ORDER — Порядок tier-ів експериментального ladder — від локальної моделі до найсильнішої хмарної.
41
+ - buildExperimentLadder — Будує experiment-only ladder із `cloud-max`. Production ladder це не змінює.
42
+ - samplingProfilesForTier — Повертає можливі sampling profiles для заданого tier-а.
43
+ - chooseCleanCandidate — Дефолтний вибір найкращого (clean) кандидата серед усіх спроб.
44
+ Вибір відбувається за критеріями: менша кількість змінених файлів, менший розмір patch, менша латентність.
45
+ - runTierSamplingExperiment — Виконує послідовність випробувань (sampling) для одного tier.
46
+ Для кожного кандидата виконується rollback до S1, запускається worker,
47
+ оцінюється чистота, і якщо кандидат обраний, застосовується його patch.
32
48
 
33
49
  ## Гарантії поведінки
34
50
 
@@ -25,7 +25,7 @@ import { renderViolations, renderDiagnostics } from './render.mjs'
25
25
  import { createProgressReporter } from './progress.mjs'
26
26
  import { runPlanConcurrently } from './scheduler.mjs'
27
27
 
28
- // Цей файл: npm/scripts/lib/lint-surface/run-detectors.mjs → PACKAGE_ROOT = npm (4 dirname угору).
28
+ /** Цей файл: npm/scripts/lib/lint-surface/run-detectors.mjs → PACKAGE_ROOT = npm (4 dirname угору). */
29
29
  export const DEFAULT_RULES_DIR = join(dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url))))), 'rules')
30
30
 
31
31
  /**
@@ -10,6 +10,7 @@ import { dirname } from 'node:path'
10
10
 
11
11
  import { createSnapshot } from './snapshot.mjs'
12
12
 
13
+ /** Порядок tier-ів експериментального ladder — від локальної моделі до найсильнішої хмарної. */
13
14
  export const EXPERIMENT_TIER_ORDER = Object.freeze(['local-min', 'cloud-min', 'cloud-avg', 'cloud-max'])
14
15
 
15
16
  const DEFAULT_LOCAL_TIMEOUT_MS = 300_000