From 6ed1c643e7b8ad0836031b728d4af0f590dde031 Mon Sep 17 00:00:00 2001 From: seto Date: Mon, 13 Apr 2026 15:37:39 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20MultiEdit=20gate=20bypass=20=E2=80=94=20?= =?UTF-8?q?handle=20edits[].file=5Fpath=20correctly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P1 bug reported by greptile-apps: MultiEdit uses toolInput.edits[].file_path, not toolInput.file_path. The gate was silently allowing all MultiEdit calls. Fix: separate MultiEdit into its own branch that iterates edits array and gates on the first unchecked file_path. 9/9 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/hooks/gateguard-fact-force.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/scripts/hooks/gateguard-fact-force.js b/scripts/hooks/gateguard-fact-force.js index 4126c545..4bbde83e 100644 --- a/scripts/hooks/gateguard-fact-force.js +++ b/scripts/hooks/gateguard-fact-force.js @@ -192,7 +192,7 @@ function run(rawInput) { const toolName = data.tool_name || ''; const toolInput = data.tool_input || {}; - if (toolName === 'Edit' || toolName === 'MultiEdit' || toolName === 'Write') { + if (toolName === 'Edit' || toolName === 'Write') { const filePath = toolInput.file_path || ''; if (!filePath) { return rawInput; // allow @@ -200,14 +200,24 @@ function run(rawInput) { if (!isChecked(filePath)) { markChecked(filePath); - const msg = (toolName === 'Edit' || toolName === 'MultiEdit') - ? editGateMsg(filePath) : writeGateMsg(filePath); - return denyResult(msg); + return denyResult(toolName === 'Edit' ? editGateMsg(filePath) : writeGateMsg(filePath)); } return rawInput; // allow } + if (toolName === 'MultiEdit') { + const edits = toolInput.edits || []; + for (const edit of edits) { + const filePath = edit.file_path || ''; + if (filePath && !isChecked(filePath)) { + markChecked(filePath); + return denyResult(editGateMsg(filePath)); + } + } + return rawInput; // allow + } + if (toolName === 'Bash') { const command = toolInput.command || '';