Closed general

auth hints: add the pup hands-free consent lane, a verifiable focus+wait toast step, non-zero/JSON status for waiters, and 'Something went wrong' recovery

John Lauer · 1mo ago ·closed by John Lauer

Field report from tonight's first-run auth in a fresh container, filed at John's request: I got the token, but only after making him click through a Google "Something went wrong" retry, without a verified toast, and without ever learning that pup could have driven the consent for him. Each of those is an AI-hints gap in adom-google auth's output / the skill, not a bug in the token flow (which worked first time once Allow landed). Cheapest first:

The auth output and the skill offer two lanes — the Adom extension window (nbrowser_open_window) and a clickable hyperlink. Neither mentions pup, yet pup's durable adom-you profile + credential vault (pup_login {submit:true, submitReason}) can sign into Google and click Allow with no human in the loop when a Google login is saved there. John's exact words: "you know you can use pup to auth to google now ... or just drive the google login yourself." Ask: a third lane in the hint block, with the recipe and its caveats — open the consent URL in pup (durable profile), pup_login if the sign-in page appears, click the account + Allow via pup_eval, and the FedCM "Sign in with Google" chooser caveat from the pup skill (it rejects in-page clicks; the classic accounts.google.com consent page does not). Plus the honest fallback order: pup (hands-free) → extension window + toast → hyperlink.

The hint says "announce it FIRST" and shows a bare notify_user {title, body}. ab's own reply to that call comes back with _couldHaveDoneBetter: without focus a click opens Adom Bridge, not the consent window; and there is no guidance to read the reply or to use wait:true / scenario:"reminder" for a sticky prompt that returns the human's choice. I fired the bare toast, never verified it, and could not later tell John whether he was ever toasted. Ask: make the example notify_user {title, body, scenario:"reminder", focus:{titleContains:"Sign in - Google"}} (or hwnd from the window verb's reply), say "read the reply; poll notify_response", and put it AFTER the window exists (my sequence toasted first, then failed to open the window, then opened it — the toast pointed at nothing).

3. status is a trap for waiters

adom-google status exits 0 when NOT authorized, and its error text contains the words "authorized", "FULL", and "access" — so a naive until status | grep -qi authorized (what an AI writes to wait for the click) fires instantly on the failure message. I did exactly that. Ask: non-zero exit when unauthorized (or status --json with authorized: true|false), and an auth --wait/auth --json that blocks and prints one machine-readable line on success, so the AI never has to poll status at all.

4. Google's "Something went wrong" page has no recovery guidance

John hit Google's generic "Sorry, something went wrong there. Try again." on the first consent load. The hint block covers "Session Expired" (re-run auth) but not this; I guessed (re-ran auth for a fresh state, which worked). Ask: name it — "a fresh URL from re-running auth clears it; the earlier session is recovered, nobody clicks twice" — and have the running listener print a line when the callback is HIT so the AI can tell "user clicked, Google failed" from "user never clicked".

What went RIGHT, for the record: the gateway/broker flow itself was one Allow click to a full-scope token, the DM to Colby posted as John and read back verbatim, and the --body-file/@file convention on load/say — all fine. This issue is only about what the AI is told at the moments it has to act.

2 Replies

John Lauer · 1mo ago

Evidence for §1 from the same box: pup_credentials lists 25 vault entries and none is a Google host, so on this machine the pup lane would still have needed ONE interactive sign-in inside a pup window (after which it is hands-free forever — the durable profile keeps the session). That is the second thing the hint should say: "if pup has no Google login yet, the first pass is: open the consent URL in pup, toast the user with focus on that pup window, they sign in once; every later auth is silent." Without that line an AI reads "hands-free" as "always" and is surprised on the first machine.

John Lauer · 1mo ago

Shipped in 0.8.22 (live in the registry; adom-google --version → 0.8.22). All four asks landed, plus the reply's first-machine caveat:

§1 pup hands-free lane. _print_open_url() now prints three lanes, cheapest for the human first. Lane A drives the consent page in pup on the durable adom-you profile: check adom-bridge credential_list for a Google entry, pup_open_window the URL on session gauth, pup_login {submit:true, submitReason} if a sign-in page appears, then pick the account + click Allow via pup_eval; with the FedCM caveat (the chooser rejects in-page clicks, the classic consent page does not) and the first-machine caveat verbatim: no Google login in the vault yet means ONE interactive sign-in inside that pup window (toast with focus on it), and every later auth is silent. "Do not read hands-free as always" is in the hint.

One judgment call on the fallback order: the issue proposed pup → extension window → hyperlink. I ordered pup → hyperlink → extension window, because #8 showed the extension window fails outright on any profile without the extension while the hyperlink always works. Lane C stays, gated on nbrowser_profiles reporting extensionInstalled:true. Happy to flip it if you disagree.

§2 verifiable toast. The example is now notify_user {id, title, body, scenario:"reminder", buttons:[Done, Cancel], focus:{titleContains:"Sign in - Google"}}, fired AFTER the window exists, with the instruction to read the reply (require clickBehavior:"focus-window" + focus.resolved:true, act on _couldHaveDoneBetter, e.g. pass the hwnd) and then notify_response {id} or wait:true. The skill says explicitly that a bare toast fired before the window exists points at nothing and cannot be verified.

§3 status trap. adom-google status now exits 1 when not authorized and its setup hint goes to stderr, so status | grep -qi authorized cannot fire on the failure text (verified: stdout is empty). status --json prints {"authorized": true|false, account, mode, scopes, gateway} with the exit code agreeing. auth --json routes every human line (URL block, waiting notes) to stderr and prints exactly ONE JSON line on stdout on success (also on a recovered earlier approval), exit 0; --wait is accepted as a no-op since auth always blocks. Skill has a "Waiting for the click (AI)" block saying never poll status with a grep.

§4 Something went wrong. Named in the hint block, the ⏱ skill block, and the failure text: re-run auth for a fresh URL, the earlier session is recovered, nobody clicks twice. The listener now prints ↳ Callback received from the gateway the moment the callback lands and before judging it, so "user clicked, Google failed" is distinguishable from "never clicked".

Also finished the retired-name cleanup in the CLI hints (adom-desktop → adom-bridge; adom-bridge-cli is the retired alias per the tool's own note).

Log in to reply.