Skip to content

feat(preview): fill login forms from rbw without exposing the secret to agents #557

Closed

Description

@lukemaj

What: Agents can sign in to a site in a Chromeria browser tab with a credential from the user's Bitwarden vault (rbw), and the password and one-time code never pass through the agent's transcript or tool results.
Why: Today an agent can only type a password through preview_type, which writes it in plain text into the session log; the server browser refuses clipboard paste (NotAllowedError) and is driven over --remote-debugging-pipe, so no outside helper can fill the field either.
So what: A worker designs and builds a credential-fill preview tool; the planner reviews it and deploys it after the user approves the design.

Outcome

An agent driving a Chromeria browser tab reaches a login form and calls one tool that names a vault item and a field (for example item Shopify, field password or totp) plus the target input. Chromeria reads the value from rbw on the machine that owns the vault, types it into that input, and returns only success or a specific error. The value never appears in the agent's tool arguments, tool results, transcript, logs, traces or screenshots.

Problem Statement

Observed 2026-10-19 on cavallo while logging an agent into admin.shopify.com in the server browser (Default profile):

  • navigator.clipboard.readText() in the page returns NotAllowedError; Meta+V into the password input inserts nothing.
  • The headless browser runs with --remote-debugging-pipe, so a local script cannot attach over CDP.
  • The only working route, preview_type, puts the password into the tool call, which is stored in the agent session log.

The user wants agents to log in on their own with the vault entries on rocky (rbw get <item>, rbw code <item> for TOTP) when a session expires.

Solution

A preview tool that names a vault item and field instead of carrying the value. Chromeria resolves the value server-side from rbw (local, or on the vault machine over SSH), types it into the target input, and returns only success or a specific error.

#520 / PR #530 mirror the user's Chrome cookies into Chromeria, which covers sites where the user is already signed in on the Mac. This Issue covers what #520 deliberately excluded: passwords, and re-login when no human session exists (expired session, new machine, a site that signs out often). Both are needed.

Elon record

  • Requirements and who asked: user, 2026-10-19, amazonads thread: "we need a robust way for agents to log into Chromeria web pages using rbw, not this one-time patch"; agents may log in with the rocky vault on their own.
  • Deleted: clipboard paste and outside CDP helpers (both blocked, see Problem Statement); typing secrets through preview_type (leaks into logs); storing passwords in Chromeria.
  • Bottleneck: no preview tool can put a secret into a page without the agent seeing it.
  • Checked myself: ps of the server browser (--headless --remote-debugging-pipe, profile ~/.t3/userdata/server-browser/profiles/default); clipboard read NotAllowedError and empty paste on accounts.shopify.com; rbw get --full Shopify on rocky holds username, password and TOTP secret fields; spec: mirror Mac browser logins into Chromeria and out to bestia and Rocky #520 scope and PR feat(preview): mirror Mac Chrome logins to connected environments #530 comments.

Acceptance criteria

  • A preview tool (name to be designed, for example preview_fill_credential) takes a vault item reference, a field (username, password, totp) and a locator, and fills the input without returning the value.
  • The value is never present in tool arguments, tool results, renderer state, logs, traces, Issues or PRs; screenshots of password inputs stay masked.
  • Works when the vault lives on another machine (rbw on rocky over SSH) and when rbw is local.
  • Specific errors: vault locked, item missing, field missing, input not found; no silent fallback.
  • Each use is recorded (item name, site origin, time, thread) without the value, so the user can audit agent logins.

User stories

  1. As the user, I let agents log in to my sites with my vault entries, so I am not interrupted when a session expires.
  2. As an agent, I fill a password and a one-time code without ever seeing them, so the transcript stays clean.
  3. As the user, I can see which agent logged in where and when.

Implementation decisions

  • To be designed: tool name and arguments, where rbw runs (local versus the vault machine), per-environment vault configuration, and masking of password inputs in screenshots.

Design review

  • Independent review: pending; required before implementation.
  • User decisions: agents may log in with the rocky vault on their own (user, 2026-10-19).

Testing decisions

  • Prove at the preview tool seam: a test page with username, password and TOTP inputs; assert the inputs are filled and that no tool result, log line or trace contains the value. Live proof against admin.shopify.com.

Non-goals

Blockers

  • None.

Required proof

  • An agent logs into admin.shopify.com (password plus TOTP) in the server browser on cavallo, and a search of the session log and server logs for the password finds no match.

Contribution to the Objective

Lets agents keep working on the user's sites (Shopify, Amazon Seller Central, Canva) without the user re-entering passwords, removing a recurring human interruption.

Activity

  1. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: Design proposal for preview_fill_credential, checked against outside prior art; ready for the user's approval.
    Why: The Opus design review read the Chromeria code at c8b69c6; two researchers (GPT-6.1, Grok 4.7) compared Steel, Browser Use, Playwright MCP, 1Password, Bitwarden, Skyvern, Hyperbrowser and Operator.
    So what: After the user approves, a worker implements it on a branch with the tests below; the planner reviews and runs the live Shopify proof.

    Decision

    One server-browser operation. The agent passes item, field (username | password | totp) and a required locator; the result is { filled, item, field, origin } or PreviewCredentialError with a fixed reason (vaultNotConfigured, vaultUnavailable, vaultLocked, itemNotFound, itemAmbiguous, fieldMissing, originMismatch, insecureOrigin). The value never enters the broker request or response.

    Flow inside ServerBrowser: resolve the locator and its owning frame; https only; rbw unlocked; rbw get --field uris -- <item> and match the frame origin; fetch the value (rbw get --field … or rbw code); re-check the origin; fill; verify on the server; keep the value in memory on the tab only for redaction.

    This is the pattern Steel (origin-bound fill), Browser Use and Skyvern (placeholder resolved by the runner, TOTP minted in the runner) already ship. 1Password's agentic autofill adds a human approval per fill, which this Issue rules out; Bitwarden MCP and aac connect --output json return secrets to the caller and fail the requirement.

    User decisions (2026-10-19, amazonads thread)

    • The rbw vault is a service account with business logins only: no folder restriction; agents may use any item.
    • Vault location per environment lives in server settings, no Settings UI: cavallo and bestia ssh rocky /opt/homebrew/bin/rbw, rocky local, edna none.
    • Username and TOTP visible in a screenshot for the seconds before submit is acceptable; no pixel masking.

    Changes from research

    • Origin match: host equals the item's URI host, or is a subdomain of it on a dot boundary (Bitwarden's base-domain behavior), so shopify.com covers accounts.shopify.com and admin.shopify.com but not evilshopify.com or shopify.com.evil.com.
    • Redaction: mask the filled fields' values in snapshots by element, not by substring-replacing whole snapshot text (Playwright MCP #1106 shows that corrupts labels and refs); substring scrubbing of results stays only for the password value.
    • Read-back: preview_evaluate is refused on the tab after a fill until the next cross-document navigation; the submit request body is never captured.
    • Limits stated honestly: this keeps secrets out of tool results and logs and stops wrong-site fills. It does not stop an agent that has shell access from running rbw itself, nor from using the logged-in session afterwards.

    Security details kept from the design

    • New preview/CredentialVault.ts spawns rbw or ssh <target> <rbwPath> … itself, single-quotes every remote argument, puts -- before the item, validates the item name (strict charset, ≤128 chars, no leading -), and never logs stdout (the shared runSshCommand logs stdout on failure, so it is not used).
    • Refuses to run if DEBUG enables Playwright protocol logging.
    • Audit: one line per attempt in stateDir/credential-fills.jsonl (0600): time, environment, thread, project, provider, item, field, origin, tab, result. No value.

    Files

    packages/contracts/src/previewAutomation.ts, packages/contracts/src/settings.ts, apps/server/src/mcp/toolkits/preview/tools.ts, handlers.ts, new apps/server/src/preview/CredentialVault.ts, apps/server/src/preview/ServerBrowser.ts, ServerBrowserPage.ts, packages/shared/src/t3McpToolPresentation.ts, tests for each.

    Proof

    Unit tests for argument quoting and error mapping with a fake spawner; an origin matcher table; real headless Chromium with username, password, one-time-code and a cross-origin iframe, a fake vault returning sentinel values, asserting the sentinel is absent from every result, snapshot, console entry, network URL and action timeline, evaluate refused while armed, and wrong-origin fills refused after only the uris lookup; MCP CallToolResult contains no sentinel; live login to admin.shopify.com (password + TOTP) on cavallo with grep -cF of the session and server logs returning 0.

  2. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: Design simplification: Chromeria only ever runs a local rbw; the SSH hop to rocky lives in the machine wrapper.
    Why: The user asked for an rbw wrapper like the existing gog/himalaya ones; it is now installed on cavallo and bestia (runbook f9e0962, shared/scripts/rocky-tool), so rbw there runs rocky's rbw over SSH with every argument single-quoted for the remote shell.
    So what: The worker builds the design above with this change.

    • credentialVault becomes { kind: "none" } (default) or { kind: "local", rbwPath }. Planned: cavallo and bestia ~/.local/bin/rbw (the wrapper), rocky /opt/homebrew/bin/rbw, edna none.
    • Delete the ssh kind, target/port/identityFile, and Chromeria-side remote quoting. CredentialVault.ts spawns rbwPath directly with an argument array (no shell), still with -- before the item and the strict item-name check, and still never logs stdout.
    • Verified: rbw unlocked exits 0 and rbw get --list-fields Shopify lists username, totp, uris, password through the wrapper on cavallo and bestia. Wrapper exit 69 means rocky was unreachable; map it to vaultUnavailable.
  3. added a commit that references this issue on Oct 19, 2026
    3f1a127
  4. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: preview_fill_credential is implemented in PR #561 (head 2c716703aa), built to the approved design with the local-rbwPath simplification.
    Why: Agents need to sign in without the value passing through their transcript, results or logs.
    So what: The planner runs independent review and the live admin.shopify.com proof on cavallo; merging needs the user's approval.

    Handoff:

    • Branch feat/557-preview-fill-credential, rebased on origin/main e760e6af8b. Commits: 3f1a12741e (feature), 2c716703aa (registry PR link, docs only).
    • Proof on 3f1a12741e: focused suites 568 passed / 1 skipped across 23 files, including real headless Chromium sentinel tests, the fake-spawner vault tests and the MCP CallToolResult + audit test; typecheck clean for server, contracts, shared, web, mobile, desktop, client-runtime; lint clean; fork-features check and fork-check.sh OK. Commands and details are in the PR body.
    • Deviations: reasons protocolLogging and fillFailed added; tabId in the result and error; the DEBUG refusal also covers pw:api; the evaluate refusal uses PreviewAutomationExecutionError.
    • Not done: independent review, CI on the PR, live Shopify login. rbw get/rbw code were never run against the real vault.
    • To enable on a machine: set "credentialVault": {"kind": "local", "rbwPath": "<path>"} in that server's userdata/settings.json (cavallo and bestia ~/.local/bin/rbw, rocky /opt/homebrew/bin/rbw); this is a settings change I did not make.
  5. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: The five P1 findings from review round 1 on PR #561 are fixed on head 290cb2704d.
    Why: Round 1 (pullrequestreview-5578161274) reproduced leaks through screenshot pixels, encoded results, session state, username/TOTP echoes and a popup's opener.
    So what: The planner runs independent review round 2 on 290cb2704d, then the live admin.shopify.com proof; merging needs the user's approval.

    Handoff:

    • Branch feat/557-preview-fill-credential, 0 behind origin/main at push. Commits: 3f1a12741e feature, 2c716703aa registry link, 290cb2704d review fixes.
    • Per finding:
      1. Snapshots of every tab in an armed opener group return a 1x1 placeholder PNG; recording can't start there, and a fill is refused while one runs.
      2. All three values are scrubbed from results, error messages and error details, in raw/URL/form/lowercase-hex/JSON/HTML forms, keys included; only the snapshot's screenshot.data is exempt.
      3. Navigation status and popup URLs are scrubbed before Manager session state and events.
      4. Console/network/text echoes of username and code are scrubbed, and element masking covers an input's current (edited) value.
      5. Evaluate is refused across the opener group.
    • Proof on 290cb2704d: PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers pnpm exec vp test run apps/server/src/preview apps/server/src/mcp/toolkits/preview apps/server/src/mcp/McpHttpServer.test.ts apps/server/src/mcp/PreviewAutomationBroker.test.ts apps/server/src/serverSettings.test.ts packages/contracts/src/settings.test.ts packages/shared/src/t3McpToolPresentation.test.ts: 22 files passed, 1 skipped; 524 tests passed, 1 skipped. Typecheck (apps/server, packages/contracts, packages/shared) and lint clean; fork-features check and fork-check.sh OK. The new server-level regression fails with the session scrub reverted and with the guard narrowed to one tab.
    • Remaining boundaries, stated in the PR:
      • a download exporting a filled value;
      • collateral masking of short values in other threads' results;
      • partial codes echoed outside the input;
      • the human live view;
      • split one-digit code inputs.
    • Not done: review round 2, CI, the live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  6. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: The four findings from review round 2 on PR #561 are fixed on head 100cc53e40.
    Why: Round 2 (pullrequestreview-5578341412) showed the password survived a GET navigation, a racing popup recording and mixed encodings, and that global scrubbing broke other threads' responses.
    So what: The planner runs independent review round 3 on 100cc53e40, then the live admin.shopify.com proof; merging needs the user's approval.

    Handoff:

    • Branch feat/557-preview-fill-credential, 0 behind origin/main at push. Round-2 fix commit: 100cc53e40.
    • Per finding:
      1. Protection lasts until every tab in the opener group has loaded a document since the fill whose URL and title hold no filled value.
      2. A fill and a recording start each claim their tab before their first await and exclude each other across the group.
      3. Normalize-then-match scrubbing (URL in any case, +, HTML named and numeric entities, JSON escapes, two layers), with whole-line replacement.
      4. Scrubbing covers only the thread that holds the values and keeps trusted field names; values and the group's stored entries are released once it is clean.
    • Proof on 100cc53e40: PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers pnpm exec vp test run apps/server/src/preview apps/server/src/mcp/toolkits/preview apps/server/src/mcp/McpHttpServer.test.ts apps/server/src/mcp/PreviewAutomationBroker.test.ts apps/server/src/serverSettings.test.ts packages/contracts/src/settings.test.ts packages/shared/src/t3McpToolPresentation.test.ts: 22 files passed, 1 skipped; 539 tests passed, 1 skipped.
      • The first run had one failure in serverSettings.test.ts (an untouched file-watch test); it passed 3 of 3 alone and in the rerun.
      • Typecheck (apps/server, packages/contracts, packages/shared), lint and git diff --check clean; fork checks OK.
      • Mutations that disarm on any navigation, drop the fill/recording claims, or scrub all threads each fail a new test.
    • Remaining boundaries, stated in the PR: lazy release of values, whole-line redaction, transforms beyond two decode layers, downloads, partial codes outside the input, the human live view, split code inputs.
    • Not done: review round 3, CI, a real-browser recording decode, the live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  7. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: Planner redesign after three review rounds: replace scrubbing with a login quarantine.
    Why: Each round closed the reported leaks and the next round found new ones in the same machinery (lazy release, release races, group splits, entity tables); the bottleneck is the attempt to let agents keep reading a page that holds a secret, not any single bug.
    So what: The worker rebuilds PR #561 on this model; the reviewer then reviews the quarantine instead of the scrubber.

    Elon record

    • Requirements and who asked: user (feat(preview): fill login forms from rbw without exposing the secret to agents #557): an agent logs in with rbw values and never sees them; agents may log in unattended. Nothing in the requirement says the agent must read the login page while secrets are in it.
    • Deleted: result scrubbing, decode-then-match, encoding tables, lazy release, clean-document detection, group value transfer on close, the grey-image substitution logic beyond quarantine.
    • Bottleneck: read paths on a page that holds a filled secret.
    • Checked myself: the three review bodies (5578161274, 5578341412, 5578524056); every P1 so far is a read path or a release transition.

    Quarantine model

    • A successful preview_fill_credential quarantines the tab's whole opener group, including popups opened later from it.
    • In quarantine, every read is refused with one fixed error: snapshot (text and image), evaluate, recording, console, network, action timeline, downloads, page text. Renderer-facing session state and events show the tabs as "Login in progress", with no URL or title.
    • Allowed in quarantine: further preview_fill_credential calls, click/press/type by locator (results carry no page content), preview_wait_for returning only matched or timed out, and a new preview_end_login tool.
    • preview_end_login closes every tab in the group. The agent continues in a fresh tab; the profile's cookies keep the session. Quarantine also ends if the user closes the tabs. There is no other exit.
    • Values never leave the fill call: they are typed and dropped, never stored for redaction.
    • Unchanged: origin binding, https only, rbw handling, audit line, settings.
  8. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: PR #561 now implements the login quarantine from the planner's redesign, on head 836ba184cc (one squashed commit on 1e83a3169f).
    Why: Review round 3 (pullrequestreview-5578524056) found four more P1 leaks and two P2 failures in the scrubbing machinery; the redesign removes read access instead.
    So what: The planner runs independent review of the quarantine on 836ba184cc, then the live admin.shopify.com proof; merging needs the user's approval.

    Handoff:

    • Branch. feat/557-preview-fill-credential was squashed to one commit and rebased on main 1e83a3169f. Conflicts with feat(research): share page reads and web search across environments #560 were resolved: readPage is kept and refused in a login, and previewAutomation.ts is now owned by feat(research): opt-in logged-in web_read without enforced pacing #446 and shared by this feature. Force-pushed with lease from 3c1020d7f1.
    • Behavior.
      • A fill marks the tab's opener group, and later popups, with one login id before the vault read.
      • Every read operation is refused with PreviewCredentialError loginInProgress; status and session state show Login in progress without URL or title.
      • Allowed: more fills, click by locator or selector, press, type, wait_for, and dialog (redacted status).
      • preview_end_login closes the login's tabs.
      • Values are typed and dropped. Scrubbing, decoding, lazy release, clean-document detection and value transfer are deleted.
    • Proof on 836ba184cc.
      • PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers pnpm exec vp test run apps/server/src/preview apps/server/src/mcp/toolkits/preview apps/server/src/mcp/McpHttpServer.test.ts apps/server/src/mcp/PreviewAutomationBroker.test.ts apps/server/src/serverSettings.test.ts packages/contracts/src/settings.test.ts packages/shared/src/t3McpToolPresentation.test.ts: 22 files passed, 1 skipped; 525 tests passed, 1 skipped.
      • Typecheck (apps/server, packages/contracts, packages/shared, apps/web, apps/mobile) clean; lint clean; pnpm run knip:check exit 0; fork checks and git diff --check OK.
      • Four mutations (popups not joining, filled tab only, no read guard, session state not hidden) each fail a test.
      • Before the rebase, one run showed the known serverSettings.test.ts file-watch flake; it passed 3 of 3 alone and in the reruns.
    • Remaining limits (stated in the PR): wait_for/locator content oracles, the human live view, incognito sessions ending with their tabs, downloads on disk until close, split code inputs.
    • Not done: review of this head, CI on it, the live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  9. added 2 commits that reference this issue on Oct 19, 2026
    eb8b035
    c74169f
  10. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: The five round-4 findings on PR #561 are fixed through three invariants on head c74169f59d (rebased on main 5898397a65).
    Why: Round 4 (pullrequestreview-5578803129) showed the quarantine could be lost across popup attachment, failed follow-up fills and desktop reconnects, read by an in-flight status, or leaked through the fill's live origin.
    So what: The planner runs independent review of c74169f59d and the live admin.shopify.com proof; CI has started on this head; merging needs the user's approval.

    Handoff:

    • Branch. feat/557-preview-fill-credential, two commits on 5898397a65: eb8b035129 (feature) and c74169f59d (round-4 invariants). Force-pushed with lease from 836ba184cc after the rebase. The fix(desktop): Chrome login mirror no longer blocks startup #545 conflict in scripts/fork-upstream-edits.txt was resolved by keeping both blocks.
    • Invariants.
      • A: logins are keyed by preview session and CDP target, never downgrade, and end only with preview_end_login or session close. Popups inherit when the browser reports them.
      • B: every result is checked again at the response boundary.
      • C: fill results and audit name the matched vault host (site), and refusals carry no origin once the group holds a value.
    • Proof on c74169f59d.
      • PLAYWRIGHT_BROWSERS_PATH=/tmp/pw-browsers pnpm exec vp test run apps/server/src/preview apps/server/src/mcp/toolkits/preview apps/server/src/mcp/McpHttpServer.test.ts apps/server/src/mcp/PreviewAutomationBroker.test.ts apps/server/src/serverSettings.test.ts packages/contracts/src/settings.test.ts packages/shared/src/t3McpToolPresentation.test.ts: 23 files passed, 1 skipped; 533 tests passed, 1 skipped.
      • That includes CredentialLogin.integration.test.ts: the reviewer's five probes as real-Chromium regressions, plus a three-step sign-in. Each regression fails when its fix is mutated away.
      • Typecheck (apps/server, packages/contracts, packages/shared, apps/web, apps/mobile), lint, pnpm run knip:check (exit 0), fork checks and git diff --check clean.
    • CI. CI, Fork and Mobile Fingerprint Check in progress on c74169f59d at handoff.
    • Remaining limits (stated in the PR): wait_for/locator oracles, the human live view, incognito sessions, downloads on disk until close, split code inputs, desktop reconnect proven with a simulated boundary.
    • Not done: review of this head, the live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  11. lukemaj commented on Oct 19, 2026

    @lukemaj
    ContributorAuthor

    What: PR #561's round-5 findings are fixed on head 40c519b3ad by deleting the racing mechanisms, and CI is green on that head.
    Why: Round 5 (pullrequestreview-5578999598) found races in fill rollback, popup inheritance and refusal origins, and CI couldn't launch Chromium under Ubuntu AppArmor.
    So what: The planner runs independent review of 40c519b3ad, then the live admin.shopify.com proof; merging needs the user's approval.

    Handoff:

    • Branch. feat/557-preview-fill-credential, three commits on 5898397a65; the round-5 fix is 40c519b3ad.
    • Changes.
      • No rollback: a login starts with the fill and only preview_end_login or session close ends it.
      • New tabs are decided at publication: any login in their browser context applies.
      • Refusals and audit carry no page data; the audit keeps time, environment, thread, item, field, matched vault host and result.
      • The real-Chromium tests use T3CODE_SERVER_BROWSER_SANDBOX=0, like the repo's other real-browser tests, which launch unsandboxed.
    • Proof.
      • Local focused suites: 23 files passed, 1 skipped; 536 tests passed, 1 skipped (after the known settings flake passed on rerun).
      • Typecheck in five packages, lint, pnpm run knip:check and fork checks clean.
      • CI run 39343258453 green, with Check and all 8 server shards; Test Server 1 ran the 11 real-Chromium tests.
      • Label PR size passed on re-run after a GitHub API error.
      • The new regressions fail when the rollback or the publication-time context check is restored or removed.
    • New consequence. While a login lasts, new tabs anywhere in that browser profile start locked (stated in the PR).
    • Not done. Review of this head, the live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  12. lukemaj commented on Oct 20, 2026

    @lukemaj
    ContributorAuthor

    What: PR #561's round-6 findings are fixed on head 9131aa6639 with a server-browser-only, profile-level login that drains on end, and CI is green on that head.
    Why: Round 6 (pullrequestreview-5579139789) found leaks through popups still attaching at end-login, desktop context wrappers, and popup URLs published before locking.
    So what: A round-7 review has already posted review/independent=failure on 9131aa6639; the planner decides the next round. The live Shopify proof and merge approval remain.

    Handoff:

    • Branch. feat/557-preview-fill-credential, four commits on 5898397a65; the round-6 fix is 9131aa6639.
    • Changes.
      • Fills refuse on desktop-hosted tabs (serverBrowserOnly).
      • Logins are keyed by profile id: every tab in the profile, existing, new or attaching, is locked, and existing session state is republished redacted.
      • preview_end_login marks the profile ending, closes its tabs and any that finish attaching, and lifts only when no tabs or attaching popups remain.
      • User guide states the profile-wide pause.
    • Proof.
      • Local focused suites: 23 files passed, 1 skipped; 538 tests passed, 1 skipped (after the known settings flake, which passed alone and on rerun).
      • Typecheck in five packages, lint, pnpm run knip:check and fork checks clean.
      • CI run 39345636110 all green; Test Server 1 ran the 13 real-Chromium tests, all passed.
      • Each round-6 regression fails when its guard is removed.
    • Not done. Round-7 findings (posted after this push), the live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  13. lukemaj commented on Oct 20, 2026

    @lukemaj
    ContributorAuthor

    What: PR #561's round-7 finding is fixed on head f2613fbe88. CI is green, and independent review round 8 passed on that exact head.
    Why: Round 7 (pullrequestreview-5579292619) showed the login could lift while pages were still closing or tabs still attaching. Ending a login now closes the profile's browser context and lifts only after that close resolves.
    So what: The planner runs the live admin.shopify.com proof on cavallo; then the user decides the merge.

    Handoff:

    • Branch. feat/557-preview-fill-credential, five commits on 5898397a65; the round-7 fix is f2613fbe88.
    • Changes.
      • preview_end_login closes the profile's context through ServerBrowserContexts.closeContext, which waits; new tab requests wait for the close and get a fresh context from the same directory.
      • The popup attach holds and drain counting are deleted.
      • User guide updated.
    • Proof.
      • Local focused suites: 23 files passed, 1 skipped; 540 tests passed, 1 skipped.
      • Typecheck in five packages, lint, pnpm run knip:check and fork checks clean.
      • CI run 39347782218 all green; Test Server 1 ran the 15 real-Chromium tests, all passed.
      • review/independent=success (round 8).
      • Round-7 regressions fail when the close is not awaited or only pages are closed.
    • Live proof note. Cookies without an expiry do not survive preview_end_login, so the Shopify proof should check whether its admin session persists into the fresh tab.
    • Not done. The live Shopify login. No real rbw get/rbw code, no settings change, no merge.
  14. added a commit that references this issue on Oct 29, 2026
    016a99d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions