Skip to content

feat(desktop): add guarded browser click execution (Phase 2F-A2)#9

Closed
gu87 wants to merge 1 commit into
upstream-main-cleanfrom
codex/desktop-browser-click-exec-phase2f-a2
Closed

feat(desktop): add guarded browser click execution (Phase 2F-A2)#9
gu87 wants to merge 1 commit into
upstream-main-cleanfrom
codex/desktop-browser-click-exec-phase2f-a2

Conversation

@gu87

@gu87 gu87 commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Summary

Adds safe browser click execution for the desktop runtime. click moves from non-executable (AWAITING_SAFETY_ACTIONS) to executable (EXECUTABLE_ACTIONS) — but only after full user approval AND main-process re-verification with semantic safety guards.

What Changed

  • Deterministic element enumeration: getInteractiveEnumerationScript() — a fixed script that enumerates interactive elements in DOM order, assigning stable @eN refs. Shared by verify-action-target and execute-click.
  • New IPC: hermes:browser:get-interactive-snapshot (read-only element list).
  • New IPC: hermes:browser:execute-click with re-verification and semantic guards.
  • Semantic safety guards: click execution is rejected for:
    • submit_button, reset_button, file_input, password_input, external_link (by semanticRole)
    • Destructive labels (delete, remove, destroy, discard, clear all, reset all)
  • Re-verification before click: targetRef validation, deterministic re-enumeration, URL match, fingerprint match, visibility, disabled checks.
  • Execution method: Electron wc.sendInputEvent (native mouseDown/mouseUp) — no dispatchEvent, no JS injection, isTrusted: true.
  • action-gateway-ui: click executor now calls executeDesktopClick() → real execution path.

Safety Boundary

Action Phase 2F-A Phase 2F-A2
click ⚠️ Verification only, executor fails ✅ Executable after approval + guards
type ⚠️ Verification only, executor fails ⚠️ Unchanged — still non-executable
eval, press_key, scroll ❌ Permanently blocked ❌ Unchanged
navigate ✅ User-approved ✅ Unchanged

Guard Coverage

Target Status
button[type="submit"] / input[type="submit"] ❌ Blocked
button[type="reset"] / input[type="reset"] ❌ Blocked
input[type="file"] ❌ Blocked
input[type="password"] ❌ Blocked
a[href^="http"] (external links) ❌ Blocked
Destructive labels (delete/remove/destroy/discard/clear/reset) ❌ Blocked
Regular button, input[type="text"], internal a[href="#"] ✅ Allowed

Validation

  • npm run type-check: PASS
  • npx eslint (scoped): 0 errors
  • npx vitest --environment jsdom src/app/browser-runtime/: 174/174 PASS (+8 semantic guard tests)
  • npm run test:desktop:platforms: 79/79 PASS

Scope

  • Desktop Electron app + browser runtime only.
  • No backend/executor/Kanban/web dashboard changes.

🤖 Generated with Claude Code

- Move click from AWAITING_SAFETY_ACTIONS to EXECUTABLE_ACTIONS.
- Add getInteractiveEnumerationScript(): deterministic @en candidate
  enumeration shared by verify-action-target and execute-click.
- Add executeClick IPC handler with semantic safety guards:
  - Rejects submit_button, reset_button, file_input, password_input,
    external_link by semanticRole.
  - Rejects destructive labels (delete/remove/destroy/discard/clear all).
  - Re-verifies: targetRef, URL, fingerprint, visible, not disabled.
  - Executes via Electron wc.sendInputEvent (native mouseDown/mouseUp).
- Add getInteractiveSnapshot IPC (read-only element enumeration).
- Add buildSafetyContextFromElement() helper in desktop-visible-provider.
- Add executeDesktopClick() function with pre-execution bridge checks.
- Keep type non-executable (still AWAITING_SAFETY, returns failed).
- Keep eval/press_key/scroll permanently denied.
- No agent-provided JS execution — all scripts are fixed strings.
- sendInputEvent is the only mutation path.

174 browser-runtime tests pass. 79 platform tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gu87

gu87 commented Jun 7, 2026

Copy link
Copy Markdown
Owner Author

Closing for now. Real click execution crosses the safety boundary and will return after a dedicated design review.

@gu87 gu87 closed this Jun 7, 2026
@gu87 gu87 deleted the codex/desktop-browser-click-exec-phase2f-a2 branch June 7, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant