fix what the review found: signals, identity, the profile the wrapper nearly used

Ten findings from a review of the first commit. The ones that bite in normal use:

An unchecked mktemp left EPHEMERAL empty, which becomes `--user-data-dir=` — and Chrome reads that as
"use the default profile", i.e. the browser the user actually signs into. `set -u` does not catch it,
because the variable is set, just empty. Now checked and refused. That branch also never exec'd and
had no way to reach the browser with a signal; it now backgrounds, records the pid, and traps.

Signal handlers registered AFTER a build that takes minutes, so a pm2 restart during a first start
killed this process and left cargo compiling as an orphan — then started a second one on the same
target directory. Handlers now register first and shutdown kills the build.

`which('iris')` treated presence as identity. A truncated binary from an interrupted install is
present, reports ready, and never rebuilds. It now runs `--version` and checks — the same lesson
os-deps.ts already learned as `identify`.

Cookies were copied without Cookies-wal. These are WAL databases, so the newest session may exist
only in the log — copy the .db alone and the capture is signed out for exactly the account that just
signed in. PLUGIN.md had this backwards, citing WAL as the reason it was safe; corrected there too.

Also: --password-store=basic was missing from the branch that actually runs, working only because
chromiumoxide's DEFAULT_ARGS happens to supply it; seeding failures were silent, so the skill's
"sign in again" advice was offered for an unreadable profile it cannot fix; only --user-data-dir=X was
detected and not the space-separated form; installWrapper was unguarded at top level and crash-looped
on an unwritable ~/.local/bin; and it truncated the wrapper in place rather than renaming over it.

The searchPath copy is gone — the platform now exports locateBinary and this asks it. That copy is
what made the manifest probe refuse a rustup-only machine the sidecar could build on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 00:04:34 +00:00
co-authored by Claude Opus 5
parent f0c811d387
commit 083e1f1f3b
3 changed files with 152 additions and 31 deletions
+7 -2
View File
@@ -57,7 +57,12 @@ This contract predates the desktop plugin. When that plugin lands, this path is
3. **Members.** The wrapper isolates per-user by `$HOME`, but the binary lands in the *owner's*
`~/.local/bin`, and a confined member's agent cannot read it there. If members should capture,
the binary needs a shared home. Deferred until the desktop plugin defines the member story.
4. **Cookie copy under a live browser.** Copying a SQLite file mid-write can catch a torn state; in
practice the cookie DB is WAL and short-lived reads are fine, but "in practice" is not verified.
4. **Cookie copy under a live browser.** Copying a SQLite file mid-write can catch a torn state. Being
WAL does not make this safe — it is what makes the copy INCOMPLETE, because a recent write may live
only in `Cookies-wal` until the browser checkpoints it. This originally read "the cookie DB is WAL and
short-lived reads are fine", which had the reasoning backwards: the wrapper copied `Cookies` alone, so
a session created moments earlier was the one guaranteed to be missing. `-wal` is now copied alongside
each database (`-shm` deliberately is not — it is live shared memory, rebuilt on open). A torn read of
the pair is still possible under a live browser and is still unverified.
5. **`permissions: []`** is honest today (nothing platform-gated to protect) but means the owner cannot
dock-gate or role-gate the plugin's existence. Revisit if an api/ or web/ arrives.