This repository was archived by the owner on Sep 11, 2026. It is now read-only.
Repository navigation
feat: host-diff — портовано python/ruff, перший exec-tool fix - #534
Merged
Merged
Conversation
…f, перший exec-tool fix Клас exec-tool fix (фіксер спавнить зовнішній процес, що сам мутує файли на диску) залишався не портованим у wasm-міграції (§2.51 реєстру відкритих питань): гість не міг просигналити хосту, що змінив файли, і `wasmFixPattern` гейтив застосування на непорожній `FixPlan::edits`. Перевірка §2.51 (за проханням власника): «перешкода 1» (продакшн-міст не доносить файлів) уже була знята §2.53 (delta_files). «Перешкода 2» (rollback-контракт) виявилась хибною засновкою — T0-фаза (`run-fix.mjs`) не несе `recordWrite` НІ для одного T0-фіксера, декларативного чи exec-tool; справжня перешкода вужча — `FixPlan::edits` лишався порожнім, попри реальну мутацію диска. Рішення — host-diff: `run_wasm_concern_fix` (crates/rules-napi/src/lib.rs) сам знімає знімок файлів ПОВНОГО glob-у концерну до/після виклику `fix()` і синтезує `Write`/`Delete`-edits із різниці (`diff_snapshot_edits`) — без зміни WIT, гість нічого не декларує. Пілот — `python/ruff` (`fix_ruff`, crates/plugin-lang-python/src/lib.rs): точний порт fix-ruff.mjs (`uv run --frozen ruff check --fix .` + `ruff format .`), повертає порожній план — синтез повністю на хості. Новий тест wasm-fix-exec-tool-python-ruff.test.mjs доводить парність через РЕАЛЬНИЙ napi-міст (не прямий виклик гостя), непорожній план із точним змістом, відсутність double-run через продакшн-конвеєр (лічильник = 5, перевірено дією на коді до і після фіксу) і регресію декларативних фіксерів (267+231 наявних тестів парності — без змін). Реєстр: §2.63 коригує §2.51 (обидві перешкоди). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
vitaliytv
force-pushed
the
worktree-agent-a90bad1d132447a1f
branch
from
August 28, 2026 16:42
1df9e3a to
d47b900
Compare
Знайдено побіжно під час §2.64. `detect.mjs` передає `ctx.files ?? null`, розраховуючи, що хост побудує batch за glob-ом. Але `run_wasm_concern` робить це ЛИШЕ для full-scope: для per-file гілка `_` віддає порожній `Vec::new()`. Гість дістає нуль файлів, повертає нуль діагностик, концерн звітує «чисто» — без помилки, попередження чи сліду в логу. Та сама асиметрія двох napi-сигнатур, яку §2.53 полагодила для `fix` (дельта запиту) і §2.52 зробила гучною — на detect-боці не полагоджена й досі мовчазна. Обсяг: девʼять `per-file`-концернів у чотирьох гостях, усі не перевіряються в `--full`. Запис відкритий, без коду: зміна зачіпає всі wasm-плагіни, а §2.64 — про fix-контур. 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.
Summary
run_wasm_concern_fix(crates/rules-napi/src/lib.rs) сам знімає знімок файлів повного glob-у концерну ДО й ПІСЛЯ викликуfix()і синтезуєWrite/Delete-edits із різниці (diff_snapshot_edits) — без зміни WIT, гість нічого не декларує (fail-open інакше не був би виявлений).python/ruff(fix_ruff,crates/plugin-lang-python/src/lib.rs): точний портfix-ruff.mjs(uv run --frozen ruff check --fix .+ruff format .), повертає порожній план — синтез повністю на хості. JS-канон НЕ видалено (парність, не заміна).§2.51 — перевірка розбору (за проханням автора задачі)
Обидва пункти §2.51 підтверджено НЕ структурними блокерами:
delta_files).fixConcernCore/runT0Phase,npm/scripts/lib/lint-surface/run-fix.mjs) передаєlintCtxбезrecordWriteдля ВСІХ T0-фіксерів (декларативних теж) — модульний доккомент прямо документує «T0 — permanent, поза rollback». Справжня перешкода була вужчою:FixPlan::editsлишався порожнім, попри реальну мутацію диска — саме це ламалоwasmFixPattern-гейт (edits.length > 0) іguestFix-пріоритет, не rollback.Деталі, код-цитати й повний розбір — реєстр
docs/plans/2026-08-05-open-questions-register.md§2.63.Скоуп діфу — свідомий вибір
Знімок бере весь glob концерну (
contribution.glob, напр.**/*.py), а НЕ лишеrequest.files/delta_files.ruff check --fix .мутує весьcwd, не обмежується дельтою запиту — скоуп «лише дельта» був би дешевшим, але тихо пропустив би мутації поза нею (принцип проекту: «гучно й повільніше, ніж тихо й швидше»). Ціна: подвійне читання glob-у на коженfix()-виклик, для ВСІХ wasm-концернів (інфраструктура спільна). Межа: якщо концерн не задекларований уdescribe().concerns, діф пропускається (без регресії, без нового захисту).Test plan
cargo test -p rules-napi— 13/13 (без регресій)cargo test -p plugin-lang-python— 69/69 (без регресій)npm/scripts/lib/lint-surface/tests/wasm-fix-exec-tool-python-ruff.test.mjs(3 активних + 1 чесно пропущений — немаєuv/ruffу CI-середовищі):runWasmConcernFixнапряму (РЕАЛЬНИЙ napi-міст) на фейковомуuv— план непорожній, несеwrite-edit саме на цільовий файл;python/doc_comments(декларативний) — регресія: host-diff нічого не додає;runFixPipeline(повний продакшн-конвеєр) — лічильник спавнів фейковогоuv= точно 5, доводить відсутність double-run;uv/ruff(skip зconsole.warn, якщо тулів немає).git stash+ перезбірка гостя) — обидва падали (plan.edits.length === 0,code !== 0); післяstash pop— зелені.wasm-plugin-parity.test.mjs(267),wasm-plugin-parity-python.test.mjs,wasm-fix-e2e.test.mjs,fix-delta-files.test.mjs,run-fix.test.mjs— 231 додатково, усі проходять без змін (декларативні фіксери типуjs/doc_commentsповодяться байт-у-байт як раніше).cargo build --workspace --release— чисто.🤖 Generated with Claude Code