fix(test/no-process-chdir): детект по AST — цитата правила в коментарі більше не порушення - #501
Merged
Merged
Conversation
…і більше не порушення
Порядковий regex `process\.chdir\s*\(` спрацьовував і на ЗГАДЦІ виклику в
прозі: доккоментар `wasm-plugin-parity-php.test.mjs:181` цитує саме це
правило разом із дужкою, тож `lint --no-fix` репортив порушення на будь-якому
брудному дереві, включно з `origin/main`. Гірше за сам false positive був його
«фікс»: LLM-автофікс переписував цитату правила — псував документацію замість
коду (у задачі 2026-08-26 такий автофікс відкотили свідомо).
- `find_process_chdir_call_lines` шукає `CallExpression` через `oxc_parser`
(той самий движок, що AST-концерни Q3/Q4 цього ж крейта) — коментарі, JSDoc
і рядкові/шаблонні літерали структурно не спрацьовують.
- Заодно ловляться `process['chdir'](…)` і `process?.chdir(…)`, яких regex не
бачив зовсім. Голий `chdir(…)` з `import { chdir } from 'node:process'`
лишається відомою дірою знятого JS-канону — свідомо не розширюємо.
- Непарсовний файл не мовчить: на syntax-error лишається regex-фолбек
(свідома розбіжність із `find_offenders_in_body`, де ціна помилки менша).
- Дешевий префільтр `contains("chdir")` — щоб не парсити кожен тестовий файл
репозиторію заради концерну, який майже завжди мовчить.
Перевірено наскрізь через napi-міст із wasm, зібраним до і після:
BEFORE — рівно те порушення на `wasm-plugin-parity-php.test.mjs:181`,
AFTER — порожньо; реальний виклик на tmp-фікстурі далі падає.
+9 unit-тестів крейта, +1 golden через реальний wasm-компонент. Еталони
`fixtures/wasm-parity/test/no-process-chdir.json` не змінилися — усі три кейси
там суто кодові.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Проблема
npx @7n/rules lint --no-fixна будь-якому брудному дереві репортив одне порушення, якого не вносила поточна задача — воно є і наorigin/main:У рядку 181
process.chdir(dir)зустрічається лише в доккоментарі, який цитує саме це правило (no-process-chdir.mdc, «Заборонаprocess.chdirу тестах»), а не у виконуваному коді. Порядковий regexprocess\.chdir\s*\(не розрізняє код і прозу — відкривна дужка тут не рятує, бо цитата написана разом із нею.Гірше за сам false positive був його «фікс»: LLM-автофікс лінта переписував прозу, підміняючи точну цитату правила на переказ — псував документацію замість коду. У задачі 2026-08-26 такий автофікс відкотили свідомо.
Рішення
Детект концерну переїхав з порядкового regex на AST.
find_process_chdir_call_linesпарсить файл черезoxc_parser— той самий движок, що вже вживають AST-концерни задач Q3/Q4 у цьому ж крейті — і збирає рядкиCallExpression, чий callee —process.chdir. Коментарі, JSDoc і рядкові/шаблонні літерали в AST неCallExpression, тож структурно не спрацьовують.process['chdir'](…)іprocess?.chdir(…), яких regex не бачив зовсім.BTreeSetрядків — два виклики в одному рядку дають одну діагностику, як і раніше.contains("chdir"), щоб не парсити кожен тестовий файл репозиторію заради концерну, який майже завжди мовчить (full-scope обхід віддає сюди весь**/*.test.{mjs,js}).find_offenders_in_body, де портparseProgramOrNullтакий файл відкидає цілком — там ціна помилки хибний шлях у діагностиці, тут process-wide мутація cwd, через яку вже був rogue-коміт у реальний репозиторій.Свідомо поза скоупом: голий
chdir(dir)черезimport { chdir } from 'node:process'як і раніше не ловиться — це відома діра ще знятого JS-канону (npm/CHANGELOG.md, запис проstryker_config). Фікс прибирає хибні спрацювання, а не додає нові сутності детекту.Перевірка
Концерн прогнано по всьому репозиторію через napi-міст із wasm, зібраним із коду до і після:
Позитивний контроль на tmp-фікстурі: реальний
process.chdir("/tmp")далі падає, доккоментар із цитатою правила — ні.Зелені: 385 unit-тестів
plugin-lang-js, 86 goldenrules-plugin-host, 255 parity-тестів,cargo clippy,cargo fmt,lint text.Еталони
fixtures/wasm-parity/test/no-process-chdir.jsonне змінювалися — усі три кейси там суто кодові.Тести
+9 unit-тестів у крейті: цитата в JSDoc і в лінійному коментарі, фікстура в рядковому й шаблонному літералі, чужий
foo.chdir, computed-виклик, optional-chaining, одна діагностика на рядок, фолбек на syntax-error. +1 наскрізний golden через реальний wasm-компонент уrules-plugin-host.Поза цим PR
npx @7n/rules lint --no-fixу робочому дереві обривається раніше на💥 detector npm-module/package_structure: немає main.mjs. Це не від цієї зміни: відтворюється на чистому HEAD з будь-якою тривіальною правкою і не лікується ні локально зібраним napi-аддоном черезN_RULES_NATIVE_ADDON, ні синком — схоже на дрейфnode_modules/@7n/rules-darwin-arm64@1.100.9проти репо 1.100.11. Саме тому концерн перевірявся напряму через міст.🤖 Generated with Claude Code