Skip to content

fix(agents): durable no desktop hijack — gate Chrome CDP default off - #804

Merged
IgorGanapolsky merged 3 commits into
mainfrom
no-desktop-hijack-20260722
Jul 22, 2026
Merged

fix(agents): durable no desktop hijack — gate Chrome CDP default off#804
IgorGanapolsky merged 3 commits into
mainfrom
no-desktop-hijack-20260722

Conversation

@IgorGanapolsky

Copy link
Copy Markdown
Owner

Summary

  • Add AGENTS.md § No desktop hijack: never drive interactive Chrome, Computer Use, AppleScript Chrome, or daily-driver CDP unless Igor explicitly asks in that turn.
  • Gate hermes-chrome-cdp.sh, install scripts, prevention watchdog heal, and install-agent-launchagents.sh behind HERMES_ALLOW_INTERACTIVE_CHROME=1 (default off).
  • Add alwaysApply Cursor rules: .cursor/rules/no-desktop-hijack.mdc + prefer-headless rule; soften revenue/Apollo skill descriptions away from auto-Chrome.
  • Docs: docs/HEADLESS-BACKGROUND-OPS.md (host roles + task matrix), docs/NO-DESKTOP-HIJACK.md.
  • Daily driver: com.hermes.chrome-cdp unloaded; plist renamed to .disabled.

Test plan

  • bash tests/test-hermes-chrome-cdp.sh
  • node tests/test-hermes-prevention-watchdog.js
  • No Chrome launched during this task

Made with Cursor

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@IgorGanapolsky
IgorGanapolsky enabled auto-merge (squash) July 22, 2026 17:39
@gitar-bot

gitar-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a no-desktop-hijack rule for Hermes Mobile agent guidance. The main changes are:

  • Adds a standing order to avoid interactive Chrome, macOS focus stealing, and Computer Use unless explicitly requested.
  • Directs agents toward headless or API-based tools such as gh, Play/ASC APIs, Stripe CLI, adb, and SSH.
  • Keeps Chrome CDP LaunchAgents gated off by default with HERMES_ALLOW_INTERACTIVE_CHROME.

Confidence Score: 5/5

Safe to merge within the configured review scope.

The reviewable change is guidance-only and does not alter Hermes Mobile runtime behavior, connect/onboarding, Tailscale, auth probes, OTA, or key scoping.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Executed the chrome CDP no hijack validation using the generated helper script to capture the run.
  • Inspected the validation transcript in the log to verify the working directory, commands, stdout/stderr, and environment checks.
  • Confirmed the two key checks completed with exit code 0: bash tests/test-hermes-chrome-cdp.sh and node tests/test-hermes-prevention-watchdog.js.
  • Generated and captured the run_chrome_cdp_no_hijack_validation.sh helper script as an artifact for reproducibility.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
hermes-mobile/AGENTS.md Adds mobile agent guidance that prohibits desktop hijacking and keeps interactive Chrome CDP gated off by default.

Reviews (1): Last reviewed commit: "fix(agents): durable no desktop hijack —..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 54ffbcc080

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +105 to 110
if hermes_interactive_chrome_allowed; then
if [[ "$cdp_ipv4" -eq 1 && "$agent" -eq 1 ]]; then
ok=1
fi
else
ok=1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not report gated-off CDP as connected

When HERMES_ALLOW_INTERACTIVE_CHROME is unset, this branch makes --status and --apply --json exit 0 and print Bridge connected even when cdpIpv4=false and launchAgent=false; in this default state a health check can green-light a dead ws://127.0.0.1:9222 bridge instead of surfacing that browser control is gated off. Callers and install output use this command as verification, so the status should distinguish "gated off" from an actually connected CDP endpoint.

Useful? React with 👍 / 👎.

Comment on lines +16 to +18
repo_root_early="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck disable=SC1091
source "${repo_root_early}/scripts/hermes-interactive-chrome-gate.sh"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the curl installer from sourcing a local-only gate

For the advertised curl ... | bash install path, the script runs from stdin before any repo files have been fetched, so BASH_SOURCE[0] is unset/empty under set -u and the new source .../scripts/hermes-interactive-chrome-gate.sh fails before the existing fallback download block can run. This breaks even an explicitly opted-in remote install (HERMES_ALLOW_INTERACTIVE_CHROME=1 curl ... | bash) before it fetches the bridge scripts.

Useful? React with 👍 / 👎.

Comment on lines +31 to +47
const gateProbe = spawnSync(
'/bin/bash',
[
'-c',
`
set -euo pipefail
repo_root=${JSON.stringify(repoRoot)}
export HERMES_ALLOW_INTERACTIVE_CHROME=0
if [[ "\${HERMES_ALLOW_INTERACTIVE_CHROME:-0}" == "1" && -x "\${repo_root}/scripts/install-hermes-chrome-cdp.sh" ]]; then
echo INSTALLED
else
echo "SKIP com.hermes.chrome-cdp (HERMES_ALLOW_INTERACTIVE_CHROME!=1)"
fi
`,
],
{ encoding: 'utf8' },
);
@IgorGanapolsky
IgorGanapolsky force-pushed the no-desktop-hijack-20260722 branch 5 times, most recently from 1ed3764 to cec49e2 Compare July 22, 2026 19:39
IgorGanapolsky and others added 3 commits July 22, 2026 15:58
Igor's daily driver must stay usable: ban interactive Chrome/Computer Use unless
explicitly requested in that turn. Gate CDP scripts behind HERMES_ALLOW_INTERACTIVE_CHROME,
skip auto-install from install-agent-launchagents, add alwaysApply Cursor rules and
HEADLESS-BACKGROUND-OPS architecture doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ay check

Install-browser-bridge --help must work without HERMES_ALLOW_INTERACTIVE_CHROME
(macOS guard kit contract). Treat live free Play listing as warning, not hard
fail, when HTML shows a real app page (store drift vs 2026-07-22 unpublished docs).

Co-authored-by: Cursor <cursoragent@cursor.com>
Expand July 2026 headless ops doc, explicit Chrome opt-in phrases in the
alwaysApply rule, and regression test that install-agent-launchagents skips
com.hermes.chrome-cdp unless HERMES_ALLOW_INTERACTIVE_CHROME=1.

Co-authored-by: Cursor <cursoragent@cursor.com>
@IgorGanapolsky
IgorGanapolsky force-pushed the no-desktop-hijack-20260722 branch from cec49e2 to 71da382 Compare July 22, 2026 19:58
@IgorGanapolsky
IgorGanapolsky merged commit 2b91eaf into main Jul 22, 2026
12 checks passed
@IgorGanapolsky
IgorGanapolsky deleted the no-desktop-hijack-20260722 branch July 22, 2026 20:17
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.

2 participants