This repository was archived by the owner on Sep 11, 2026. It is now read-only.
Repository navigation
fix(rules-napi): порожній fix-батч не-full-scope концерну — гучна помилка - #517
Merged
Merged
Conversation
…илка #513 додав full-scope fallback, бо whole-batch концерн діставав порожній `FixRequest::files` і гість затирав конфіги замість merge. Але умова фіксу — `scope == Full`, тож гілка `_ => Vec::new()` і далі мовчки віддавала порожній батч будь-якому не-full-scope концерну з file-less діагностиками. Другий незалежний прояв того самого класу. Контракт МОВЧИТЬ про цей випадок, і це головна відповідь задачі: `diagnostic.file: option<string>` ніде не обумовлений `scope`, тож агрегована діагностика без `file` для per-file концерну — легітимний результат `detect()`. Але full-scope glob-обхід тут НЕ безпечний: він розширив би fix за межі дельти, порушивши scope, який концерн сам заявив. Отже ні «помилка концерну», ні «розширити fallback» не є правильними беззастережно — і замість вгадування додано типізовану помилку саме на неоднозначному стані: `target_files` порожній, `diagnostics` НЕ порожній, концерн не `full`. Порожні `diagnostics` і далі дають порожній план без помилки. Відкрите питання винесено у WIT-доккомент біля `record diagnostic` із двома явними варіантами для того, хто вирішуватиме: заборонити `file: none` для per-file, або дати спосіб нести per-file-дельту без per-diagnostic атрибуції. JS-бік ловить помилку в `computeWasmFixPlan` — `console.error` і деградація до порожнього плану, той самий graceful-degrade контур, що вже несуть `loadT0Patterns`/`runConcernDetector`: падіння одного концерну не вбиває весь fix-прогін. Виконавець спростував твердження з мого брифу: `rust/check` НЕ є другим кандидатом на цю ваду — він `scope = "full"`, тобто вже йшов безпечною гілкою. Перевірено особисто в `plugin-lang-rust/plugin.toml`. Він також відмовився приймати за факт мої посилання на §2.49/§2.51 — їх немає на main, вони живуть у ще не змержених PR. Правильна обережність. Тести: rules-napi 10 (з фікстурою `test/guest-fix-full-scope`), wasm-fix-e2e і parity lang-js разом 265. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
vitaliytv
force-pushed
the
fix/napi-empty-batch
branch
from
August 28, 2026 07:59
952b20d to
b7f216b
Compare
This was referenced Aug 28, 2026
vitaliytv
added a commit
that referenced
this pull request
Aug 28, 2026
…о питання #517 (#519) #517 зробив неоднозначний порожній fix-батч гучною помилкою і лишив розвилку у WIT-доккоменті: заборонити `file: none` для `per-file` (а) чи дати спосіб нести дельту без per-diagnostic атрибуції (б). Обрано (б). Корінь був не в тому, що «контракт мовчить», а в асиметрії двох napi-сигнатур: `run_wasm_concern` ПРИЙМАЄ дельту явним параметром, `run_wasm_concern_fix` реконструює її з `diagnostics[].file`. Інформація в системі була — JS тримає `item.files` і сусіднім викликом віддає її в `detect`. Прогалина проводки, не знання. Розширювати WIT не довелось: `fix-request.files` існує з 3.0.0 як окреме поле, не похідне від `diagnostics`. Додано шостий опційний `delta_files` у napi й проводку `item.files` → `loadT0Patterns` → `wasmFixPattern`. Жодного ABI-руху, guest-и не чіпані. Порядок джерел `FixRequest::files`: `diagnostics[].file` → full-scope glob для `scope: full` → явна дельта → типізована помилка. Помилка #517 лишається backstop-ом на проводку; порожня дельта за відповідь не приймається. Знімає «Перешкоду 1» з розбору порту `python/ruff` (#516) — той лишається відкладеним тільки через межу exec-tool. Тести: cargo rules-napi 10 → 13, новий fix-delta-files.test.mjs (2) на host-проводку. Обидва якорі перевірено дією — нейтралізація гілки валить рівно rust-тест, зняття аргументу — рівно JS-тест. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
vitaliytv
added a commit
that referenced
this pull request
Aug 28, 2026
…а) (#520) JS-міст fix-плану (nativeFixPattern/wasmFixPattern у run-fix.mjs) робив голий unlink() на delete-правку в try{}catch{} — на директорію unlink падає (EPERM/EISDIR), а catch{} ковтав будь-яку помилку, не лише "шлях уже відсутній". Гість, що емітить delete на теку (напр. .firebase/, .yarn), лишався зеленим і безрезультатним — той самий клас вади, що #513/#517. Rust-бік (t0.rs::to_edit_plan) уже вміє розгортати Delete-теку в пофайлові Delete + прибирати спорожнілі теки після commit. Обидва майже однакові цикли злиті у спільний applyPlanEdit(): delete тепер іде через fs.rm(recursive:true) — той самий кінцевий стан, без потреби у per-file журнальній машинерії Rust-боку. Ловиться лише ENOENT (задокументований best-effort); будь-яка інша помилка кидає Error(cause) і зупиняє прогін. Заразом виправлено застарілий доккомент fix_abie_security.rs, що описував уже видалений apply_plan і стверджував, що виконавець не вміє видаляти директорії. 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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
#513 додав full-scope fallback, бо whole-batch концерн діставав порожній
FixRequest::filesі гість затирав конфіги замість merge.Але умова фіксу —
scope == Full. Гілка_ => Vec::new()і далі мовчки віддавала порожній батч будь-якому не-full-scope концерну з file-less діагностиками. Другий незалежний прояв того самого класу.Контракт мовчить — і це головна відповідь задачі
diagnostic.file: option<string>ніде не обумовленийscope. Тож агрегована діагностика безfileдля per-file концерну — легітимний результатdetect().Але full-scope glob-обхід тут не безпечний: він розширив би fix за межі дельти, порушивши scope, який концерн сам заявив.
Отже ні «помилка концерну», ні «розширити fallback» не є правильними беззастережно. Замість вгадування — типізована помилка саме на неоднозначному стані:
target_filesпорожній,diagnosticsне порожній, концерн неfull. Порожніdiagnosticsі далі дають порожній план без помилки.Відкрите питання винесено у WIT-доккомент біля
record diagnostic, із двома явними варіантами для того, хто вирішуватиме: заборонитиfile: noneдля per-file, або дати спосіб нести per-file-дельту без per-diagnostic атрибуції.Деградація, не падіння прогону
JS-бік ловить помилку в
computeWasmFixPlan—console.errorі порожній план. Той самий graceful-degrade контур, що вже несутьloadT0Patterns/runConcernDetector: падіння одного концерну не вбиває весь fix-прогін.Виконавець спростував два твердження з мого брифу
rust/checkНЕ є другим кандидатом на цю ваду — вінscope = "full", тобто вже йшов безпечною гілкою. Перевірив особисто вplugin-lang-rust/plugin.toml. Це виправляє й опис #514, де я повторив цю помилку.Посилання на §2.49/§2.51 він відмовився приймати за факт — їх немає на
main, вони живуть у ще не змержених PR. Правильна обережність: я процитував їх так, ніби вони вже там.Тести
rules-napi10 (з новою guest-фікстуроюtest/guest-fix-full-scope),wasm-fix-e2e+ paritylang-jsразом 265.🤖 Generated with Claude Code