Skip to content

fix(profile): stage stopped profile before fresh Agent verification - #184

Draft
git-ksk wants to merge 7 commits into
mainfrom
fix/183-profile-stage
Draft

fix(profile): stage stopped profile before fresh Agent verification#184
git-ksk wants to merge 7 commits into
mainfrom
fix/183-profile-stage

Conversation

@git-ksk

@git-ksk git-ksk commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • add an optional deployment-owned prepareStoppedBrowserProfileForVerification hook
  • run that hook only after Human takeover revoke/normal-Chrome close and before fresh Agent verification, for both explicit-complete and MRTR continuation paths
  • make the reference Cloud Run provider perform a local opaque archive/restore round-trip that does not update the durable Cloud Storage pointer
  • keep the existing durable checkpoint gated on verified coarse signed_in and a stopped Agent browser

This mirrors the hosted-browser profile lifecycle pattern without adding a Steel/Browserbase runtime dependency.

Safety / ordering

Human revoke + normal browser close -> stopped-profile preparation -> fresh Agent verification -> stop Agent -> durable checkpoint -> resume.

No credential/account identity/cookie/token/raw Human input/browser content/takeover locator is added to logs or control-plane state. Preparation failure fails closed.

Validation

  • npm run check: 370 tests, 365 pass / 0 fail / 5 platform skips
  • npm run build
  • cd reference/oauth-gateway && npm test: 42/42 pass
  • production-equivalent Mac Docker synthetic profile lifecycle: PASS for direct headless, direct headful CDP, and stopped-profile staging round-trip
  • real Google local-container evidence: session survived Human -> fresh Agent; immediate completion raced, next fresh readiness was signed_in
  • git diff --check

Acceptance remaining

  • rerun real-Google Mac Docker acceptance with per-run isolated harness control state and confirm maps_complete_human_sign_in succeeds with post-Human settle
  • build/deploy the settle candidate and confirm Cloud Run candidate readiness
  • physical iPhone Google sign-in -> Done -> completion succeeds -> fresh Agent coarse signed_in
  • verified stopped-profile durable checkpoint
  • fresh Cloud Run restore retains coarse signed_in

Refs #135

@git-ksk
git-ksk force-pushed the fix/183-profile-stage branch from f9f2fec to 8d292bb Compare September 5, 2026 08:34
@git-ksk

git-ksk commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

Mac local Docker acceptance found and reproduced a profile-handoff race in the production-equivalent Linux/Chromium image.

Observed before this fix:

  • SystemBrowserCredentialSession.close() returned after the top-level Human Chromium process exited and singleton locks disappeared.
  • one profile-bound Chromium utility process remained for ~0.8s after close() returned.
  • an immediate stopped-profile tar round-trip could race a transient Chromium profile file and fail with ENOENT.

Fix:

  • on Linux, after the owned Human browser closes, wait boundedly until no Chromium process command line still carries the exact dedicated --user-data-dir=<profile> argument;
  • do not kill unrelated/stale processes automatically;
  • timeout remains fail-closed;
  • only then treat the profile as safe to hand to staging/fresh Agent Chrome.

Mac Docker re-acceptance using the same production immutable image + only this compiled browser-session overlay:

  • close returned with profile-bound Chromium process count = 0;
  • persistent synthetic cookie survived Human -> headless Agent;
  • persistent synthetic cookie survived Human -> headful CDP Agent;
  • localStorage survived both paths;
  • Human close -> profile tar round-trip -> headless Agent preserved both markers;
  • no Google account identity, cookie values, credentials, or Human input were inspected; only synthetic local markers and process/profile metadata were used.

Regression:

  • root: 368 tests / 363 pass / 0 fail / 5 platform skips
  • OAuth gateway: 42/42
  • build and acceptance-harness syntax green.

@git-ksk

git-ksk commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

Mac local production-equivalent Docker acceptance narrowed the remaining failure to a post-Human readiness race rather than profile loss.

Observed with the same Linux/Chromium image and a real Human Google sign-in:

  • Human WSS session completed and authority was revoked cleanly.
  • stopped-profile preparation completed.
  • maps_complete_human_sign_in() returned UI_STATE_CHANGED because its immediate fresh verification did not see signed_in.
  • the very next fresh maps_read_authenticated_readiness() returned signed_in.

This proves the real Google session/profile survived Human -> stopped profile -> fresh Agent in the local container. The completion verifier was treating an initial transient signed_out as terminal too early.

Fix: post-Human verification now performs a bounded 8s settle that succeeds only on observed signed_in; persistent signed_out still fails closed as HUMAN_INTERVENTION_REQUIRED, and unresolved/contradictory state still fails closed. Ordinary readiness reads keep their existing immediate semantics.

Validation:

  • targeted authenticated-readiness tests: 6/6 pass
  • root check: 370 total / 365 pass / 0 fail / 5 skip
  • OAuth gateway: 42/42 pass

@git-ksk

git-ksk commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

Acceptance bookkeeping: the latest two temporary local runs are excluded from candidate evidence. One locator expired at the configured 10-minute acceptance TTL; the following temporary harness reused fixed state/continue paths, allowing an older stale container to consume the Done signal. The resulting INTERNAL_ERROR / MAPS_NOT_OPEN output is a harness-control collision, not evidence against 99f75eb.

PR implementation/regression remains green. Next re-acceptance must isolate all temporary run-control paths per run before evaluating the bounded post-Human settle.

@git-ksk

git-ksk commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

Latest acceptance status after the bounded post-Human readiness settle work:

  1. Real-Google Mac Docker completion now passes the post-Human verifier.
  • Human takeover reached Google Maps sign-in and was completed by the Human.
  • maps_complete_human_sign_in() returned success (humanStepCompleted: true, fresh readiness recheck required).
  • stopped-profile preparation and the verified profile checkpoint both completed.
  • this confirms the earlier immediate-verification race is addressed by the bounded post-Human settle.
  1. The next failure was a separate lifecycle hole after successful checkpointing.
  • immediately after successful completion, maps_read_authenticated_readiness() returned MAPS_NOT_OPEN.
  • root cause: the credential-safe checkpoint intentionally stopped Chromium, but successful completion returned without re-establishing a fresh Maps surface for the documented readiness recheck.
  1. Fix on the combined acceptance line:
  • commit eb51de7 (fix(auth): reopen Maps after verified profile checkpoint (#183)).
  • only after the Human intervention is fully verified/resumed/fenced, start a fresh automation browser and navigate to Google Maps home.
  • no interrupted Maps action is replayed.
  • checkpoint remains taken only while the dedicated profile is stopped.
  • recovery/fail-closed semantics outside successful credential-safe completion are unchanged.

Validation:

  • root: 376 total / 371 pass / 0 fail / 5 platform skips.
  • OAuth gateway: 42/42.
  • production-equivalent Mac Docker lifecycle smoke: fresh browser reopened a Maps surface and authenticated-readiness evaluation became reachable (mapsSurface=true); this smoke intentionally did not assert account/session content.

Cloud Run acceptance candidate:

Remaining gate:

  • physical iPhone Human sign-in on the current candidate: Done -> completion success -> fresh readiness signed_in.
  • then perform a genuine fresh Cloud Run instance/revision restore from the verified checkpoint and require coarse signed_in without another Human sign-in.

No account identity, credential/session material, Human input payload, or takeover locator is recorded in this issue.

@git-ksk

git-ksk commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

Implementation status after the durability review:

fa8b506 / d6fa50f changes:

  • removes graceful container-shutdown profile publication entirely; shutdown cannot advance durable current;
  • adds checkpoint-specific Agent Chrome close with bounded exact-profile Linux Chromium quiescence; top-level Chrome failure after SIGTERM/SIGKILL and lingering exact --user-data-dir processes fail closed;
  • shares the post-verified-checkpoint fresh Maps surface boundary between explicit completion and MRTR, with no interrupted-action replay;
  • adds durable-pointer failure regressions: upload failure and pointer publication failure preserve the prior current;
  • adds source/lifecycle regressions proving publication remains behind signed_in verification and shutdown cannot invoke checkpoint publication.

Validation on #183 branch:

  • root: 374 total / 369 pass / 0 fail / 5 skip
  • OAuth gateway: 44/44
  • build + acceptance-harness syntax + git diff --check: green

Validation on combined #181/#183/#189 branch:

  • root: 379 total / 374 pass / 0 fail / 5 skip
  • OAuth gateway: 44/44
  • build + acceptance-harness syntax + git diff --check: green

Next gate remains runtime acceptance, not a code-only claim: build a no-traffic Cloud Run candidate from d6fa50f, verify health/smoke, then physical iPhone Human sign-in -> completion -> fresh coarse signed_in -> verified durable checkpoint -> genuinely fresh Cloud Run instance/revision restore -> coarse signed_in without another Human sign-in.

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.

1 participant