fix: auto-clear a stale sign-in-wall pause on login/session recovery - #29
Merged
Merged
Conversation
A transient Costco sign-in wall latches `worker_state.paused=1` with a `pause_reason` that tells the operator to run `roomieorder login` — but nothing ever cleared that flag. `login` re-authenticated, printed "session persisted", and returned without touching the pause; the periodic session probe only had a negative branch and could never un-pause. So one transient failure took the worker down until a human ran the undocumented `resume`, and the operator saw: log in -> "session persisted" -> tap -> "Costco is logged out" again. It reads as "login won't persist"; the session was fine (re-authing 8x/day), the pause flag was stale. Fix, gated strictly to login/session pauses (captcha `challenge`, `needs_review`, crash, spend-cap and manual pauses stay operator-gated): - store: LOGIN_PAUSE_MARKER + is_login_pause(reason, provider) — the single source of truth for classifying a sign-in-wall pause from the only thing a pause persists, its reason string. Provider-scoped so a signed-in Amazon probe can't clear a still-walled Costco pause. - purchase._signin_required builds its message from LOGIN_PAUSE_MARKER, so the reason it latches always carries the marker (and renders identically to the existing live string, so the fix also recovers an already-latched pause). - main._session_check_tick: log every probe outcome (a healthy probe was previously silent) and, on a signed-in probe, clear a matching login pause (Engine._resume_if_login_pause) — self-heals a transient latch. - cli login: after a confirmed verify_session(), resume a matching login pause, closing the log-in-but-still-paused loop the reason string sends the operator into. - cli doctor: print resolved absolute cwd/db/profile/catalog paths and the per-profile absolute path, so a triage run from the repo (CWD-relative config defaults) can't mistake a stale repo jar for the live service's. Auto-resume can re-arm real ordering when DRY_RUN is off, hence the narrow gate. Does not touch DOM selectors or DRY_RUN. Tests cover the classifier, the provider-scoped probe resume, challenge-stays-latched, and the login pause-clear.
Multipixelone
enabled auto-merge (squash)
July 24, 2026 05:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A reported "Costco login won't persist" turned out not to be a cookie/session bug. A transient Costco sign-in wall on 2026-07-06 latched
worker_state.paused=1with a reason string telling the operator to runroomieorder login— but nothing ever cleared that flag:cli loginre-authenticated, printed "session persisted", and returned without touching the pause.main._session_check_tickonly had a logged-out branch, so it could never un-pause.Operator-visible loop: log in → "session persisted" → tap button → "Costco is logged out" again. The session was actually healthy (re-authing ~8×/day via the persistent
kmsi/WC_PERSISTENTSSO chain);WC_AUTHENTICATION_<memberid>is a session cookie that is re-minted per launch by design, so a logged-out relaunch is expected and self-heals — only the stale pause flag kept ordering down.Fix
Gated strictly to login/session pauses — captcha
challenge,needs_review, worker crash, spend-cap and manual CLI pauses all stay operator-gated:store.py—LOGIN_PAUSE_MARKER+is_login_pause(reason, provider): single source of truth for classifying a sign-in-wall pause from the only thing a pause persists (its reason string). Provider-scoped so a signed-in Amazon probe can't clear a still-walled Costco pause.purchase.py—_signin_requiredbuilds its message fromLOGIN_PAUSE_MARKER, so the reason it latches always carries the marker. Renders identically to the existing live string, so this also recovers an already-latched pause.main.py—_session_check_ticknow logs every probe outcome (a healthy probe was previously silent) and, on a signed-in probe, clears a matching login pause (Engine._resume_if_login_pause) — self-heals a transient latch.cli.py—loginresumes a matching login pause after a confirmedverify_session(), closing the log-in-but-still-paused loop;doctornow prints resolved absolute cwd/db/profile/catalog paths (and the per-profile absolute path) so a triage run from the repo checkout — whose CWD-relative config defaults read a different, empty DB — can't mistake a stale repo jar for the live service's.Safety
Auto-resume can re-arm real ordering when
DRY_RUNis off, hence the narrow gate. No DOM selectors touched,DRY_RUNuntouched.Tests
nix flake checkequivalents pass locally: ruff clean, mypy clean (src + tests), 253 passed / 3 skipped. New coverage:login: clears a matching sign-in pause; leaves a challenge pause latchedFollow-ups (deliberately not in this PR)
nix/module.nixenv-file quoting (would exportDRY_RUN=falseinto repo shells unless paired with an.envrcguard).nixos-rebuild switchso a reboot doesn't roll back to the older generation.