Skip to content

fix(browser): real-profile snapshot names the locked auth databases; docs stop promising live copy on macOS/Linux (#111647) - #113080

Merged
teknium1 merged 2 commits into
mainfrom
fix/b113-terminal-sandbox-security-macos-profile
Sep 16, 2026
Merged

teknium1 merged 2 commits into
mainfrom
fix/b113-terminal-sandbox-security-macos-profile

Conversation

@teknium1

@teknium1 teknium1 commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Real-profile browsing on macOS/Linux now tells you WHICH auth databases a running Chrome is holding and why, and the docs stop promising that the profile can be copied live while the browser runs.

  • hermes_cli/browser_connect.py::_copy_auth_file returns the failure reason (None on success); the backup deadline is the named constant _AUTH_BACKUP_DEADLINE_S and raises _AUTH_DB_LOCKED, so a lock is distinguishable from an unreadable file.
  • _mirror_profile_auth returns {db name: reason}; new _unavailable_auth_dbs_error renders the lock wording when every failure is the deadline, otherwise the per-database SQLite error. Still fails closed; no raw-copy fallback added (the WAL-consistency stance from 58d6d52 is unchanged — see design question below).
  • Docs website/docs/user-guide/features/browser.md Real-profile note: replaces "macOS and Linux can usually copy the profile while the browser is running" with what actually happens (Cookies usually snapshots live; Login Data / Login Data For Account / Web Data need the browser quit) and quotes the new error. real_profile_autoclose is documented as the Windows profile-lock flow. config_defaults.py comment corrected likewise.
  • Sibling surfaces: tools/browser_tool_real_profile.py::_real_profile_snapshot_error renders this string verbatim (prefix browser.use_real_profile is on, but …) for Desktop/CLI/gateway; no other surface embeds the old count text (grep 'database(s) unavailable' across hermes_cli/, tools/, apps/desktop/, ui-tui/ → 0 hits after the change).

Validation

Live probe (snapshot_real_profile against a temp profile under a temp HERMES_HOME, exclusive writers held in-process on the three login/autofill DBs, Cookies free):

before (origin/main): could not read the 'chrome' profile's login data (3 database(s) unavailable). Close chrome and retry, or turn browser.use_real_profile off. — 16.4 s, Cookies copied, control after releasing locks → snapshot succeeds

after: chrome is running and holds the profile's Login Data, Login Data For Account, Web Data with a write lock, so their SQLite backup made no progress within five seconds. Hermes does not fall back to a raw file copy (it could lose committed logins). Fully quit chrome (including any background instance) and retry, or turn browser.use_real_profile off. — Cookies copied, control after release → succeeds

Tests: tests/hermes_cli/test_browser_connect_real_profile_snapshot_errors.py (2 invariants, 3 cases; red on base), plus tests/tools/test_browser_real_profile.py, tests/tools/test_browser_real_profile_pin.py, tests/hermes_cli/test_cli_browser_connect.py → 103 passed.

Root cause: _mirror_profile_auth only counted failures, and the docs described the Windows fast-lock probe (which never trips on POSIX) as "POSIX copies live", while the POSIX failure mode is the SQLite backup deadline on the login/autofill DBs.

Open design question (not decided here)

Whether to add a POSIX file-level copy fallback for the three locked DBs (as #96659 and #111670 propose) so macOS/Linux truly copy live. This PR keeps the no-fallback stance and makes the behaviour and docs truthful; the fallback remains a maintainer call.

Fixes #111647

Infographic

macos-profile

Review follow-up

  • [MINOR] hermes_cli/browser_connect.py::_copy_auth_file deadline callback raised the lock-worded _AUTH_DB_LOCKED on any backup unfinished by the deadline (a large/slow-disk DB still progressing was told "a running browser holds a write lock", and the all-locked message said to quit the browser) → fixed @8705458638bf698c80fa6005ed96e9c185afe2ed: remaining is tracked between progress callbacks; only a backup whose remaining did not decrease gets the lock wording, otherwise a plain "SQLite backup exceeded Ns while still making progress" reason falls to the details branch. Invariant test test_copy_auth_file_slow_but_progressing_backup_is_not_called_locked (red without the fix). tests/tools/test_browser_real_profile.py green.

…nd the reason

On macOS/Linux a running Chrome lets `Cookies` back up but holds `Login Data`,
`Login Data For Account` and `Web Data` with a hot write lock, so their SQLite
online backup misses the five-second deadline. The launch failed closed with a
bare "3 database(s) unavailable" count, and the docs still promised that macOS
and Linux "can copy the profile while the browser is running" (#111647).

- `_copy_auth_file` returns the failure reason (None on success) instead of a
  bool; the backup deadline is the named constant `_AUTH_BACKUP_DEADLINE_S` and
  raises `_AUTH_DB_LOCKED`, so the caller can tell "browser holds a write lock"
  from "file is not a database".
- `_mirror_profile_auth` returns `{db name: reason}`; the new
  `_unavailable_auth_dbs_error` renders "chrome is running and holds the
  profile's Login Data, Login Data For Account, Web Data with a write lock …
  Fully quit chrome and retry" when every failure is the deadline, and the
  per-database SQLite error otherwise. No raw-copy fallback is added: the
  no-fallback stance from 58d6d52 (WAL consistency) is unchanged.
- Docs: the Real-profile note no longer says macOS/Linux copy live; it states
  which databases need the browser quit and what the error looks like. The
  `real_profile_autoclose` comment stops claiming copy-while-running works on
  POSIX.
@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 8705458 — fix: only call an auth DB backup "locked" when it made no pr

all good!

The backup deadline callback raised _AUTH_DB_LOCKED on ANY backup that had
not finished by the deadline, so a large auth DB on a slow disk that was
still copying pages got the "a running browser holds a write lock" wording,
and the all-locked message told the user to quit the browser for a cause
that was not a lock. Track `remaining` between progress callbacks: a held
write lock fails every step with `remaining` unchanged, while real progress
shrinks it. Only the former keeps the lock wording; the latter reports a
plain "backup exceeded Ns" reason that falls to the details branch.

Review follow-up on #113080.
@teknium1
teknium1 merged commit 713a937 into main Sep 16, 2026
34 checks passed
@teknium1
teknium1 deleted the fix/b113-terminal-sandbox-security-macos-profile branch September 16, 2026 23:53
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.

macOS: real-profile snapshot fails with 3 databases unavailable while Chrome is running, contrary to docs

1 participant