diff --git a/docs/architecture-audit-2026-10.md b/docs/architecture-audit-2026-10.md index eb5986e..fdae775 100644 --- a/docs/architecture-audit-2026-10.md +++ b/docs/architecture-audit-2026-10.md @@ -73,13 +73,11 @@ handleFiles, эффекты, workspace-разметка). Декомпозици колбэков `on*`). Нужен группирующий view-model-объект или разбиение на подкомпоненты. -### M4. `runMask` обходит санитизацию параметров +### M4. `runMask` обходил санитизацию параметров — СДЕЛАНО (2026-10) -`SchemaToolView.svelte:591`: основной путь `run()` идёт через `execute` → -`sanitizeSchemaParams` (`executor/executor.ts:153`), а mask-превью передаёт -`step.params` как есть. Значения вне диапазона/невалидный hex дойдут до -core-функций без клампинга. (Сам обход executor для `domOnly`-маски каноничен по -`docs/architecture.md`; рассинхрон санитизации — нет.) +`SchemaToolView.svelte` (derived `maskResults`): параметры шага теперь проходят +`sanitizeSchemaParams(stepSchema, step.params, { source: input })` — тот же +контракт, что в `executor/executor.ts` (вход шага как source-контекст). ### M5. UI-метаданные дропдауна скачивания в core-слое diff --git a/web/src/lib/components/schema/SchemaToolView.svelte b/web/src/lib/components/schema/SchemaToolView.svelte index f78499c..122c8f3 100644 --- a/web/src/lib/components/schema/SchemaToolView.svelte +++ b/web/src/lib/components/schema/SchemaToolView.svelte @@ -44,6 +44,7 @@ import { applySourceDefaults, clampSourceAwareMaxes, + sanitizeSchemaParams, type ToolSchema, } from "$lib/registry-schema"; import { onMount } from "svelte"; @@ -99,11 +100,14 @@ if (!stepTool?.runMask) return; const input = i === 0 ? source : stepResults[i - 1]; if (!input) return; + // Same contract as executor.ts: params are sanitized against the + // schema with the step input as the source context. + const stepSchema = toolSchemaOf(step); + const params = stepSchema + ? sanitizeSchemaParams(stepSchema, step.params, { source: input }) + : step.params; try { - next[step.key] = stepTool.runMask({ - params: step.params, - source: input, - }); + next[step.key] = stepTool.runMask({ params, source: input }); } catch { next[step.key] = null; }