Skip to content

handle multi-profile session persistence and anti-dormancy #2

Description

@diegohb

Migrate establishing authentication and persisting it - avoiding phantom auth and dormancy bugs experienced in gemiterm.

ref: https://github.com/teng-lin/notebooklm-py/blob/main/docs/auth-cookie-lifecycle.md

Pivotal aspect of the solution:

Nothing in gemiterm's code was changed — the fix was a three-step browser-backed rotation, executed entirely outside the CLI:

1. Launched headless Chromium against the profile's persistent user-data directory

bunx @playwright/cli -s=zeekl3 open --browser=chromium --persistent \
  --profile=<abs>\.gemiterm\profiles\dhb-zeek https://gemini.google.com/app

This is the key detail: dhb-zeek is not just a storage_state.json — it's a full Chromium user-data dir (Default/Network/Cookies DB, Local State, caches) created by your earlier headed logins. The live Google session was still alive in the browser's own cookie database, independent of the exported snapshot. A session in that DB outlives the stale storage_state.json beside it.

2. Waited ~12 s for the page's own JS to run, then exported

bunx @playwright/cli -s=zeekl3 state-save .gemiterm/harness/l3-recovered.json
bunx @playwright/cli -s=zeekl3 close

During that page load, Google's identity surface saw a familiar device (persistent profile = device continuity) and the page's JavaScript performed the __Secure-1PSIDTS rotation that raw HTTP couldn't coax — the exported jar's PSIDTS value differed from the 9-hour-stale disk copy (verified by comparison, values never printed).

3. Overwrote the stale snapshot with the rotated one

Copy-Item .gemiterm\harness\l3-recovered.json .gemiterm\profiles\dhb-zeek\storage_state.json

Your CLI then listed 14 conversations because it now read a jar whose PSIDTS was freshly minted rather than superseded.

Why this is the fix and not the L1 attempts: the same session probed through RotateCookies POST (exact notebooklm wire) got 200 + hfcr=600 + SIDCC refresh but PSIDTS withheld — twice, including with the sentinel body. Google will not re-mint PSIDTS over raw HTTP for this account state; it will over a real browser context executing the page's rotation code. That asymmetry is why the profile resurrected via browser and not via fetch — and it's the empirical basis for making browser-backed refresh the primary rotation engine in the replacement design (notebooklm's L3 rung, functioning as their docs describe: the browser profile "stores a live Google SSO session, which can outlive the storage_state.json cookies").

Activity

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