Skip to content

fix(hooks): restrict MultiEdit AI-reviewed marker source - #339

Open
atomicdjt wants to merge 1 commit into
griddynamics:mainfrom
atomicdjt:fix/210-multiedit-review-marker-boundary
Open

fix(hooks): restrict MultiEdit AI-reviewed marker source#339
atomicdjt wants to merge 1 commit into
griddynamics:mainfrom
atomicdjt:fix/210-multiedit-review-marker-boundary

Conversation

@atomicdjt

@atomicdjt atomicdjt commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Problem

Edit accepts the Rosetta-AI-reviewed override marker only from new_string, but MultiEdit previously scanned every property of each edits[] object. A marker in old_string or another property could therefore satisfy the reconsider-deny override without appearing in content being written.

Root cause

hasAIReviewedMarker used Object.values(item) for object entries in array-valued marker fields. MARKER_FIELDS_BY_TOOL identifies MultiEdit.edits as the relevant top-level field, but the nested traversal did not enforce the same write-field boundary as plain Edit.

Fix

For MultiEdit, marker detection now checks only each edit item's string new_string. The existing behavior for plain Edit, MCP marker fields, and other array-shaped inputs is unchanged.

This is a focused defense-in-depth correctness fix; it does not change the marker string or redesign dangerous-action policy.

Regression coverage

  • marker only in MultiEdit.edits[].old_string remains denied;
  • marker only in an unrelated edit property remains denied;
  • marker in one MultiEdit.edits[].new_string remains accepted;
  • existing plain Edit positive and old-string negative cases remain green;
  • existing dangerous-actions coverage remains green.

Verification

  • npx tsc — passed;
  • npx vitest run tests/dangerous-actions.test.ts — 198 passed;
  • npx vitest run tests/regression/bundle-isolation.test.ts after bundle build — 193 passed;
  • full hooks Vitest suite — 1,403 passed, 40 failures;
  • a clean untouched worktree at the same upstream SHA reproduced the same 40 failures, all in existing Windows path/async assumptions outside this change;
  • npm run check — passed;
  • git diff --check — passed;
  • bundle build stages (tsc plus build-bundles.mjs) — passed;
  • the repository's build:quiet and pre-commit wrapper cannot complete on this Windows host because their Unix rm command is not available; the TypeScript and bundle stages succeeded directly.

Fixes #210

Codex assisted with repository analysis, implementation, regression tests, and validation. I directed the scope and reviewed the final diff and PR text.

Signed-off-by: David Turner <davidelsey9513@gmail.com>
@github-actions github-actions Bot added bug Something isn't working security labels Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Rosetta Triage Review

Summary: Fixes a security bypass in the dangerous-actions hook — hasAIReviewedMarker for MultiEdit scanned every field of each edits[] item (including old_string), so the Rosetta-AI-reviewed override marker could be planted in a field that isn't the actual write content, silently defeating the same protection that plain Edit already enforces (marker restricted to new_string). The fix narrows MultiEdit marker detection to each item's new_string only, matching evalMultiEdit's own scan boundary and closing issue #210 exactly as described.

Findings:

  • Root cause is accurately diagnosed and the fix is minimal and correctly scoped: only the MultiEdit branch of hasAIReviewedMarker changes; Edit, Bash, Write, and MCP marker paths are untouched.
  • Fix aligns marker-detection with the pre-existing danger-scanning logic in evalMultiEdit (src/hooks/src/hooks/dangerous-actions/evaluate.ts:198-209), which already only reads new_string — so detection and override are now symmetric.
  • New tests cover both bypass vectors from the issue (marker in old_string, marker in an unrelated edit property) and assert continued denial; existing positive/negative Edit and MultiEdit cases are preserved.
  • CI (build-test, CodeQL, lint/analyze) is green on this PR.

Caveats:

  • PR description reports 40 pre-existing Vitest failures reproduced on a clean untouched worktree (attributed to Windows path/async assumptions), unrelated to this change — consistent with a focused fix, but worth confirming CI's own Linux run doesn't hit the same count for a different reason.

Automated triage by Rosetta agent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ROSETTA] MultiEdit AI-reviewed marker check scans old_string too

1 participant